12017 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * thinkpad_acpi.c - ThinkPad ACPI Extras4 *5 * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>6 * Copyright (C) 2006-2009 Henrique de Moraes Holschuh <hmh@hmh.eng.br>7 */8 9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt10 11#define TPACPI_VERSION "0.26"12#define TPACPI_SYSFS_VERSION 0x03000013 14/*15 * Changelog:16 * 2007-10-20 changelog trimmed down17 *18 * 2007-03-27 0.14 renamed to thinkpad_acpi and moved to19 * drivers/misc.20 *21 * 2006-11-22 0.13 new maintainer22 * changelog now lives in git commit history, and will23 * not be updated further in-file.24 *25 * 2005-03-17 0.11 support for 600e, 770x26 * thanks to Jamie Lentin <lentinj@dial.pipex.com>27 *28 * 2005-01-16 0.9 use MODULE_VERSION29 * thanks to Henrik Brix Andersen <brix@gentoo.org>30 * fix parameter passing on module loading31 * thanks to Rusty Russell <rusty@rustcorp.com.au>32 * thanks to Jim Radford <radford@blackbean.org>33 * 2004-11-08 0.8 fix init error case, don't return from a macro34 * thanks to Chris Wright <chrisw@osdl.org>35 */36 37#include <linux/acpi.h>38#include <linux/backlight.h>39#include <linux/bitops.h>40#include <linux/delay.h>41#include <linux/dmi.h>42#include <linux/fb.h>43#include <linux/freezer.h>44#include <linux/hwmon.h>45#include <linux/hwmon-sysfs.h>46#include <linux/init.h>47#include <linux/input.h>48#include <linux/input/sparse-keymap.h>49#include <linux/jiffies.h>50#include <linux/kernel.h>51#include <linux/kthread.h>52#include <linux/leds.h>53#include <linux/list.h>54#include <linux/lockdep.h>55#include <linux/module.h>56#include <linux/mutex.h>57#include <linux/nvram.h>58#include <linux/pci.h>59#include <linux/platform_device.h>60#include <linux/platform_profile.h>61#include <linux/power_supply.h>62#include <linux/proc_fs.h>63#include <linux/rfkill.h>64#include <linux/sched.h>65#include <linux/sched/signal.h>66#include <linux/seq_file.h>67#include <linux/slab.h>68#include <linux/string.h>69#include <linux/string_helpers.h>70#include <linux/sysfs.h>71#include <linux/types.h>72#include <linux/uaccess.h>73#include <linux/units.h>74#include <linux/workqueue.h>75 76#include <acpi/battery.h>77#include <acpi/video.h>78 79#include <drm/drm_privacy_screen_driver.h>80 81#include <sound/control.h>82#include <sound/core.h>83#include <sound/initval.h>84 85#include "dual_accel_detect.h"86 87/* ThinkPad CMOS commands */88#define TP_CMOS_VOLUME_DOWN 089#define TP_CMOS_VOLUME_UP 190#define TP_CMOS_VOLUME_MUTE 291#define TP_CMOS_BRIGHTNESS_UP 492#define TP_CMOS_BRIGHTNESS_DOWN 593#define TP_CMOS_THINKLIGHT_ON 1294#define TP_CMOS_THINKLIGHT_OFF 1395 96/* NVRAM Addresses */97enum tp_nvram_addr {98 TP_NVRAM_ADDR_HK2 = 0x57,99 TP_NVRAM_ADDR_THINKLIGHT = 0x58,100 TP_NVRAM_ADDR_VIDEO = 0x59,101 TP_NVRAM_ADDR_BRIGHTNESS = 0x5e,102 TP_NVRAM_ADDR_MIXER = 0x60,103};104 105/* NVRAM bit masks */106enum {107 TP_NVRAM_MASK_HKT_THINKPAD = 0x08,108 TP_NVRAM_MASK_HKT_ZOOM = 0x20,109 TP_NVRAM_MASK_HKT_DISPLAY = 0x40,110 TP_NVRAM_MASK_HKT_HIBERNATE = 0x80,111 TP_NVRAM_MASK_THINKLIGHT = 0x10,112 TP_NVRAM_MASK_HKT_DISPEXPND = 0x30,113 TP_NVRAM_MASK_HKT_BRIGHTNESS = 0x20,114 TP_NVRAM_MASK_LEVEL_BRIGHTNESS = 0x0f,115 TP_NVRAM_POS_LEVEL_BRIGHTNESS = 0,116 TP_NVRAM_MASK_MUTE = 0x40,117 TP_NVRAM_MASK_HKT_VOLUME = 0x80,118 TP_NVRAM_MASK_LEVEL_VOLUME = 0x0f,119 TP_NVRAM_POS_LEVEL_VOLUME = 0,120};121 122/* Misc NVRAM-related */123enum {124 TP_NVRAM_LEVEL_VOLUME_MAX = 14,125};126 127/* ACPI HIDs */128#define TPACPI_ACPI_IBM_HKEY_HID "IBM0068"129#define TPACPI_ACPI_LENOVO_HKEY_HID "LEN0068"130#define TPACPI_ACPI_LENOVO_HKEY_V2_HID "LEN0268"131#define TPACPI_ACPI_EC_HID "PNP0C09"132 133/* Input IDs */134#define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */135#define TPACPI_HKEY_INPUT_VERSION 0x4101136 137/* ACPI \WGSV commands */138enum {139 TP_ACPI_WGSV_GET_STATE = 0x01, /* Get state information */140 TP_ACPI_WGSV_PWR_ON_ON_RESUME = 0x02, /* Resume WWAN powered on */141 TP_ACPI_WGSV_PWR_OFF_ON_RESUME = 0x03, /* Resume WWAN powered off */142 TP_ACPI_WGSV_SAVE_STATE = 0x04, /* Save state for S4/S5 */143};144 145/* TP_ACPI_WGSV_GET_STATE bits */146enum {147 TP_ACPI_WGSV_STATE_WWANEXIST = 0x0001, /* WWAN hw available */148 TP_ACPI_WGSV_STATE_WWANPWR = 0x0002, /* WWAN radio enabled */149 TP_ACPI_WGSV_STATE_WWANPWRRES = 0x0004, /* WWAN state at resume */150 TP_ACPI_WGSV_STATE_WWANBIOSOFF = 0x0008, /* WWAN disabled in BIOS */151 TP_ACPI_WGSV_STATE_BLTHEXIST = 0x0001, /* BLTH hw available */152 TP_ACPI_WGSV_STATE_BLTHPWR = 0x0002, /* BLTH radio enabled */153 TP_ACPI_WGSV_STATE_BLTHPWRRES = 0x0004, /* BLTH state at resume */154 TP_ACPI_WGSV_STATE_BLTHBIOSOFF = 0x0008, /* BLTH disabled in BIOS */155 TP_ACPI_WGSV_STATE_UWBEXIST = 0x0010, /* UWB hw available */156 TP_ACPI_WGSV_STATE_UWBPWR = 0x0020, /* UWB radio enabled */157};158 159/* HKEY events */160enum tpacpi_hkey_event_t {161 /* Original hotkeys */162 TP_HKEY_EV_ORIG_KEY_START = 0x1001, /* First hotkey (FN+F1) */163 TP_HKEY_EV_BRGHT_UP = 0x1010, /* Brightness up */164 TP_HKEY_EV_BRGHT_DOWN = 0x1011, /* Brightness down */165 TP_HKEY_EV_KBD_LIGHT = 0x1012, /* Thinklight/kbd backlight */166 TP_HKEY_EV_VOL_UP = 0x1015, /* Volume up or unmute */167 TP_HKEY_EV_VOL_DOWN = 0x1016, /* Volume down or unmute */168 TP_HKEY_EV_VOL_MUTE = 0x1017, /* Mixer output mute */169 TP_HKEY_EV_ORIG_KEY_END = 0x1020, /* Last original hotkey code */170 171 /* Adaptive keyboard (2014 X1 Carbon) */172 TP_HKEY_EV_DFR_CHANGE_ROW = 0x1101, /* Change adaptive kbd Fn row mode */173 TP_HKEY_EV_DFR_S_QUICKVIEW_ROW = 0x1102, /* Set adap. kbd Fn row to function mode */174 TP_HKEY_EV_ADAPTIVE_KEY_START = 0x1103, /* First hotkey code on adaptive kbd */175 TP_HKEY_EV_ADAPTIVE_KEY_END = 0x1116, /* Last hotkey code on adaptive kbd */176 177 /* Extended hotkey events in 2017+ models */178 TP_HKEY_EV_EXTENDED_KEY_START = 0x1300, /* First extended hotkey code */179 TP_HKEY_EV_PRIVACYGUARD_TOGGLE = 0x130f, /* Toggle priv.guard on/off */180 TP_HKEY_EV_EXTENDED_KEY_END = 0x1319, /* Last extended hotkey code using181 * hkey -> scancode translation for182 * compat. Later codes are entered183 * directly in the sparse-keymap.184 */185 TP_HKEY_EV_AMT_TOGGLE = 0x131a, /* Toggle AMT on/off */186 TP_HKEY_EV_DOUBLETAP_TOGGLE = 0x131c, /* Toggle trackpoint doubletap on/off */187 TP_HKEY_EV_PROFILE_TOGGLE = 0x131f, /* Toggle platform profile */188 189 /* Reasons for waking up from S3/S4 */190 TP_HKEY_EV_WKUP_S3_UNDOCK = 0x2304, /* undock requested, S3 */191 TP_HKEY_EV_WKUP_S4_UNDOCK = 0x2404, /* undock requested, S4 */192 TP_HKEY_EV_WKUP_S3_BAYEJ = 0x2305, /* bay ejection req, S3 */193 TP_HKEY_EV_WKUP_S4_BAYEJ = 0x2405, /* bay ejection req, S4 */194 TP_HKEY_EV_WKUP_S3_BATLOW = 0x2313, /* battery empty, S3 */195 TP_HKEY_EV_WKUP_S4_BATLOW = 0x2413, /* battery empty, S4 */196 197 /* Auto-sleep after eject request */198 TP_HKEY_EV_BAYEJ_ACK = 0x3003, /* bay ejection complete */199 TP_HKEY_EV_UNDOCK_ACK = 0x4003, /* undock complete */200 201 /* Misc bay events */202 TP_HKEY_EV_OPTDRV_EJ = 0x3006, /* opt. drive tray ejected */203 TP_HKEY_EV_HOTPLUG_DOCK = 0x4010, /* docked into hotplug dock204 or port replicator */205 TP_HKEY_EV_HOTPLUG_UNDOCK = 0x4011, /* undocked from hotplug206 dock or port replicator */207 /*208 * Thinkpad X1 Tablet series devices emit 0x4012 and 0x4013209 * when keyboard cover is attached, detached or folded onto the back210 */211 TP_HKEY_EV_KBD_COVER_ATTACH = 0x4012, /* keyboard cover attached */212 TP_HKEY_EV_KBD_COVER_DETACH = 0x4013, /* keyboard cover detached or folded back */213 214 /* User-interface events */215 TP_HKEY_EV_LID_CLOSE = 0x5001, /* laptop lid closed */216 TP_HKEY_EV_LID_OPEN = 0x5002, /* laptop lid opened */217 TP_HKEY_EV_TABLET_TABLET = 0x5009, /* tablet swivel up */218 TP_HKEY_EV_TABLET_NOTEBOOK = 0x500a, /* tablet swivel down */219 TP_HKEY_EV_TABLET_CHANGED = 0x60c0, /* X1 Yoga (2016):220 * enter/leave tablet mode221 */222 TP_HKEY_EV_PEN_INSERTED = 0x500b, /* tablet pen inserted */223 TP_HKEY_EV_PEN_REMOVED = 0x500c, /* tablet pen removed */224 TP_HKEY_EV_BRGHT_CHANGED = 0x5010, /* backlight control event */225 226 /* Key-related user-interface events */227 TP_HKEY_EV_KEY_NUMLOCK = 0x6000, /* NumLock key pressed */228 TP_HKEY_EV_KEY_FN = 0x6005, /* Fn key pressed? E420 */229 TP_HKEY_EV_KEY_FN_ESC = 0x6060, /* Fn+Esc key pressed X240 */230 231 /* Thermal events */232 TP_HKEY_EV_ALARM_BAT_HOT = 0x6011, /* battery too hot */233 TP_HKEY_EV_ALARM_BAT_XHOT = 0x6012, /* battery critically hot */234 TP_HKEY_EV_ALARM_SENSOR_HOT = 0x6021, /* sensor too hot */235 TP_HKEY_EV_ALARM_SENSOR_XHOT = 0x6022, /* sensor critically hot */236 TP_HKEY_EV_THM_TABLE_CHANGED = 0x6030, /* windows; thermal table changed */237 TP_HKEY_EV_THM_CSM_COMPLETED = 0x6032, /* windows; thermal control set238 * command completed. Related to239 * AML DYTC */240 TP_HKEY_EV_THM_TRANSFM_CHANGED = 0x60F0, /* windows; thermal transformation241 * changed. Related to AML GMTS */242 243 /* AC-related events */244 TP_HKEY_EV_AC_CHANGED = 0x6040, /* AC status changed */245 246 /* Further user-interface events */247 TP_HKEY_EV_PALM_DETECTED = 0x60b0, /* palm hoveres keyboard */248 TP_HKEY_EV_PALM_UNDETECTED = 0x60b1, /* palm removed */249 250 /* Misc */251 TP_HKEY_EV_RFKILL_CHANGED = 0x7000, /* rfkill switch changed */252 253 /* Misc2 */254 TP_HKEY_EV_TRACK_DOUBLETAP = 0x8036, /* trackpoint doubletap */255};256 257/****************************************************************************258 * Main driver259 */260 261#define TPACPI_NAME "thinkpad"262#define TPACPI_DESC "ThinkPad ACPI Extras"263#define TPACPI_FILE TPACPI_NAME "_acpi"264#define TPACPI_URL "http://ibm-acpi.sf.net/"265#define TPACPI_MAIL "ibm-acpi-devel@lists.sourceforge.net"266 267#define TPACPI_PROC_DIR "ibm"268#define TPACPI_ACPI_EVENT_PREFIX "ibm"269#define TPACPI_DRVR_NAME TPACPI_FILE270#define TPACPI_DRVR_SHORTNAME "tpacpi"271#define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon"272 273#define TPACPI_NVRAM_KTHREAD_NAME "ktpacpi_nvramd"274#define TPACPI_WORKQUEUE_NAME "ktpacpid"275 276#define TPACPI_MAX_ACPI_ARGS 3277 278/* Debugging printk groups */279#define TPACPI_DBG_ALL 0xffff280#define TPACPI_DBG_DISCLOSETASK 0x8000281#define TPACPI_DBG_INIT 0x0001282#define TPACPI_DBG_EXIT 0x0002283#define TPACPI_DBG_RFKILL 0x0004284#define TPACPI_DBG_HKEY 0x0008285#define TPACPI_DBG_FAN 0x0010286#define TPACPI_DBG_BRGHT 0x0020287#define TPACPI_DBG_MIXER 0x0040288 289#define FAN_NOT_PRESENT 65535290 291/****************************************************************************292 * Driver-wide structs and misc. variables293 */294 295struct ibm_struct;296 297struct tp_acpi_drv_struct {298 const struct acpi_device_id *hid;299 struct acpi_driver *driver;300 301 void (*notify) (struct ibm_struct *, u32);302 acpi_handle *handle;303 u32 type;304 struct acpi_device *device;305};306 307struct ibm_struct {308 char *name;309 310 int (*read) (struct seq_file *);311 int (*write) (char *);312 void (*exit) (void);313 void (*resume) (void);314 void (*suspend) (void);315 void (*shutdown) (void);316 317 struct list_head all_drivers;318 319 struct tp_acpi_drv_struct *acpi;320 321 struct {322 u8 acpi_driver_registered:1;323 u8 acpi_notify_installed:1;324 u8 proc_created:1;325 u8 init_called:1;326 u8 experimental:1;327 } flags;328};329 330struct ibm_init_struct {331 char param[32];332 333 int (*init) (struct ibm_init_struct *);334 umode_t base_procfs_mode;335 struct ibm_struct *data;336};337 338/* DMI Quirks */339struct quirk_entry {340 bool btusb_bug;341};342 343static struct quirk_entry quirk_btusb_bug = {344 .btusb_bug = true,345};346 347static struct {348 u32 bluetooth:1;349 u32 hotkey:1;350 u32 hotkey_mask:1;351 u32 hotkey_wlsw:1;352 enum {353 TP_HOTKEY_TABLET_NONE = 0,354 TP_HOTKEY_TABLET_USES_MHKG,355 TP_HOTKEY_TABLET_USES_GMMS,356 } hotkey_tablet;357 u32 kbdlight:1;358 u32 light:1;359 u32 light_status:1;360 u32 bright_acpimode:1;361 u32 bright_unkfw:1;362 u32 wan:1;363 u32 uwb:1;364 u32 fan_ctrl_status_undef:1;365 u32 second_fan:1;366 u32 second_fan_ctl:1;367 u32 beep_needs_two_args:1;368 u32 mixer_no_level_control:1;369 u32 battery_force_primary:1;370 u32 input_device_registered:1;371 u32 platform_drv_registered:1;372 u32 sensors_pdrv_registered:1;373 u32 hotkey_poll_active:1;374 u32 has_adaptive_kbd:1;375 u32 kbd_lang:1;376 u32 trackpoint_doubletap:1;377 struct quirk_entry *quirks;378} tp_features;379 380static struct {381 u16 hotkey_mask_ff:1;382 u16 volume_ctrl_forbidden:1;383} tp_warned;384 385struct thinkpad_id_data {386 unsigned int vendor; /* ThinkPad vendor:387 * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */388 389 char *bios_version_str; /* Something like 1ZET51WW (1.03z) */390 char *ec_version_str; /* Something like 1ZHT51WW-1.04a */391 392 u32 bios_model; /* 1Y = 0x3159, 0 = unknown */393 u32 ec_model;394 u16 bios_release; /* 1ZETK1WW = 0x4b31, 0 = unknown */395 u16 ec_release;396 397 char *model_str; /* ThinkPad T43 */398 char *nummodel_str; /* 9384A9C for a 9384-A9C model */399};400static struct thinkpad_id_data thinkpad_id;401 402static enum {403 TPACPI_LIFE_INIT = 0,404 TPACPI_LIFE_RUNNING,405 TPACPI_LIFE_EXITING,406} tpacpi_lifecycle;407 408static int experimental;409static u32 dbg_level;410 411static struct workqueue_struct *tpacpi_wq;412 413enum led_status_t {414 TPACPI_LED_OFF = 0,415 TPACPI_LED_ON,416 TPACPI_LED_BLINK,417};418 419/* tpacpi LED class */420struct tpacpi_led_classdev {421 struct led_classdev led_classdev;422 int led;423};424 425/* brightness level capabilities */426static unsigned int bright_maxlvl; /* 0 = unknown */427 428#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES429static int dbg_wlswemul;430static bool tpacpi_wlsw_emulstate;431static int dbg_bluetoothemul;432static bool tpacpi_bluetooth_emulstate;433static int dbg_wwanemul;434static bool tpacpi_wwan_emulstate;435static int dbg_uwbemul;436static bool tpacpi_uwb_emulstate;437#endif438 439 440/*************************************************************************441 * Debugging helpers442 */443 444#define dbg_printk(a_dbg_level, format, arg...) \445do { \446 if (dbg_level & (a_dbg_level)) \447 printk(KERN_DEBUG pr_fmt("%s: " format), \448 __func__, ##arg); \449} while (0)450 451#ifdef CONFIG_THINKPAD_ACPI_DEBUG452#define vdbg_printk dbg_printk453static const char *str_supported(int is_supported);454#else455static inline const char *str_supported(int is_supported) { return ""; }456#define vdbg_printk(a_dbg_level, format, arg...) \457 do { if (0) no_printk(format, ##arg); } while (0)458#endif459 460static void tpacpi_log_usertask(const char * const what)461{462 printk(KERN_DEBUG pr_fmt("%s: access by process with PID %d\n"),463 what, task_tgid_vnr(current));464}465 466#define tpacpi_disclose_usertask(what, format, arg...) \467do { \468 if (unlikely((dbg_level & TPACPI_DBG_DISCLOSETASK) && \469 (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \470 printk(KERN_DEBUG pr_fmt("%s: PID %d: " format), \471 what, task_tgid_vnr(current), ## arg); \472 } \473} while (0)474 475/*476 * Quirk handling helpers477 *478 * ThinkPad IDs and versions seen in the field so far are479 * two or three characters from the set [0-9A-Z], i.e. base 36.480 *481 * We use values well outside that range as specials.482 */483 484#define TPACPI_MATCH_ANY 0xffffffffU485#define TPACPI_MATCH_ANY_VERSION 0xffffU486#define TPACPI_MATCH_UNKNOWN 0U487 488/* TPID('1', 'Y') == 0x3159 */489#define TPID(__c1, __c2) (((__c1) << 8) | (__c2))490#define TPID3(__c1, __c2, __c3) (((__c1) << 16) | ((__c2) << 8) | (__c3))491#define TPVER TPID492 493#define TPACPI_Q_IBM(__id1, __id2, __quirk) \494 { .vendor = PCI_VENDOR_ID_IBM, \495 .bios = TPID(__id1, __id2), \496 .ec = TPACPI_MATCH_ANY, \497 .quirks = (__quirk) }498 499#define TPACPI_Q_LNV(__id1, __id2, __quirk) \500 { .vendor = PCI_VENDOR_ID_LENOVO, \501 .bios = TPID(__id1, __id2), \502 .ec = TPACPI_MATCH_ANY, \503 .quirks = (__quirk) }504 505#define TPACPI_Q_LNV3(__id1, __id2, __id3, __quirk) \506 { .vendor = PCI_VENDOR_ID_LENOVO, \507 .bios = TPID3(__id1, __id2, __id3), \508 .ec = TPACPI_MATCH_ANY, \509 .quirks = (__quirk) }510 511#define TPACPI_QEC_IBM(__id1, __id2, __quirk) \512 { .vendor = PCI_VENDOR_ID_IBM, \513 .bios = TPACPI_MATCH_ANY, \514 .ec = TPID(__id1, __id2), \515 .quirks = (__quirk) }516 517#define TPACPI_QEC_LNV(__id1, __id2, __quirk) \518 { .vendor = PCI_VENDOR_ID_LENOVO, \519 .bios = TPACPI_MATCH_ANY, \520 .ec = TPID(__id1, __id2), \521 .quirks = (__quirk) }522 523struct tpacpi_quirk {524 unsigned int vendor;525 u32 bios;526 u32 ec;527 unsigned long quirks;528};529 530/**531 * tpacpi_check_quirks() - search BIOS/EC version on a list532 * @qlist: array of &struct tpacpi_quirk533 * @qlist_size: number of elements in @qlist534 *535 * Iterates over a quirks list until one is found that matches the536 * ThinkPad's vendor, BIOS and EC model.537 *538 * Returns: %0 if nothing matches, otherwise returns the quirks field of539 * the matching &struct tpacpi_quirk entry.540 *541 * The match criteria is: vendor, ec and bios must match.542 */543static unsigned long __init tpacpi_check_quirks(544 const struct tpacpi_quirk *qlist,545 unsigned int qlist_size)546{547 while (qlist_size) {548 if ((qlist->vendor == thinkpad_id.vendor ||549 qlist->vendor == TPACPI_MATCH_ANY) &&550 (qlist->bios == thinkpad_id.bios_model ||551 qlist->bios == TPACPI_MATCH_ANY) &&552 (qlist->ec == thinkpad_id.ec_model ||553 qlist->ec == TPACPI_MATCH_ANY))554 return qlist->quirks;555 556 qlist_size--;557 qlist++;558 }559 return 0;560}561 562static inline bool __pure __init tpacpi_is_lenovo(void)563{564 return thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO;565}566 567static inline bool __pure __init tpacpi_is_ibm(void)568{569 return thinkpad_id.vendor == PCI_VENDOR_ID_IBM;570}571 572/****************************************************************************573 ****************************************************************************574 *575 * ACPI Helpers and device model576 *577 ****************************************************************************578 ****************************************************************************/579 580/*************************************************************************581 * ACPI basic handles582 */583 584static acpi_handle root_handle;585static acpi_handle ec_handle;586 587#define TPACPI_HANDLE(object, parent, paths...) \588 static acpi_handle object##_handle; \589 static const acpi_handle * const object##_parent __initconst = \590 &parent##_handle; \591 static char *object##_paths[] __initdata = { paths }592 593TPACPI_HANDLE(ecrd, ec, "ECRD"); /* 570 */594TPACPI_HANDLE(ecwr, ec, "ECWR"); /* 570 */595 596TPACPI_HANDLE(cmos, root, "\\UCMS", /* R50, R50e, R50p, R51, */597 /* T4x, X31, X40 */598 "\\CMOS", /* A3x, G4x, R32, T23, T30, X22-24, X30 */599 "\\CMS", /* R40, R40e */600 ); /* all others */601 602TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */603 "^HKEY", /* R30, R31 */604 "HKEY", /* all others */605 ); /* 570 */606 607/*************************************************************************608 * ACPI helpers609 */610 611static int acpi_evalf(acpi_handle handle,612 int *res, char *method, char *fmt, ...)613{614 char *fmt0 = fmt;615 struct acpi_object_list params;616 union acpi_object in_objs[TPACPI_MAX_ACPI_ARGS];617 struct acpi_buffer result, *resultp;618 union acpi_object out_obj;619 acpi_status status;620 va_list ap;621 char res_type;622 int success;623 int quiet;624 625 if (!*fmt) {626 pr_err("acpi_evalf() called with empty format\n");627 return 0;628 }629 630 if (*fmt == 'q') {631 quiet = 1;632 fmt++;633 } else634 quiet = 0;635 636 res_type = *(fmt++);637 638 params.count = 0;639 params.pointer = &in_objs[0];640 641 va_start(ap, fmt);642 while (*fmt) {643 char c = *(fmt++);644 switch (c) {645 case 'd': /* int */646 in_objs[params.count].integer.value = va_arg(ap, int);647 in_objs[params.count++].type = ACPI_TYPE_INTEGER;648 break;649 /* add more types as needed */650 default:651 pr_err("acpi_evalf() called with invalid format character '%c'\n",652 c);653 va_end(ap);654 return 0;655 }656 }657 va_end(ap);658 659 if (res_type != 'v') {660 result.length = sizeof(out_obj);661 result.pointer = &out_obj;662 resultp = &result;663 } else664 resultp = NULL;665 666 status = acpi_evaluate_object(handle, method, ¶ms, resultp);667 668 switch (res_type) {669 case 'd': /* int */670 success = (status == AE_OK &&671 out_obj.type == ACPI_TYPE_INTEGER);672 if (success && res)673 *res = out_obj.integer.value;674 break;675 case 'v': /* void */676 success = status == AE_OK;677 break;678 /* add more types as needed */679 default:680 pr_err("acpi_evalf() called with invalid format character '%c'\n",681 res_type);682 return 0;683 }684 685 if (!success && !quiet)686 pr_err("acpi_evalf(%s, %s, ...) failed: %s\n",687 method, fmt0, acpi_format_exception(status));688 689 return success;690}691 692static int acpi_ec_read(int i, u8 *p)693{694 int v;695 696 if (ecrd_handle) {697 if (!acpi_evalf(ecrd_handle, &v, NULL, "dd", i))698 return 0;699 *p = v;700 } else {701 if (ec_read(i, p) < 0)702 return 0;703 }704 705 return 1;706}707 708static int acpi_ec_write(int i, u8 v)709{710 if (ecwr_handle) {711 if (!acpi_evalf(ecwr_handle, NULL, NULL, "vdd", i, v))712 return 0;713 } else {714 if (ec_write(i, v) < 0)715 return 0;716 }717 718 return 1;719}720 721static int issue_thinkpad_cmos_command(int cmos_cmd)722{723 if (!cmos_handle)724 return -ENXIO;725 726 if (!acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd))727 return -EIO;728 729 return 0;730}731 732/*************************************************************************733 * ACPI device model734 */735 736#define TPACPI_ACPIHANDLE_INIT(object) \737 drv_acpi_handle_init(#object, &object##_handle, *object##_parent, \738 object##_paths, ARRAY_SIZE(object##_paths))739 740static void __init drv_acpi_handle_init(const char *name,741 acpi_handle *handle, const acpi_handle parent,742 char **paths, const int num_paths)743{744 int i;745 acpi_status status;746 747 vdbg_printk(TPACPI_DBG_INIT, "trying to locate ACPI handle for %s\n",748 name);749 750 for (i = 0; i < num_paths; i++) {751 status = acpi_get_handle(parent, paths[i], handle);752 if (ACPI_SUCCESS(status)) {753 dbg_printk(TPACPI_DBG_INIT,754 "Found ACPI handle %s for %s\n",755 paths[i], name);756 return;757 }758 }759 760 vdbg_printk(TPACPI_DBG_INIT, "ACPI handle for %s not found\n",761 name);762 *handle = NULL;763}764 765static acpi_status __init tpacpi_acpi_handle_locate_callback(acpi_handle handle,766 u32 level, void *context, void **return_value)767{768 if (!strcmp(context, "video")) {769 struct acpi_device *dev = acpi_fetch_acpi_dev(handle);770 771 if (!dev || strcmp(ACPI_VIDEO_HID, acpi_device_hid(dev)))772 return AE_OK;773 }774 775 *(acpi_handle *)return_value = handle;776 777 return AE_CTRL_TERMINATE;778}779 780static void __init tpacpi_acpi_handle_locate(const char *name,781 const char *hid,782 acpi_handle *handle)783{784 acpi_status status;785 acpi_handle device_found;786 787 BUG_ON(!name || !handle);788 vdbg_printk(TPACPI_DBG_INIT,789 "trying to locate ACPI handle for %s, using HID %s\n",790 name, hid ? hid : "NULL");791 792 memset(&device_found, 0, sizeof(device_found));793 status = acpi_get_devices(hid, tpacpi_acpi_handle_locate_callback,794 (void *)name, &device_found);795 796 *handle = NULL;797 798 if (ACPI_SUCCESS(status)) {799 *handle = device_found;800 dbg_printk(TPACPI_DBG_INIT,801 "Found ACPI handle for %s\n", name);802 } else {803 vdbg_printk(TPACPI_DBG_INIT,804 "Could not locate an ACPI handle for %s: %s\n",805 name, acpi_format_exception(status));806 }807}808 809static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data)810{811 struct ibm_struct *ibm = data;812 813 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)814 return;815 816 if (!ibm || !ibm->acpi || !ibm->acpi->notify)817 return;818 819 ibm->acpi->notify(ibm, event);820}821 822static int __init setup_acpi_notify(struct ibm_struct *ibm)823{824 acpi_status status;825 826 BUG_ON(!ibm->acpi);827 828 if (!*ibm->acpi->handle)829 return 0;830 831 vdbg_printk(TPACPI_DBG_INIT,832 "setting up ACPI notify for %s\n", ibm->name);833 834 ibm->acpi->device = acpi_fetch_acpi_dev(*ibm->acpi->handle);835 if (!ibm->acpi->device) {836 pr_err("acpi_fetch_acpi_dev(%s) failed\n", ibm->name);837 return -ENODEV;838 }839 840 ibm->acpi->device->driver_data = ibm;841 sprintf(acpi_device_class(ibm->acpi->device), "%s/%s",842 TPACPI_ACPI_EVENT_PREFIX,843 ibm->name);844 845 status = acpi_install_notify_handler(*ibm->acpi->handle,846 ibm->acpi->type, dispatch_acpi_notify, ibm);847 if (ACPI_FAILURE(status)) {848 if (status == AE_ALREADY_EXISTS) {849 pr_notice("another device driver is already handling %s events\n",850 ibm->name);851 } else {852 pr_err("acpi_install_notify_handler(%s) failed: %s\n",853 ibm->name, acpi_format_exception(status));854 }855 return -ENODEV;856 }857 ibm->flags.acpi_notify_installed = 1;858 return 0;859}860 861static int __init tpacpi_device_add(struct acpi_device *device)862{863 return 0;864}865 866static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)867{868 int rc;869 870 dbg_printk(TPACPI_DBG_INIT,871 "registering %s as an ACPI driver\n", ibm->name);872 873 BUG_ON(!ibm->acpi);874 875 ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);876 if (!ibm->acpi->driver) {877 pr_err("failed to allocate memory for ibm->acpi->driver\n");878 return -ENOMEM;879 }880 881 sprintf(ibm->acpi->driver->name, "%s_%s", TPACPI_NAME, ibm->name);882 ibm->acpi->driver->ids = ibm->acpi->hid;883 884 ibm->acpi->driver->ops.add = &tpacpi_device_add;885 886 rc = acpi_bus_register_driver(ibm->acpi->driver);887 if (rc < 0) {888 pr_err("acpi_bus_register_driver(%s) failed: %d\n",889 ibm->name, rc);890 kfree(ibm->acpi->driver);891 ibm->acpi->driver = NULL;892 } else if (!rc)893 ibm->flags.acpi_driver_registered = 1;894 895 return rc;896}897 898 899/****************************************************************************900 ****************************************************************************901 *902 * Procfs Helpers903 *904 ****************************************************************************905 ****************************************************************************/906 907static int dispatch_proc_show(struct seq_file *m, void *v)908{909 struct ibm_struct *ibm = m->private;910 911 if (!ibm || !ibm->read)912 return -EINVAL;913 return ibm->read(m);914}915 916static int dispatch_proc_open(struct inode *inode, struct file *file)917{918 return single_open(file, dispatch_proc_show, pde_data(inode));919}920 921static ssize_t dispatch_proc_write(struct file *file,922 const char __user *userbuf,923 size_t count, loff_t *pos)924{925 struct ibm_struct *ibm = pde_data(file_inode(file));926 char *kernbuf;927 int ret;928 929 if (!ibm || !ibm->write)930 return -EINVAL;931 if (count > PAGE_SIZE - 1)932 return -EINVAL;933 934 kernbuf = memdup_user_nul(userbuf, count);935 if (IS_ERR(kernbuf))936 return PTR_ERR(kernbuf);937 ret = ibm->write(kernbuf);938 if (ret == 0)939 ret = count;940 941 kfree(kernbuf);942 943 return ret;944}945 946static const struct proc_ops dispatch_proc_ops = {947 .proc_open = dispatch_proc_open,948 .proc_read = seq_read,949 .proc_lseek = seq_lseek,950 .proc_release = single_release,951 .proc_write = dispatch_proc_write,952};953 954/****************************************************************************955 ****************************************************************************956 *957 * Device model: input, hwmon and platform958 *959 ****************************************************************************960 ****************************************************************************/961 962static struct platform_device *tpacpi_pdev;963static struct platform_device *tpacpi_sensors_pdev;964static struct device *tpacpi_hwmon;965static struct input_dev *tpacpi_inputdev;966static struct mutex tpacpi_inputdev_send_mutex;967static LIST_HEAD(tpacpi_all_drivers);968 969#ifdef CONFIG_PM_SLEEP970static int tpacpi_suspend_handler(struct device *dev)971{972 struct ibm_struct *ibm, *itmp;973 974 list_for_each_entry_safe(ibm, itmp,975 &tpacpi_all_drivers,976 all_drivers) {977 if (ibm->suspend)978 (ibm->suspend)();979 }980 981 return 0;982}983 984static int tpacpi_resume_handler(struct device *dev)985{986 struct ibm_struct *ibm, *itmp;987 988 list_for_each_entry_safe(ibm, itmp,989 &tpacpi_all_drivers,990 all_drivers) {991 if (ibm->resume)992 (ibm->resume)();993 }994 995 return 0;996}997#endif998 999static SIMPLE_DEV_PM_OPS(tpacpi_pm,1000 tpacpi_suspend_handler, tpacpi_resume_handler);1001 1002static void tpacpi_shutdown_handler(struct platform_device *pdev)1003{1004 struct ibm_struct *ibm, *itmp;1005 1006 list_for_each_entry_safe(ibm, itmp,1007 &tpacpi_all_drivers,1008 all_drivers) {1009 if (ibm->shutdown)1010 (ibm->shutdown)();1011 }1012}1013 1014/*************************************************************************1015 * sysfs support helpers1016 */1017 1018static int parse_strtoul(const char *buf,1019 unsigned long max, unsigned long *value)1020{1021 char *endp;1022 1023 *value = simple_strtoul(skip_spaces(buf), &endp, 0);1024 endp = skip_spaces(endp);1025 if (*endp || *value > max)1026 return -EINVAL;1027 1028 return 0;1029}1030 1031static void tpacpi_disable_brightness_delay(void)1032{1033 if (acpi_evalf(hkey_handle, NULL, "PWMS", "qvd", 0))1034 pr_notice("ACPI backlight control delay disabled\n");1035}1036 1037static void printk_deprecated_attribute(const char * const what,1038 const char * const details)1039{1040 tpacpi_log_usertask("deprecated sysfs attribute");1041 pr_warn("WARNING: sysfs attribute %s is deprecated and will be removed. %s\n",1042 what, details);1043}1044 1045/*************************************************************************1046 * rfkill and radio control support helpers1047 */1048 1049/*1050 * ThinkPad-ACPI firmware handling model:1051 *1052 * WLSW (master wireless switch) is event-driven, and is common to all1053 * firmware-controlled radios. It cannot be controlled, just monitored,1054 * as expected. It overrides all radio state in firmware1055 *1056 * The kernel, a masked-off hotkey, and WLSW can change the radio state1057 * (TODO: verify how WLSW interacts with the returned radio state).1058 *1059 * The only time there are shadow radio state changes, is when1060 * masked-off hotkeys are used.1061 */1062 1063/*1064 * Internal driver API for radio state:1065 *1066 * int: < 0 = error, otherwise enum tpacpi_rfkill_state1067 * bool: true means radio blocked (off)1068 */1069enum tpacpi_rfkill_state {1070 TPACPI_RFK_RADIO_OFF = 0,1071 TPACPI_RFK_RADIO_ON1072};1073 1074/* rfkill switches */1075enum tpacpi_rfk_id {1076 TPACPI_RFK_BLUETOOTH_SW_ID = 0,1077 TPACPI_RFK_WWAN_SW_ID,1078 TPACPI_RFK_UWB_SW_ID,1079 TPACPI_RFK_SW_MAX1080};1081 1082static const char *tpacpi_rfkill_names[] = {1083 [TPACPI_RFK_BLUETOOTH_SW_ID] = "bluetooth",1084 [TPACPI_RFK_WWAN_SW_ID] = "wwan",1085 [TPACPI_RFK_UWB_SW_ID] = "uwb",1086 [TPACPI_RFK_SW_MAX] = NULL1087};1088 1089/* ThinkPad-ACPI rfkill subdriver */1090struct tpacpi_rfk {1091 struct rfkill *rfkill;1092 enum tpacpi_rfk_id id;1093 const struct tpacpi_rfk_ops *ops;1094};1095 1096struct tpacpi_rfk_ops {1097 /* firmware interface */1098 int (*get_status)(void);1099 int (*set_status)(const enum tpacpi_rfkill_state);1100};1101 1102static struct tpacpi_rfk *tpacpi_rfkill_switches[TPACPI_RFK_SW_MAX];1103 1104/* Query FW and update rfkill sw state for a given rfkill switch */1105static int tpacpi_rfk_update_swstate(const struct tpacpi_rfk *tp_rfk)1106{1107 int status;1108 1109 if (!tp_rfk)1110 return -ENODEV;1111 1112 status = (tp_rfk->ops->get_status)();1113 if (status < 0)1114 return status;1115 1116 rfkill_set_sw_state(tp_rfk->rfkill,1117 (status == TPACPI_RFK_RADIO_OFF));1118 1119 return status;1120}1121 1122/*1123 * Sync the HW-blocking state of all rfkill switches,1124 * do notice it causes the rfkill core to schedule uevents1125 */1126static void tpacpi_rfk_update_hwblock_state(bool blocked)1127{1128 unsigned int i;1129 struct tpacpi_rfk *tp_rfk;1130 1131 for (i = 0; i < TPACPI_RFK_SW_MAX; i++) {1132 tp_rfk = tpacpi_rfkill_switches[i];1133 if (tp_rfk) {1134 if (rfkill_set_hw_state(tp_rfk->rfkill,1135 blocked)) {1136 /* ignore -- we track sw block */1137 }1138 }1139 }1140}1141 1142/* Call to get the WLSW state from the firmware */1143static int hotkey_get_wlsw(void);1144 1145/* Call to query WLSW state and update all rfkill switches */1146static bool tpacpi_rfk_check_hwblock_state(void)1147{1148 int res = hotkey_get_wlsw();1149 int hw_blocked;1150 1151 /* When unknown or unsupported, we have to assume it is unblocked */1152 if (res < 0)1153 return false;1154 1155 hw_blocked = (res == TPACPI_RFK_RADIO_OFF);1156 tpacpi_rfk_update_hwblock_state(hw_blocked);1157 1158 return hw_blocked;1159}1160 1161static int tpacpi_rfk_hook_set_block(void *data, bool blocked)1162{1163 struct tpacpi_rfk *tp_rfk = data;1164 int res;1165 1166 dbg_printk(TPACPI_DBG_RFKILL,1167 "request to change radio state to %s\n",1168 blocked ? "blocked" : "unblocked");1169 1170 /* try to set radio state */1171 res = (tp_rfk->ops->set_status)(blocked ?1172 TPACPI_RFK_RADIO_OFF : TPACPI_RFK_RADIO_ON);1173 1174 /* and update the rfkill core with whatever the FW really did */1175 tpacpi_rfk_update_swstate(tp_rfk);1176 1177 return (res < 0) ? res : 0;1178}1179 1180static const struct rfkill_ops tpacpi_rfk_rfkill_ops = {1181 .set_block = tpacpi_rfk_hook_set_block,1182};1183 1184static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,1185 const struct tpacpi_rfk_ops *tp_rfkops,1186 const enum rfkill_type rfktype,1187 const char *name,1188 const bool set_default)1189{1190 struct tpacpi_rfk *atp_rfk;1191 int res;1192 bool sw_state = false;1193 bool hw_state;1194 int sw_status;1195 1196 BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]);1197 1198 atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL);1199 if (atp_rfk)1200 atp_rfk->rfkill = rfkill_alloc(name,1201 &tpacpi_pdev->dev,1202 rfktype,1203 &tpacpi_rfk_rfkill_ops,1204 atp_rfk);1205 if (!atp_rfk || !atp_rfk->rfkill) {1206 pr_err("failed to allocate memory for rfkill class\n");1207 kfree(atp_rfk);1208 return -ENOMEM;1209 }1210 1211 atp_rfk->id = id;1212 atp_rfk->ops = tp_rfkops;1213 1214 sw_status = (tp_rfkops->get_status)();1215 if (sw_status < 0) {1216 pr_err("failed to read initial state for %s, error %d\n",1217 name, sw_status);1218 } else {1219 sw_state = (sw_status == TPACPI_RFK_RADIO_OFF);1220 if (set_default) {1221 /* try to keep the initial state, since we ask the1222 * firmware to preserve it across S5 in NVRAM */1223 rfkill_init_sw_state(atp_rfk->rfkill, sw_state);1224 }1225 }1226 hw_state = tpacpi_rfk_check_hwblock_state();1227 rfkill_set_hw_state(atp_rfk->rfkill, hw_state);1228 1229 res = rfkill_register(atp_rfk->rfkill);1230 if (res < 0) {1231 pr_err("failed to register %s rfkill switch: %d\n", name, res);1232 rfkill_destroy(atp_rfk->rfkill);1233 kfree(atp_rfk);1234 return res;1235 }1236 1237 tpacpi_rfkill_switches[id] = atp_rfk;1238 1239 pr_info("rfkill switch %s: radio is %sblocked\n",1240 name, (sw_state || hw_state) ? "" : "un");1241 return 0;1242}1243 1244static void tpacpi_destroy_rfkill(const enum tpacpi_rfk_id id)1245{1246 struct tpacpi_rfk *tp_rfk;1247 1248 BUG_ON(id >= TPACPI_RFK_SW_MAX);1249 1250 tp_rfk = tpacpi_rfkill_switches[id];1251 if (tp_rfk) {1252 rfkill_unregister(tp_rfk->rfkill);1253 rfkill_destroy(tp_rfk->rfkill);1254 tpacpi_rfkill_switches[id] = NULL;1255 kfree(tp_rfk);1256 }1257}1258 1259static void printk_deprecated_rfkill_attribute(const char * const what)1260{1261 printk_deprecated_attribute(what,1262 "Please switch to generic rfkill before year 2010");1263}1264 1265/* sysfs <radio> enable ------------------------------------------------ */1266static ssize_t tpacpi_rfk_sysfs_enable_show(const enum tpacpi_rfk_id id,1267 struct device_attribute *attr,1268 char *buf)1269{1270 int status;1271 1272 printk_deprecated_rfkill_attribute(attr->attr.name);1273 1274 /* This is in the ABI... */1275 if (tpacpi_rfk_check_hwblock_state()) {1276 status = TPACPI_RFK_RADIO_OFF;1277 } else {1278 status = tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);1279 if (status < 0)1280 return status;1281 }1282 1283 return sysfs_emit(buf, "%d\n",1284 (status == TPACPI_RFK_RADIO_ON) ? 1 : 0);1285}1286 1287static ssize_t tpacpi_rfk_sysfs_enable_store(const enum tpacpi_rfk_id id,1288 struct device_attribute *attr,1289 const char *buf, size_t count)1290{1291 unsigned long t;1292 int res;1293 1294 printk_deprecated_rfkill_attribute(attr->attr.name);1295 1296 if (parse_strtoul(buf, 1, &t))1297 return -EINVAL;1298 1299 tpacpi_disclose_usertask(attr->attr.name, "set to %ld\n", t);1300 1301 /* This is in the ABI... */1302 if (tpacpi_rfk_check_hwblock_state() && !!t)1303 return -EPERM;1304 1305 res = tpacpi_rfkill_switches[id]->ops->set_status((!!t) ?1306 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF);1307 tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);1308 1309 return (res < 0) ? res : count;1310}1311 1312/* procfs -------------------------------------------------------------- */1313static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, struct seq_file *m)1314{1315 if (id >= TPACPI_RFK_SW_MAX)1316 seq_printf(m, "status:\t\tnot supported\n");1317 else {1318 int status;1319 1320 /* This is in the ABI... */1321 if (tpacpi_rfk_check_hwblock_state()) {1322 status = TPACPI_RFK_RADIO_OFF;1323 } else {1324 status = tpacpi_rfk_update_swstate(1325 tpacpi_rfkill_switches[id]);1326 if (status < 0)1327 return status;1328 }1329 1330 seq_printf(m, "status:\t\t%s\n", str_enabled_disabled(status == TPACPI_RFK_RADIO_ON));1331 seq_printf(m, "commands:\tenable, disable\n");1332 }1333 1334 return 0;1335}1336 1337static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf)1338{1339 char *cmd;1340 int status = -1;1341 int res = 0;1342 1343 if (id >= TPACPI_RFK_SW_MAX)1344 return -ENODEV;1345 1346 while ((cmd = strsep(&buf, ","))) {1347 if (strstarts(cmd, "enable"))1348 status = TPACPI_RFK_RADIO_ON;1349 else if (strstarts(cmd, "disable"))1350 status = TPACPI_RFK_RADIO_OFF;1351 else1352 return -EINVAL;1353 }1354 1355 if (status != -1) {1356 tpacpi_disclose_usertask("procfs", "attempt to %s %s\n",1357 str_enable_disable(status == TPACPI_RFK_RADIO_ON),1358 tpacpi_rfkill_names[id]);1359 res = (tpacpi_rfkill_switches[id]->ops->set_status)(status);1360 tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);1361 }1362 1363 return res;1364}1365 1366/*************************************************************************1367 * thinkpad-acpi driver attributes1368 */1369 1370/* interface_version --------------------------------------------------- */1371static ssize_t interface_version_show(struct device_driver *drv, char *buf)1372{1373 return sysfs_emit(buf, "0x%08x\n", TPACPI_SYSFS_VERSION);1374}1375static DRIVER_ATTR_RO(interface_version);1376 1377/* debug_level --------------------------------------------------------- */1378static ssize_t debug_level_show(struct device_driver *drv, char *buf)1379{1380 return sysfs_emit(buf, "0x%04x\n", dbg_level);1381}1382 1383static ssize_t debug_level_store(struct device_driver *drv, const char *buf,1384 size_t count)1385{1386 unsigned long t;1387 1388 if (parse_strtoul(buf, 0xffff, &t))1389 return -EINVAL;1390 1391 dbg_level = t;1392 1393 return count;1394}1395static DRIVER_ATTR_RW(debug_level);1396 1397/* version ------------------------------------------------------------- */1398static ssize_t version_show(struct device_driver *drv, char *buf)1399{1400 return sysfs_emit(buf, "%s v%s\n",1401 TPACPI_DESC, TPACPI_VERSION);1402}1403static DRIVER_ATTR_RO(version);1404 1405/* --------------------------------------------------------------------- */1406 1407#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES1408 1409/* wlsw_emulstate ------------------------------------------------------ */1410static ssize_t wlsw_emulstate_show(struct device_driver *drv, char *buf)1411{1412 return sysfs_emit(buf, "%d\n", !!tpacpi_wlsw_emulstate);1413}1414 1415static ssize_t wlsw_emulstate_store(struct device_driver *drv, const char *buf,1416 size_t count)1417{1418 unsigned long t;1419 1420 if (parse_strtoul(buf, 1, &t))1421 return -EINVAL;1422 1423 if (tpacpi_wlsw_emulstate != !!t) {1424 tpacpi_wlsw_emulstate = !!t;1425 tpacpi_rfk_update_hwblock_state(!t); /* negative logic */1426 }1427 1428 return count;1429}1430static DRIVER_ATTR_RW(wlsw_emulstate);1431 1432/* bluetooth_emulstate ------------------------------------------------- */1433static ssize_t bluetooth_emulstate_show(struct device_driver *drv, char *buf)1434{1435 return sysfs_emit(buf, "%d\n", !!tpacpi_bluetooth_emulstate);1436}1437 1438static ssize_t bluetooth_emulstate_store(struct device_driver *drv,1439 const char *buf, size_t count)1440{1441 unsigned long t;1442 1443 if (parse_strtoul(buf, 1, &t))1444 return -EINVAL;1445 1446 tpacpi_bluetooth_emulstate = !!t;1447 1448 return count;1449}1450static DRIVER_ATTR_RW(bluetooth_emulstate);1451 1452/* wwan_emulstate ------------------------------------------------- */1453static ssize_t wwan_emulstate_show(struct device_driver *drv, char *buf)1454{1455 return sysfs_emit(buf, "%d\n", !!tpacpi_wwan_emulstate);1456}1457 1458static ssize_t wwan_emulstate_store(struct device_driver *drv, const char *buf,1459 size_t count)1460{1461 unsigned long t;1462 1463 if (parse_strtoul(buf, 1, &t))1464 return -EINVAL;1465 1466 tpacpi_wwan_emulstate = !!t;1467 1468 return count;1469}1470static DRIVER_ATTR_RW(wwan_emulstate);1471 1472/* uwb_emulstate ------------------------------------------------- */1473static ssize_t uwb_emulstate_show(struct device_driver *drv, char *buf)1474{1475 return sysfs_emit(buf, "%d\n", !!tpacpi_uwb_emulstate);1476}1477 1478static ssize_t uwb_emulstate_store(struct device_driver *drv, const char *buf,1479 size_t count)1480{1481 unsigned long t;1482 1483 if (parse_strtoul(buf, 1, &t))1484 return -EINVAL;1485 1486 tpacpi_uwb_emulstate = !!t;1487 1488 return count;1489}1490static DRIVER_ATTR_RW(uwb_emulstate);1491#endif1492 1493/*************************************************************************1494 * Firmware Data1495 */1496 1497/*1498 * Table of recommended minimum BIOS versions1499 *1500 * Reasons for listing:1501 * 1. Stable BIOS, listed because the unknown amount of1502 * bugs and bad ACPI behaviour on older versions1503 *1504 * 2. BIOS or EC fw with known bugs that trigger on Linux1505 *1506 * 3. BIOS with known reduced functionality in older versions1507 *1508 * We recommend the latest BIOS and EC version.1509 * We only support the latest BIOS and EC fw version as a rule.1510 *1511 * Sources: IBM ThinkPad Public Web Documents (update changelogs),1512 * Information from users in ThinkWiki1513 *1514 * WARNING: we use this table also to detect that the machine is1515 * a ThinkPad in some cases, so don't remove entries lightly.1516 */1517 1518#define TPV_Q(__v, __id1, __id2, __bv1, __bv2) \1519 { .vendor = (__v), \1520 .bios = TPID(__id1, __id2), \1521 .ec = TPACPI_MATCH_ANY, \1522 .quirks = TPACPI_MATCH_ANY_VERSION << 16 \1523 | TPVER(__bv1, __bv2) }1524 1525#define TPV_Q_X(__v, __bid1, __bid2, __bv1, __bv2, \1526 __eid, __ev1, __ev2) \1527 { .vendor = (__v), \1528 .bios = TPID(__bid1, __bid2), \1529 .ec = __eid, \1530 .quirks = TPVER(__ev1, __ev2) << 16 \1531 | TPVER(__bv1, __bv2) }1532 1533#define TPV_QI0(__id1, __id2, __bv1, __bv2) \1534 TPV_Q(PCI_VENDOR_ID_IBM, __id1, __id2, __bv1, __bv2)1535 1536/* Outdated IBM BIOSes often lack the EC id string */1537#define TPV_QI1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \1538 TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2, \1539 __bv1, __bv2, TPID(__id1, __id2), \1540 __ev1, __ev2), \1541 TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2, \1542 __bv1, __bv2, TPACPI_MATCH_UNKNOWN, \1543 __ev1, __ev2)1544 1545/* Outdated IBM BIOSes often lack the EC id string */1546#define TPV_QI2(__bid1, __bid2, __bv1, __bv2, \1547 __eid1, __eid2, __ev1, __ev2) \1548 TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2, \1549 __bv1, __bv2, TPID(__eid1, __eid2), \1550 __ev1, __ev2), \1551 TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2, \1552 __bv1, __bv2, TPACPI_MATCH_UNKNOWN, \1553 __ev1, __ev2)1554 1555#define TPV_QL0(__id1, __id2, __bv1, __bv2) \1556 TPV_Q(PCI_VENDOR_ID_LENOVO, __id1, __id2, __bv1, __bv2)1557 1558#define TPV_QL1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \1559 TPV_Q_X(PCI_VENDOR_ID_LENOVO, __id1, __id2, \1560 __bv1, __bv2, TPID(__id1, __id2), \1561 __ev1, __ev2)1562 1563#define TPV_QL2(__bid1, __bid2, __bv1, __bv2, \1564 __eid1, __eid2, __ev1, __ev2) \1565 TPV_Q_X(PCI_VENDOR_ID_LENOVO, __bid1, __bid2, \1566 __bv1, __bv2, TPID(__eid1, __eid2), \1567 __ev1, __ev2)1568 1569static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = {1570 /* Numeric models ------------------ */1571 /* FW MODEL BIOS VERS */1572 TPV_QI0('I', 'M', '6', '5'), /* 570 */1573 TPV_QI0('I', 'U', '2', '6'), /* 570E */1574 TPV_QI0('I', 'B', '5', '4'), /* 600 */1575 TPV_QI0('I', 'H', '4', '7'), /* 600E */1576 TPV_QI0('I', 'N', '3', '6'), /* 600E */1577 TPV_QI0('I', 'T', '5', '5'), /* 600X */1578 TPV_QI0('I', 'D', '4', '8'), /* 770, 770E, 770ED */1579 TPV_QI0('I', 'I', '4', '2'), /* 770X */1580 TPV_QI0('I', 'O', '2', '3'), /* 770Z */1581 1582 /* A-series ------------------------- */1583 /* FW MODEL BIOS VERS EC VERS */1584 TPV_QI0('I', 'W', '5', '9'), /* A20m */1585 TPV_QI0('I', 'V', '6', '9'), /* A20p */1586 TPV_QI0('1', '0', '2', '6'), /* A21e, A22e */1587 TPV_QI0('K', 'U', '3', '6'), /* A21e */1588 TPV_QI0('K', 'X', '3', '6'), /* A21m, A22m */1589 TPV_QI0('K', 'Y', '3', '8'), /* A21p, A22p */1590 TPV_QI0('1', 'B', '1', '7'), /* A22e */1591 TPV_QI0('1', '3', '2', '0'), /* A22m */1592 TPV_QI0('1', 'E', '7', '3'), /* A30/p (0) */1593 TPV_QI1('1', 'G', '4', '1', '1', '7'), /* A31/p (0) */1594 TPV_QI1('1', 'N', '1', '6', '0', '7'), /* A31/p (0) */1595 1596 /* G-series ------------------------- */1597 /* FW MODEL BIOS VERS */1598 TPV_QI0('1', 'T', 'A', '6'), /* G40 */1599 TPV_QI0('1', 'X', '5', '7'), /* G41 */1600 1601 /* R-series, T-series --------------- */1602 /* FW MODEL BIOS VERS EC VERS */1603 TPV_QI0('1', 'C', 'F', '0'), /* R30 */1604 TPV_QI0('1', 'F', 'F', '1'), /* R31 */1605 TPV_QI0('1', 'M', '9', '7'), /* R32 */1606 TPV_QI0('1', 'O', '6', '1'), /* R40 */1607 TPV_QI0('1', 'P', '6', '5'), /* R40 */1608 TPV_QI0('1', 'S', '7', '0'), /* R40e */1609 TPV_QI1('1', 'R', 'D', 'R', '7', '1'), /* R50/p, R51,1610 T40/p, T41/p, T42/p (1) */1611 TPV_QI1('1', 'V', '7', '1', '2', '8'), /* R50e, R51 (1) */1612 TPV_QI1('7', '8', '7', '1', '0', '6'), /* R51e (1) */1613 TPV_QI1('7', '6', '6', '9', '1', '6'), /* R52 (1) */1614 TPV_QI1('7', '0', '6', '9', '2', '8'), /* R52, T43 (1) */1615 1616 TPV_QI0('I', 'Y', '6', '1'), /* T20 */1617 TPV_QI0('K', 'Z', '3', '4'), /* T21 */1618 TPV_QI0('1', '6', '3', '2'), /* T22 */1619 TPV_QI1('1', 'A', '6', '4', '2', '3'), /* T23 (0) */1620 TPV_QI1('1', 'I', '7', '1', '2', '0'), /* T30 (0) */1621 TPV_QI1('1', 'Y', '6', '5', '2', '9'), /* T43/p (1) */1622 1623 TPV_QL1('7', '9', 'E', '3', '5', '0'), /* T60/p */1624 TPV_QL1('7', 'C', 'D', '2', '2', '2'), /* R60, R60i */1625 TPV_QL1('7', 'E', 'D', '0', '1', '5'), /* R60e, R60i */1626 1627 /* BIOS FW BIOS VERS EC FW EC VERS */1628 TPV_QI2('1', 'W', '9', '0', '1', 'V', '2', '8'), /* R50e (1) */1629 TPV_QL2('7', 'I', '3', '4', '7', '9', '5', '0'), /* T60/p wide */1630 1631 /* X-series ------------------------- */1632 /* FW MODEL BIOS VERS EC VERS */1633 TPV_QI0('I', 'Z', '9', 'D'), /* X20, X21 */1634 TPV_QI0('1', 'D', '7', '0'), /* X22, X23, X24 */1635 TPV_QI1('1', 'K', '4', '8', '1', '8'), /* X30 (0) */1636 TPV_QI1('1', 'Q', '9', '7', '2', '3'), /* X31, X32 (0) */1637 TPV_QI1('1', 'U', 'D', '3', 'B', '2'), /* X40 (0) */1638 TPV_QI1('7', '4', '6', '4', '2', '7'), /* X41 (0) */1639 TPV_QI1('7', '5', '6', '0', '2', '0'), /* X41t (0) */1640 1641 TPV_QL1('7', 'B', 'D', '7', '4', '0'), /* X60/s */1642 TPV_QL1('7', 'J', '3', '0', '1', '3'), /* X60t */1643 1644 /* (0) - older versions lack DMI EC fw string and functionality */1645 /* (1) - older versions known to lack functionality */1646};1647 1648#undef TPV_QL11649#undef TPV_QL01650#undef TPV_QI21651#undef TPV_QI11652#undef TPV_QI01653#undef TPV_Q_X1654#undef TPV_Q1655 1656static void __init tpacpi_check_outdated_fw(void)1657{1658 unsigned long fwvers;1659 u16 ec_version, bios_version;1660 1661 fwvers = tpacpi_check_quirks(tpacpi_bios_version_qtable,1662 ARRAY_SIZE(tpacpi_bios_version_qtable));1663 1664 if (!fwvers)1665 return;1666 1667 bios_version = fwvers & 0xffffU;1668 ec_version = (fwvers >> 16) & 0xffffU;1669 1670 /* note that unknown versions are set to 0x0000 and we use that */1671 if ((bios_version > thinkpad_id.bios_release) ||1672 (ec_version > thinkpad_id.ec_release &&1673 ec_version != TPACPI_MATCH_ANY_VERSION)) {1674 /*1675 * The changelogs would let us track down the exact1676 * reason, but it is just too much of a pain to track1677 * it. We only list BIOSes that are either really1678 * broken, or really stable to begin with, so it is1679 * best if the user upgrades the firmware anyway.1680 */1681 pr_warn("WARNING: Outdated ThinkPad BIOS/EC firmware\n");1682 pr_warn("WARNING: This firmware may be missing critical bug fixes and/or important features\n");1683 }1684}1685 1686static bool __init tpacpi_is_fw_known(void)1687{1688 return tpacpi_check_quirks(tpacpi_bios_version_qtable,1689 ARRAY_SIZE(tpacpi_bios_version_qtable)) != 0;1690}1691 1692/****************************************************************************1693 ****************************************************************************1694 *1695 * Subdrivers1696 *1697 ****************************************************************************1698 ****************************************************************************/1699 1700/*************************************************************************1701 * thinkpad-acpi metadata subdriver1702 */1703 1704static int thinkpad_acpi_driver_read(struct seq_file *m)1705{1706 seq_printf(m, "driver:\t\t%s\n", TPACPI_DESC);1707 seq_printf(m, "version:\t%s\n", TPACPI_VERSION);1708 return 0;1709}1710 1711static struct ibm_struct thinkpad_acpi_driver_data = {1712 .name = "driver",1713 .read = thinkpad_acpi_driver_read,1714};1715 1716/*************************************************************************1717 * Hotkey subdriver1718 */1719 1720/*1721 * ThinkPad firmware event model1722 *1723 * The ThinkPad firmware has two main event interfaces: normal ACPI1724 * notifications (which follow the ACPI standard), and a private event1725 * interface.1726 *1727 * The private event interface also issues events for the hotkeys. As1728 * the driver gained features, the event handling code ended up being1729 * built around the hotkey subdriver. This will need to be refactored1730 * to a more formal event API eventually.1731 *1732 * Some "hotkeys" are actually supposed to be used as event reports,1733 * such as "brightness has changed", "volume has changed", depending on1734 * the ThinkPad model and how the firmware is operating.1735 *1736 * Unlike other classes, hotkey-class events have mask/unmask control on1737 * non-ancient firmware. However, how it behaves changes a lot with the1738 * firmware model and version.1739 */1740 1741enum { /* hot key scan codes (derived from ACPI DSDT) */1742 TP_ACPI_HOTKEYSCAN_FNF1 = 0,1743 TP_ACPI_HOTKEYSCAN_FNF2,1744 TP_ACPI_HOTKEYSCAN_FNF3,1745 TP_ACPI_HOTKEYSCAN_FNF4,1746 TP_ACPI_HOTKEYSCAN_FNF5,1747 TP_ACPI_HOTKEYSCAN_FNF6,1748 TP_ACPI_HOTKEYSCAN_FNF7,1749 TP_ACPI_HOTKEYSCAN_FNF8,1750 TP_ACPI_HOTKEYSCAN_FNF9,1751 TP_ACPI_HOTKEYSCAN_FNF10,1752 TP_ACPI_HOTKEYSCAN_FNF11,1753 TP_ACPI_HOTKEYSCAN_FNF12,1754 TP_ACPI_HOTKEYSCAN_FNBACKSPACE,1755 TP_ACPI_HOTKEYSCAN_FNINSERT,1756 TP_ACPI_HOTKEYSCAN_FNDELETE,1757 TP_ACPI_HOTKEYSCAN_FNHOME,1758 TP_ACPI_HOTKEYSCAN_FNEND,1759 TP_ACPI_HOTKEYSCAN_FNPAGEUP,1760 TP_ACPI_HOTKEYSCAN_FNPAGEDOWN,1761 TP_ACPI_HOTKEYSCAN_FNSPACE,1762 TP_ACPI_HOTKEYSCAN_VOLUMEUP,1763 TP_ACPI_HOTKEYSCAN_VOLUMEDOWN,1764 TP_ACPI_HOTKEYSCAN_MUTE,1765 TP_ACPI_HOTKEYSCAN_THINKPAD,1766 TP_ACPI_HOTKEYSCAN_UNK1,1767 TP_ACPI_HOTKEYSCAN_UNK2,1768 TP_ACPI_HOTKEYSCAN_MICMUTE,1769 TP_ACPI_HOTKEYSCAN_UNK4,1770 TP_ACPI_HOTKEYSCAN_CONFIG,1771 TP_ACPI_HOTKEYSCAN_SEARCH,1772 TP_ACPI_HOTKEYSCAN_SCALE,1773 TP_ACPI_HOTKEYSCAN_FILE,1774 1775 /* Adaptive keyboard keycodes */1776 TP_ACPI_HOTKEYSCAN_ADAPTIVE_START, /* 32 / 0x20 */1777 TP_ACPI_HOTKEYSCAN_MUTE2 = TP_ACPI_HOTKEYSCAN_ADAPTIVE_START,1778 TP_ACPI_HOTKEYSCAN_BRIGHTNESS_ZERO,1779 TP_ACPI_HOTKEYSCAN_CLIPPING_TOOL,1780 TP_ACPI_HOTKEYSCAN_CLOUD,1781 TP_ACPI_HOTKEYSCAN_UNK9,1782 TP_ACPI_HOTKEYSCAN_VOICE,1783 TP_ACPI_HOTKEYSCAN_UNK10,1784 TP_ACPI_HOTKEYSCAN_GESTURES,1785 TP_ACPI_HOTKEYSCAN_UNK11,1786 TP_ACPI_HOTKEYSCAN_UNK12,1787 TP_ACPI_HOTKEYSCAN_UNK13,1788 TP_ACPI_HOTKEYSCAN_CONFIG2,1789 TP_ACPI_HOTKEYSCAN_NEW_TAB,1790 TP_ACPI_HOTKEYSCAN_RELOAD,1791 TP_ACPI_HOTKEYSCAN_BACK,1792 TP_ACPI_HOTKEYSCAN_MIC_DOWN,1793 TP_ACPI_HOTKEYSCAN_MIC_UP,1794 TP_ACPI_HOTKEYSCAN_MIC_CANCELLATION,1795 TP_ACPI_HOTKEYSCAN_CAMERA_MODE,1796 TP_ACPI_HOTKEYSCAN_ROTATE_DISPLAY,1797 1798 /* Lenovo extended keymap, starting at 0x1300 */1799 TP_ACPI_HOTKEYSCAN_EXTENDED_START, /* 52 / 0x34 */1800 /* first new observed key (star, favorites) is 0x1311 */1801 TP_ACPI_HOTKEYSCAN_STAR = 69,1802 TP_ACPI_HOTKEYSCAN_CLIPPING_TOOL2,1803 TP_ACPI_HOTKEYSCAN_CALCULATOR,1804 TP_ACPI_HOTKEYSCAN_BLUETOOTH,1805 TP_ACPI_HOTKEYSCAN_KEYBOARD,1806 TP_ACPI_HOTKEYSCAN_FN_RIGHT_SHIFT, /* Used by "Lenovo Quick Clean" */1807 TP_ACPI_HOTKEYSCAN_NOTIFICATION_CENTER,1808 TP_ACPI_HOTKEYSCAN_PICKUP_PHONE,1809 TP_ACPI_HOTKEYSCAN_HANGUP_PHONE,1810};1811 1812enum { /* Keys/events available through NVRAM polling */1813 TPACPI_HKEY_NVRAM_KNOWN_MASK = 0x00fb88c0U,1814 TPACPI_HKEY_NVRAM_GOOD_MASK = 0x00fb8000U,1815};1816 1817enum { /* Positions of some of the keys in hotkey masks */1818 TP_ACPI_HKEY_DISPSWTCH_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF7,1819 TP_ACPI_HKEY_DISPXPAND_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF8,1820 TP_ACPI_HKEY_HIBERNATE_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF12,1821 TP_ACPI_HKEY_BRGHTUP_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNHOME,1822 TP_ACPI_HKEY_BRGHTDWN_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNEND,1823 TP_ACPI_HKEY_KBD_LIGHT_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNPAGEUP,1824 TP_ACPI_HKEY_ZOOM_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNSPACE,1825 TP_ACPI_HKEY_VOLUP_MASK = 1 << TP_ACPI_HOTKEYSCAN_VOLUMEUP,1826 TP_ACPI_HKEY_VOLDWN_MASK = 1 << TP_ACPI_HOTKEYSCAN_VOLUMEDOWN,1827 TP_ACPI_HKEY_MUTE_MASK = 1 << TP_ACPI_HOTKEYSCAN_MUTE,1828 TP_ACPI_HKEY_THINKPAD_MASK = 1 << TP_ACPI_HOTKEYSCAN_THINKPAD,1829};1830 1831enum { /* NVRAM to ACPI HKEY group map */1832 TP_NVRAM_HKEY_GROUP_HK2 = TP_ACPI_HKEY_THINKPAD_MASK |1833 TP_ACPI_HKEY_ZOOM_MASK |1834 TP_ACPI_HKEY_DISPSWTCH_MASK |1835 TP_ACPI_HKEY_HIBERNATE_MASK,1836 TP_NVRAM_HKEY_GROUP_BRIGHTNESS = TP_ACPI_HKEY_BRGHTUP_MASK |1837 TP_ACPI_HKEY_BRGHTDWN_MASK,1838 TP_NVRAM_HKEY_GROUP_VOLUME = TP_ACPI_HKEY_VOLUP_MASK |1839 TP_ACPI_HKEY_VOLDWN_MASK |1840 TP_ACPI_HKEY_MUTE_MASK,1841};1842 1843#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL1844struct tp_nvram_state {1845 u16 thinkpad_toggle:1;1846 u16 zoom_toggle:1;1847 u16 display_toggle:1;1848 u16 thinklight_toggle:1;1849 u16 hibernate_toggle:1;1850 u16 displayexp_toggle:1;1851 u16 display_state:1;1852 u16 brightness_toggle:1;1853 u16 volume_toggle:1;1854 u16 mute:1;1855 1856 u8 brightness_level;1857 u8 volume_level;1858};1859 1860/* kthread for the hotkey poller */1861static struct task_struct *tpacpi_hotkey_task;1862 1863/*1864 * Acquire mutex to write poller control variables as an1865 * atomic block.1866 *1867 * Increment hotkey_config_change when changing them if you1868 * want the kthread to forget old state.1869 *1870 * See HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END1871 */1872static struct mutex hotkey_thread_data_mutex;1873static unsigned int hotkey_config_change;1874 1875/*1876 * hotkey poller control variables1877 *1878 * Must be atomic or readers will also need to acquire mutex1879 *1880 * HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END1881 * should be used only when the changes need to be taken as1882 * a block, OR when one needs to force the kthread to forget1883 * old state.1884 */1885static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */1886static unsigned int hotkey_poll_freq = 10; /* Hz */1887 1888#define HOTKEY_CONFIG_CRITICAL_START \1889 do { \1890 mutex_lock(&hotkey_thread_data_mutex); \1891 hotkey_config_change++; \1892 } while (0);1893#define HOTKEY_CONFIG_CRITICAL_END \1894 mutex_unlock(&hotkey_thread_data_mutex);1895 1896#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */1897 1898#define hotkey_source_mask 0U1899#define HOTKEY_CONFIG_CRITICAL_START1900#define HOTKEY_CONFIG_CRITICAL_END1901 1902#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */1903 1904static struct mutex hotkey_mutex;1905 1906static enum { /* Reasons for waking up */1907 TP_ACPI_WAKEUP_NONE = 0, /* None or unknown */1908 TP_ACPI_WAKEUP_BAYEJ, /* Bay ejection request */1909 TP_ACPI_WAKEUP_UNDOCK, /* Undock request */1910} hotkey_wakeup_reason;1911 1912static int hotkey_autosleep_ack;1913 1914static u32 hotkey_orig_mask; /* events the BIOS had enabled */1915static u32 hotkey_all_mask; /* all events supported in fw */1916static u32 hotkey_adaptive_all_mask; /* all adaptive events supported in fw */1917static u32 hotkey_reserved_mask; /* events better left disabled */1918static u32 hotkey_driver_mask; /* events needed by the driver */1919static u32 hotkey_user_mask; /* events visible to userspace */1920static u32 hotkey_acpi_mask; /* events enabled in firmware */1921 1922static bool tpacpi_driver_event(const unsigned int hkey_event);1923static void hotkey_poll_setup(const bool may_warn);1924 1925/* HKEY.MHKG() return bits */1926#define TP_HOTKEY_TABLET_MASK (1 << 3)1927enum {1928 TP_ACPI_MULTI_MODE_INVALID = 0,1929 TP_ACPI_MULTI_MODE_UNKNOWN = 1 << 0,1930 TP_ACPI_MULTI_MODE_LAPTOP = 1 << 1,1931 TP_ACPI_MULTI_MODE_TABLET = 1 << 2,1932 TP_ACPI_MULTI_MODE_FLAT = 1 << 3,1933 TP_ACPI_MULTI_MODE_STAND = 1 << 4,1934 TP_ACPI_MULTI_MODE_TENT = 1 << 5,1935 TP_ACPI_MULTI_MODE_STAND_TENT = 1 << 6,1936};1937 1938enum {1939 /* The following modes are considered tablet mode for the purpose of1940 * reporting the status to userspace. i.e. in all these modes it makes1941 * sense to disable the laptop input devices such as touchpad and1942 * keyboard.1943 */1944 TP_ACPI_MULTI_MODE_TABLET_LIKE = TP_ACPI_MULTI_MODE_TABLET |1945 TP_ACPI_MULTI_MODE_STAND |1946 TP_ACPI_MULTI_MODE_TENT |1947 TP_ACPI_MULTI_MODE_STAND_TENT,1948};1949 1950static int hotkey_get_wlsw(void)1951{1952 int status;1953 1954 if (!tp_features.hotkey_wlsw)1955 return -ENODEV;1956 1957#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES1958 if (dbg_wlswemul)1959 return (tpacpi_wlsw_emulstate) ?1960 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;1961#endif1962 1963 if (!acpi_evalf(hkey_handle, &status, "WLSW", "d"))1964 return -EIO;1965 1966 return (status) ? TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;1967}1968 1969static int hotkey_gmms_get_tablet_mode(int s, int *has_tablet_mode)1970{1971 int type = (s >> 16) & 0xffff;1972 int value = s & 0xffff;1973 int mode = TP_ACPI_MULTI_MODE_INVALID;1974 int valid_modes = 0;1975 1976 if (has_tablet_mode)1977 *has_tablet_mode = 0;1978 1979 switch (type) {1980 case 1:1981 valid_modes = TP_ACPI_MULTI_MODE_LAPTOP |1982 TP_ACPI_MULTI_MODE_TABLET |1983 TP_ACPI_MULTI_MODE_STAND_TENT;1984 break;1985 case 2:1986 valid_modes = TP_ACPI_MULTI_MODE_LAPTOP |1987 TP_ACPI_MULTI_MODE_FLAT |1988 TP_ACPI_MULTI_MODE_TABLET |1989 TP_ACPI_MULTI_MODE_STAND |1990 TP_ACPI_MULTI_MODE_TENT;1991 break;1992 case 3:1993 valid_modes = TP_ACPI_MULTI_MODE_LAPTOP |1994 TP_ACPI_MULTI_MODE_FLAT;1995 break;1996 case 4:1997 case 5:1998 /* In mode 4, FLAT is not specified as a valid mode. However,1999 * it can be seen at least on the X1 Yoga 2nd Generation.2000 */2001 valid_modes = TP_ACPI_MULTI_MODE_LAPTOP |2002 TP_ACPI_MULTI_MODE_FLAT |2003 TP_ACPI_MULTI_MODE_TABLET |2004 TP_ACPI_MULTI_MODE_STAND |2005 TP_ACPI_MULTI_MODE_TENT;2006 break;2007 default:2008 pr_err("Unknown multi mode status type %d with value 0x%04X, please report this to %s\n",2009 type, value, TPACPI_MAIL);2010 return 0;2011 }2012 2013 if (has_tablet_mode && (valid_modes & TP_ACPI_MULTI_MODE_TABLET_LIKE))2014 *has_tablet_mode = 1;2015 2016 switch (value) {2017 case 1:2018 mode = TP_ACPI_MULTI_MODE_LAPTOP;2019 break;2020 case 2:2021 mode = TP_ACPI_MULTI_MODE_FLAT;2022 break;2023 case 3:2024 mode = TP_ACPI_MULTI_MODE_TABLET;2025 break;2026 case 4:2027 if (type == 1)2028 mode = TP_ACPI_MULTI_MODE_STAND_TENT;2029 else2030 mode = TP_ACPI_MULTI_MODE_STAND;2031 break;2032 case 5:2033 mode = TP_ACPI_MULTI_MODE_TENT;2034 break;2035 default:2036 if (type == 5 && value == 0xffff) {2037 pr_warn("Multi mode status is undetected, assuming laptop\n");2038 return 0;2039 }2040 }2041 2042 if (!(mode & valid_modes)) {2043 pr_err("Unknown/reserved multi mode value 0x%04X for type %d, please report this to %s\n",2044 value, type, TPACPI_MAIL);2045 return 0;2046 }2047 2048 return !!(mode & TP_ACPI_MULTI_MODE_TABLET_LIKE);2049}2050 2051static int hotkey_get_tablet_mode(int *status)2052{2053 int s;2054 2055 switch (tp_features.hotkey_tablet) {2056 case TP_HOTKEY_TABLET_USES_MHKG:2057 if (!acpi_evalf(hkey_handle, &s, "MHKG", "d"))2058 return -EIO;2059 2060 *status = ((s & TP_HOTKEY_TABLET_MASK) != 0);2061 break;2062 case TP_HOTKEY_TABLET_USES_GMMS:2063 if (!acpi_evalf(hkey_handle, &s, "GMMS", "dd", 0))2064 return -EIO;2065 2066 *status = hotkey_gmms_get_tablet_mode(s, NULL);2067 break;2068 default:2069 break;2070 }2071 2072 return 0;2073}2074 2075/*2076 * Reads current event mask from firmware, and updates2077 * hotkey_acpi_mask accordingly. Also resets any bits2078 * from hotkey_user_mask that are unavailable to be2079 * delivered (shadow requirement of the userspace ABI).2080 */2081static int hotkey_mask_get(void)2082{2083 lockdep_assert_held(&hotkey_mutex);2084 2085 if (tp_features.hotkey_mask) {2086 u32 m = 0;2087 2088 if (!acpi_evalf(hkey_handle, &m, "DHKN", "d"))2089 return -EIO;2090 2091 hotkey_acpi_mask = m;2092 } else {2093 /* no mask support doesn't mean no event support... */2094 hotkey_acpi_mask = hotkey_all_mask;2095 }2096 2097 /* sync userspace-visible mask */2098 hotkey_user_mask &= (hotkey_acpi_mask | hotkey_source_mask);2099 2100 return 0;2101}2102 2103static void hotkey_mask_warn_incomplete_mask(void)2104{2105 /* log only what the user can fix... */2106 const u32 wantedmask = hotkey_driver_mask &2107 ~(hotkey_acpi_mask | hotkey_source_mask) &2108 (hotkey_all_mask | TPACPI_HKEY_NVRAM_KNOWN_MASK);2109 2110 if (wantedmask)2111 pr_notice("required events 0x%08x not enabled!\n", wantedmask);2112}2113 2114/*2115 * Set the firmware mask when supported2116 *2117 * Also calls hotkey_mask_get to update hotkey_acpi_mask.2118 *2119 * NOTE: does not set bits in hotkey_user_mask, but may reset them.2120 */2121static int hotkey_mask_set(u32 mask)2122{2123 int i;2124 int rc = 0;2125 2126 const u32 fwmask = mask & ~hotkey_source_mask;2127 2128 lockdep_assert_held(&hotkey_mutex);2129 2130 if (tp_features.hotkey_mask) {2131 for (i = 0; i < 32; i++) {2132 if (!acpi_evalf(hkey_handle,2133 NULL, "MHKM", "vdd", i + 1,2134 !!(mask & (1 << i)))) {2135 rc = -EIO;2136 break;2137 }2138 }2139 }2140 2141 /*2142 * We *must* make an inconditional call to hotkey_mask_get to2143 * refresh hotkey_acpi_mask and update hotkey_user_mask2144 *2145 * Take the opportunity to also log when we cannot _enable_2146 * a given event.2147 */2148 if (!hotkey_mask_get() && !rc && (fwmask & ~hotkey_acpi_mask)) {2149 pr_notice("asked for hotkey mask 0x%08x, but firmware forced it to 0x%08x\n",2150 fwmask, hotkey_acpi_mask);2151 }2152 2153 if (tpacpi_lifecycle != TPACPI_LIFE_EXITING)2154 hotkey_mask_warn_incomplete_mask();2155 2156 return rc;2157}2158 2159/*2160 * Sets hotkey_user_mask and tries to set the firmware mask2161 */2162static int hotkey_user_mask_set(const u32 mask)2163{2164 int rc;2165 2166 lockdep_assert_held(&hotkey_mutex);2167 2168 /* Give people a chance to notice they are doing something that2169 * is bound to go boom on their users sooner or later */2170 if (!tp_warned.hotkey_mask_ff &&2171 (mask == 0xffff || mask == 0xffffff ||2172 mask == 0xffffffff)) {2173 tp_warned.hotkey_mask_ff = 1;2174 pr_notice("setting the hotkey mask to 0x%08x is likely not the best way to go about it\n",2175 mask);2176 pr_notice("please consider using the driver defaults, and refer to up-to-date thinkpad-acpi documentation\n");2177 }2178 2179 /* Try to enable what the user asked for, plus whatever we need.2180 * this syncs everything but won't enable bits in hotkey_user_mask */2181 rc = hotkey_mask_set((mask | hotkey_driver_mask) & ~hotkey_source_mask);2182 2183 /* Enable the available bits in hotkey_user_mask */2184 hotkey_user_mask = mask & (hotkey_acpi_mask | hotkey_source_mask);2185 2186 return rc;2187}2188 2189/*2190 * Sets the driver hotkey mask.2191 *2192 * Can be called even if the hotkey subdriver is inactive2193 */2194static int tpacpi_hotkey_driver_mask_set(const u32 mask)2195{2196 int rc;2197 2198 /* Do the right thing if hotkey_init has not been called yet */2199 if (!tp_features.hotkey) {2200 hotkey_driver_mask = mask;2201 return 0;2202 }2203 2204 mutex_lock(&hotkey_mutex);2205 2206 HOTKEY_CONFIG_CRITICAL_START2207 hotkey_driver_mask = mask;2208#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL2209 hotkey_source_mask |= (mask & ~hotkey_all_mask);2210#endif2211 HOTKEY_CONFIG_CRITICAL_END2212 2213 rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) &2214 ~hotkey_source_mask);2215 hotkey_poll_setup(true);2216 2217 mutex_unlock(&hotkey_mutex);2218 2219 return rc;2220}2221 2222static int hotkey_status_get(int *status)2223{2224 if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))2225 return -EIO;2226 2227 return 0;2228}2229 2230static int hotkey_status_set(bool enable)2231{2232 if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", enable ? 1 : 0))2233 return -EIO;2234 2235 return 0;2236}2237 2238static void tpacpi_input_send_tabletsw(void)2239{2240 int state;2241 2242 if (tp_features.hotkey_tablet &&2243 !hotkey_get_tablet_mode(&state)) {2244 mutex_lock(&tpacpi_inputdev_send_mutex);2245 2246 input_report_switch(tpacpi_inputdev,2247 SW_TABLET_MODE, !!state);2248 input_sync(tpacpi_inputdev);2249 2250 mutex_unlock(&tpacpi_inputdev_send_mutex);2251 }2252}2253 2254static bool tpacpi_input_send_key(const u32 hkey, bool *send_acpi_ev)2255{2256 bool known_ev;2257 u32 scancode;2258 2259 if (tpacpi_driver_event(hkey))2260 return true;2261 2262 /*2263 * Before the conversion to using the sparse-keymap helpers the driver used to2264 * map the hkey event codes to 0x00 - 0x4d scancodes so that a straight scancode2265 * indexed array could be used to map scancodes to keycodes:2266 *2267 * 0x1001 - 0x1020 -> 0x00 - 0x1f (Original ThinkPad events)2268 * 0x1103 - 0x1116 -> 0x20 - 0x33 (Adaptive keyboard, 2014 X1 Carbon)2269 * 0x1300 - 0x1319 -> 0x34 - 0x4d (Additional keys send in 2017+ models)2270 *2271 * The sparse-keymap tables still use these scancodes for these ranges to2272 * preserve userspace API compatibility (e.g. hwdb keymappings).2273 */2274 if (hkey >= TP_HKEY_EV_ORIG_KEY_START &&2275 hkey <= TP_HKEY_EV_ORIG_KEY_END) {2276 scancode = hkey - TP_HKEY_EV_ORIG_KEY_START;2277 if (!(hotkey_user_mask & (1 << scancode)))2278 return true; /* Not reported but still a known code */2279 } else if (hkey >= TP_HKEY_EV_ADAPTIVE_KEY_START &&2280 hkey <= TP_HKEY_EV_ADAPTIVE_KEY_END) {2281 scancode = hkey - TP_HKEY_EV_ADAPTIVE_KEY_START +2282 TP_ACPI_HOTKEYSCAN_ADAPTIVE_START;2283 } else if (hkey >= TP_HKEY_EV_EXTENDED_KEY_START &&2284 hkey <= TP_HKEY_EV_EXTENDED_KEY_END) {2285 scancode = hkey - TP_HKEY_EV_EXTENDED_KEY_START +2286 TP_ACPI_HOTKEYSCAN_EXTENDED_START;2287 } else {2288 /*2289 * Do not send ACPI netlink events for unknown hotkeys, to2290 * avoid userspace starting to rely on them. Instead these2291 * should be added to the keymap to send evdev events.2292 */2293 if (send_acpi_ev)2294 *send_acpi_ev = false;2295 2296 scancode = hkey;2297 }2298 2299 mutex_lock(&tpacpi_inputdev_send_mutex);2300 known_ev = sparse_keymap_report_event(tpacpi_inputdev, scancode, 1, true);2301 mutex_unlock(&tpacpi_inputdev_send_mutex);2302 2303 return known_ev;2304}2305 2306#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL2307static struct tp_acpi_drv_struct ibm_hotkey_acpidriver;2308 2309/* Do NOT call without validating scancode first */2310static void tpacpi_hotkey_send_key(unsigned int scancode)2311{2312 tpacpi_input_send_key(TP_HKEY_EV_ORIG_KEY_START + scancode, NULL);2313}2314 2315static void hotkey_read_nvram(struct tp_nvram_state *n, const u32 m)2316{2317 u8 d;2318 2319 if (m & TP_NVRAM_HKEY_GROUP_HK2) {2320 d = nvram_read_byte(TP_NVRAM_ADDR_HK2);2321 n->thinkpad_toggle = !!(d & TP_NVRAM_MASK_HKT_THINKPAD);2322 n->zoom_toggle = !!(d & TP_NVRAM_MASK_HKT_ZOOM);2323 n->display_toggle = !!(d & TP_NVRAM_MASK_HKT_DISPLAY);2324 n->hibernate_toggle = !!(d & TP_NVRAM_MASK_HKT_HIBERNATE);2325 }2326 if (m & TP_ACPI_HKEY_KBD_LIGHT_MASK) {2327 d = nvram_read_byte(TP_NVRAM_ADDR_THINKLIGHT);2328 n->thinklight_toggle = !!(d & TP_NVRAM_MASK_THINKLIGHT);2329 }2330 if (m & TP_ACPI_HKEY_DISPXPAND_MASK) {2331 d = nvram_read_byte(TP_NVRAM_ADDR_VIDEO);2332 n->displayexp_toggle =2333 !!(d & TP_NVRAM_MASK_HKT_DISPEXPND);2334 }2335 if (m & TP_NVRAM_HKEY_GROUP_BRIGHTNESS) {2336 d = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);2337 n->brightness_level = (d & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)2338 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;2339 n->brightness_toggle =2340 !!(d & TP_NVRAM_MASK_HKT_BRIGHTNESS);2341 }2342 if (m & TP_NVRAM_HKEY_GROUP_VOLUME) {2343 d = nvram_read_byte(TP_NVRAM_ADDR_MIXER);2344 n->volume_level = (d & TP_NVRAM_MASK_LEVEL_VOLUME)2345 >> TP_NVRAM_POS_LEVEL_VOLUME;2346 n->mute = !!(d & TP_NVRAM_MASK_MUTE);2347 n->volume_toggle = !!(d & TP_NVRAM_MASK_HKT_VOLUME);2348 }2349}2350 2351#define TPACPI_COMPARE_KEY(__scancode, __member) \2352do { \2353 if ((event_mask & (1 << __scancode)) && \2354 oldn->__member != newn->__member) \2355 tpacpi_hotkey_send_key(__scancode); \2356} while (0)2357 2358#define TPACPI_MAY_SEND_KEY(__scancode) \2359do { \2360 if (event_mask & (1 << __scancode)) \2361 tpacpi_hotkey_send_key(__scancode); \2362} while (0)2363 2364static void issue_volchange(const unsigned int oldvol,2365 const unsigned int newvol,2366 const u32 event_mask)2367{2368 unsigned int i = oldvol;2369 2370 while (i > newvol) {2371 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN);2372 i--;2373 }2374 while (i < newvol) {2375 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);2376 i++;2377 }2378}2379 2380static void issue_brightnesschange(const unsigned int oldbrt,2381 const unsigned int newbrt,2382 const u32 event_mask)2383{2384 unsigned int i = oldbrt;2385 2386 while (i > newbrt) {2387 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND);2388 i--;2389 }2390 while (i < newbrt) {2391 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME);2392 i++;2393 }2394}2395 2396static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,2397 struct tp_nvram_state *newn,2398 const u32 event_mask)2399{2400 2401 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle);2402 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle);2403 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle);2404 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF12, hibernate_toggle);2405 2406 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNPAGEUP, thinklight_toggle);2407 2408 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF8, displayexp_toggle);2409 2410 /*2411 * Handle volume2412 *2413 * This code is supposed to duplicate the IBM firmware behaviour:2414 * - Pressing MUTE issues mute hotkey message, even when already mute2415 * - Pressing Volume up/down issues volume up/down hotkey messages,2416 * even when already at maximum or minimum volume2417 * - The act of unmuting issues volume up/down notification,2418 * depending which key was used to unmute2419 *2420 * We are constrained to what the NVRAM can tell us, which is not much2421 * and certainly not enough if more than one volume hotkey was pressed2422 * since the last poll cycle.2423 *2424 * Just to make our life interesting, some newer Lenovo ThinkPads have2425 * bugs in the BIOS and may fail to update volume_toggle properly.2426 */2427 if (newn->mute) {2428 /* muted */2429 if (!oldn->mute ||2430 oldn->volume_toggle != newn->volume_toggle ||2431 oldn->volume_level != newn->volume_level) {2432 /* recently muted, or repeated mute keypress, or2433 * multiple presses ending in mute */2434 issue_volchange(oldn->volume_level, newn->volume_level,2435 event_mask);2436 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE);2437 }2438 } else {2439 /* unmute */2440 if (oldn->mute) {2441 /* recently unmuted, issue 'unmute' keypress */2442 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);2443 }2444 if (oldn->volume_level != newn->volume_level) {2445 issue_volchange(oldn->volume_level, newn->volume_level,2446 event_mask);2447 } else if (oldn->volume_toggle != newn->volume_toggle) {2448 /* repeated vol up/down keypress at end of scale ? */2449 if (newn->volume_level == 0)2450 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN);2451 else if (newn->volume_level >= TP_NVRAM_LEVEL_VOLUME_MAX)2452 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);2453 }2454 }2455 2456 /* handle brightness */2457 if (oldn->brightness_level != newn->brightness_level) {2458 issue_brightnesschange(oldn->brightness_level,2459 newn->brightness_level, event_mask);2460 } else if (oldn->brightness_toggle != newn->brightness_toggle) {2461 /* repeated key presses that didn't change state */2462 if (newn->brightness_level == 0)2463 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND);2464 else if (newn->brightness_level >= bright_maxlvl2465 && !tp_features.bright_unkfw)2466 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME);2467 }2468 2469#undef TPACPI_COMPARE_KEY2470#undef TPACPI_MAY_SEND_KEY2471}2472 2473/*2474 * Polling driver2475 *2476 * We track all events in hotkey_source_mask all the time, since2477 * most of them are edge-based. We only issue those requested by2478 * hotkey_user_mask or hotkey_driver_mask, though.2479 */2480static int hotkey_kthread(void *data)2481{2482 struct tp_nvram_state s[2] = { 0 };2483 u32 poll_mask, event_mask;2484 unsigned int si, so;2485 unsigned long t;2486 unsigned int change_detector;2487 unsigned int poll_freq;2488 bool was_frozen;2489 2490 if (tpacpi_lifecycle == TPACPI_LIFE_EXITING)2491 goto exit;2492 2493 set_freezable();2494 2495 so = 0;2496 si = 1;2497 t = 0;2498 2499 /* Initial state for compares */2500 mutex_lock(&hotkey_thread_data_mutex);2501 change_detector = hotkey_config_change;2502 poll_mask = hotkey_source_mask;2503 event_mask = hotkey_source_mask &2504 (hotkey_driver_mask | hotkey_user_mask);2505 poll_freq = hotkey_poll_freq;2506 mutex_unlock(&hotkey_thread_data_mutex);2507 hotkey_read_nvram(&s[so], poll_mask);2508 2509 while (!kthread_should_stop()) {2510 if (t == 0) {2511 if (likely(poll_freq))2512 t = 1000/poll_freq;2513 else2514 t = 100; /* should never happen... */2515 }2516 t = msleep_interruptible(t);2517 if (unlikely(kthread_freezable_should_stop(&was_frozen)))2518 break;2519 2520 if (t > 0 && !was_frozen)2521 continue;2522 2523 mutex_lock(&hotkey_thread_data_mutex);2524 if (was_frozen || hotkey_config_change != change_detector) {2525 /* forget old state on thaw or config change */2526 si = so;2527 t = 0;2528 change_detector = hotkey_config_change;2529 }2530 poll_mask = hotkey_source_mask;2531 event_mask = hotkey_source_mask &2532 (hotkey_driver_mask | hotkey_user_mask);2533 poll_freq = hotkey_poll_freq;2534 mutex_unlock(&hotkey_thread_data_mutex);2535 2536 if (likely(poll_mask)) {2537 hotkey_read_nvram(&s[si], poll_mask);2538 if (likely(si != so)) {2539 hotkey_compare_and_issue_event(&s[so], &s[si],2540 event_mask);2541 }2542 }2543 2544 so = si;2545 si ^= 1;2546 }2547 2548exit:2549 return 0;2550}2551 2552static void hotkey_poll_stop_sync(void)2553{2554 lockdep_assert_held(&hotkey_mutex);2555 2556 if (tpacpi_hotkey_task) {2557 kthread_stop(tpacpi_hotkey_task);2558 tpacpi_hotkey_task = NULL;2559 }2560}2561 2562static void hotkey_poll_setup(const bool may_warn)2563{2564 const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask;2565 const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask;2566 2567 lockdep_assert_held(&hotkey_mutex);2568 2569 if (hotkey_poll_freq > 0 &&2570 (poll_driver_mask ||2571 (poll_user_mask && tpacpi_inputdev->users > 0))) {2572 if (!tpacpi_hotkey_task) {2573 tpacpi_hotkey_task = kthread_run(hotkey_kthread,2574 NULL, TPACPI_NVRAM_KTHREAD_NAME);2575 if (IS_ERR(tpacpi_hotkey_task)) {2576 tpacpi_hotkey_task = NULL;2577 pr_err("could not create kernel thread for hotkey polling\n");2578 }2579 }2580 } else {2581 hotkey_poll_stop_sync();2582 if (may_warn && (poll_driver_mask || poll_user_mask) &&2583 hotkey_poll_freq == 0) {2584 pr_notice("hot keys 0x%08x and/or events 0x%08x require polling, which is currently disabled\n",2585 poll_user_mask, poll_driver_mask);2586 }2587 }2588}2589 2590static void hotkey_poll_setup_safe(const bool may_warn)2591{2592 mutex_lock(&hotkey_mutex);2593 hotkey_poll_setup(may_warn);2594 mutex_unlock(&hotkey_mutex);2595}2596 2597static void hotkey_poll_set_freq(unsigned int freq)2598{2599 lockdep_assert_held(&hotkey_mutex);2600 2601 if (!freq)2602 hotkey_poll_stop_sync();2603 2604 hotkey_poll_freq = freq;2605}2606 2607#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */2608 2609static void hotkey_poll_setup(const bool __unused)2610{2611}2612 2613static void hotkey_poll_setup_safe(const bool __unused)2614{2615}2616 2617static void hotkey_poll_stop_sync(void)2618{2619}2620#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */2621 2622static int hotkey_inputdev_open(struct input_dev *dev)2623{2624 switch (tpacpi_lifecycle) {2625 case TPACPI_LIFE_INIT:2626 case TPACPI_LIFE_RUNNING:2627 hotkey_poll_setup_safe(false);2628 return 0;2629 case TPACPI_LIFE_EXITING:2630 return -EBUSY;2631 }2632 2633 /* Should only happen if tpacpi_lifecycle is corrupt */2634 BUG();2635 return -EBUSY;2636}2637 2638static void hotkey_inputdev_close(struct input_dev *dev)2639{2640 /* disable hotkey polling when possible */2641 if (tpacpi_lifecycle != TPACPI_LIFE_EXITING &&2642 !(hotkey_source_mask & hotkey_driver_mask))2643 hotkey_poll_setup_safe(false);2644}2645 2646/* sysfs hotkey enable ------------------------------------------------- */2647static ssize_t hotkey_enable_show(struct device *dev,2648 struct device_attribute *attr,2649 char *buf)2650{2651 int res, status;2652 2653 printk_deprecated_attribute("hotkey_enable",2654 "Hotkey reporting is always enabled");2655 2656 res = hotkey_status_get(&status);2657 if (res)2658 return res;2659 2660 return sysfs_emit(buf, "%d\n", status);2661}2662 2663static ssize_t hotkey_enable_store(struct device *dev,2664 struct device_attribute *attr,2665 const char *buf, size_t count)2666{2667 unsigned long t;2668 2669 printk_deprecated_attribute("hotkey_enable",2670 "Hotkeys can be disabled through hotkey_mask");2671 2672 if (parse_strtoul(buf, 1, &t))2673 return -EINVAL;2674 2675 if (t == 0)2676 return -EPERM;2677 2678 return count;2679}2680 2681static DEVICE_ATTR_RW(hotkey_enable);2682 2683/* sysfs hotkey mask --------------------------------------------------- */2684static ssize_t hotkey_mask_show(struct device *dev,2685 struct device_attribute *attr,2686 char *buf)2687{2688 return sysfs_emit(buf, "0x%08x\n", hotkey_user_mask);2689}2690 2691static ssize_t hotkey_mask_store(struct device *dev,2692 struct device_attribute *attr,2693 const char *buf, size_t count)2694{2695 unsigned long t;2696 int res;2697 2698 if (parse_strtoul(buf, 0xffffffffUL, &t))2699 return -EINVAL;2700 2701 if (mutex_lock_killable(&hotkey_mutex))2702 return -ERESTARTSYS;2703 2704 res = hotkey_user_mask_set(t);2705 2706#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL2707 hotkey_poll_setup(true);2708#endif2709 2710 mutex_unlock(&hotkey_mutex);2711 2712 tpacpi_disclose_usertask("hotkey_mask", "set to 0x%08lx\n", t);2713 2714 return (res) ? res : count;2715}2716 2717static DEVICE_ATTR_RW(hotkey_mask);2718 2719/* sysfs hotkey bios_enabled ------------------------------------------- */2720static ssize_t hotkey_bios_enabled_show(struct device *dev,2721 struct device_attribute *attr,2722 char *buf)2723{2724 return sysfs_emit(buf, "0\n");2725}2726 2727static DEVICE_ATTR_RO(hotkey_bios_enabled);2728 2729/* sysfs hotkey bios_mask ---------------------------------------------- */2730static ssize_t hotkey_bios_mask_show(struct device *dev,2731 struct device_attribute *attr,2732 char *buf)2733{2734 printk_deprecated_attribute("hotkey_bios_mask",2735 "This attribute is useless.");2736 return sysfs_emit(buf, "0x%08x\n", hotkey_orig_mask);2737}2738 2739static DEVICE_ATTR_RO(hotkey_bios_mask);2740 2741/* sysfs hotkey all_mask ----------------------------------------------- */2742static ssize_t hotkey_all_mask_show(struct device *dev,2743 struct device_attribute *attr,2744 char *buf)2745{2746 return sysfs_emit(buf, "0x%08x\n",2747 hotkey_all_mask | hotkey_source_mask);2748}2749 2750static DEVICE_ATTR_RO(hotkey_all_mask);2751 2752/* sysfs hotkey all_mask ----------------------------------------------- */2753static ssize_t hotkey_adaptive_all_mask_show(struct device *dev,2754 struct device_attribute *attr,2755 char *buf)2756{2757 return sysfs_emit(buf, "0x%08x\n",2758 hotkey_adaptive_all_mask | hotkey_source_mask);2759}2760 2761static DEVICE_ATTR_RO(hotkey_adaptive_all_mask);2762 2763/* sysfs hotkey recommended_mask --------------------------------------- */2764static ssize_t hotkey_recommended_mask_show(struct device *dev,2765 struct device_attribute *attr,2766 char *buf)2767{2768 return sysfs_emit(buf, "0x%08x\n",2769 (hotkey_all_mask | hotkey_source_mask)2770 & ~hotkey_reserved_mask);2771}2772 2773static DEVICE_ATTR_RO(hotkey_recommended_mask);2774 2775#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL2776 2777/* sysfs hotkey hotkey_source_mask ------------------------------------- */2778static ssize_t hotkey_source_mask_show(struct device *dev,2779 struct device_attribute *attr,2780 char *buf)2781{2782 return sysfs_emit(buf, "0x%08x\n", hotkey_source_mask);2783}2784 2785static ssize_t hotkey_source_mask_store(struct device *dev,2786 struct device_attribute *attr,2787 const char *buf, size_t count)2788{2789 unsigned long t;2790 u32 r_ev;2791 int rc;2792 2793 if (parse_strtoul(buf, 0xffffffffUL, &t) ||2794 ((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0))2795 return -EINVAL;2796 2797 if (mutex_lock_killable(&hotkey_mutex))2798 return -ERESTARTSYS;2799 2800 HOTKEY_CONFIG_CRITICAL_START2801 hotkey_source_mask = t;2802 HOTKEY_CONFIG_CRITICAL_END2803 2804 rc = hotkey_mask_set((hotkey_user_mask | hotkey_driver_mask) &2805 ~hotkey_source_mask);2806 hotkey_poll_setup(true);2807 2808 /* check if events needed by the driver got disabled */2809 r_ev = hotkey_driver_mask & ~(hotkey_acpi_mask & hotkey_all_mask)2810 & ~hotkey_source_mask & TPACPI_HKEY_NVRAM_KNOWN_MASK;2811 2812 mutex_unlock(&hotkey_mutex);2813 2814 if (rc < 0)2815 pr_err("hotkey_source_mask: failed to update the firmware event mask!\n");2816 2817 if (r_ev)2818 pr_notice("hotkey_source_mask: some important events were disabled: 0x%04x\n",2819 r_ev);2820 2821 tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t);2822 2823 return (rc < 0) ? rc : count;2824}2825 2826static DEVICE_ATTR_RW(hotkey_source_mask);2827 2828/* sysfs hotkey hotkey_poll_freq --------------------------------------- */2829static ssize_t hotkey_poll_freq_show(struct device *dev,2830 struct device_attribute *attr,2831 char *buf)2832{2833 return sysfs_emit(buf, "%d\n", hotkey_poll_freq);2834}2835 2836static ssize_t hotkey_poll_freq_store(struct device *dev,2837 struct device_attribute *attr,2838 const char *buf, size_t count)2839{2840 unsigned long t;2841 2842 if (parse_strtoul(buf, 25, &t))2843 return -EINVAL;2844 2845 if (mutex_lock_killable(&hotkey_mutex))2846 return -ERESTARTSYS;2847 2848 hotkey_poll_set_freq(t);2849 hotkey_poll_setup(true);2850 2851 mutex_unlock(&hotkey_mutex);2852 2853 tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t);2854 2855 return count;2856}2857 2858static DEVICE_ATTR_RW(hotkey_poll_freq);2859 2860#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */2861 2862/* sysfs hotkey radio_sw (pollable) ------------------------------------ */2863static ssize_t hotkey_radio_sw_show(struct device *dev,2864 struct device_attribute *attr,2865 char *buf)2866{2867 int res;2868 res = hotkey_get_wlsw();2869 if (res < 0)2870 return res;2871 2872 /* Opportunistic update */2873 tpacpi_rfk_update_hwblock_state((res == TPACPI_RFK_RADIO_OFF));2874 2875 return sysfs_emit(buf, "%d\n",2876 (res == TPACPI_RFK_RADIO_OFF) ? 0 : 1);2877}2878 2879static DEVICE_ATTR_RO(hotkey_radio_sw);2880 2881static void hotkey_radio_sw_notify_change(void)2882{2883 if (tp_features.hotkey_wlsw)2884 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,2885 "hotkey_radio_sw");2886}2887 2888/* sysfs hotkey tablet mode (pollable) --------------------------------- */2889static ssize_t hotkey_tablet_mode_show(struct device *dev,2890 struct device_attribute *attr,2891 char *buf)2892{2893 int res, s;2894 res = hotkey_get_tablet_mode(&s);2895 if (res < 0)2896 return res;2897 2898 return sysfs_emit(buf, "%d\n", !!s);2899}2900 2901static DEVICE_ATTR_RO(hotkey_tablet_mode);2902 2903static void hotkey_tablet_mode_notify_change(void)2904{2905 if (tp_features.hotkey_tablet)2906 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,2907 "hotkey_tablet_mode");2908}2909 2910/* sysfs wakeup reason (pollable) -------------------------------------- */2911static ssize_t hotkey_wakeup_reason_show(struct device *dev,2912 struct device_attribute *attr,2913 char *buf)2914{2915 return sysfs_emit(buf, "%d\n", hotkey_wakeup_reason);2916}2917 2918static DEVICE_ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL);2919 2920static void hotkey_wakeup_reason_notify_change(void)2921{2922 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,2923 "wakeup_reason");2924}2925 2926/* sysfs wakeup hotunplug_complete (pollable) -------------------------- */2927static ssize_t hotkey_wakeup_hotunplug_complete_show(struct device *dev,2928 struct device_attribute *attr,2929 char *buf)2930{2931 return sysfs_emit(buf, "%d\n", hotkey_autosleep_ack);2932}2933 2934static DEVICE_ATTR(wakeup_hotunplug_complete, S_IRUGO,2935 hotkey_wakeup_hotunplug_complete_show, NULL);2936 2937static void hotkey_wakeup_hotunplug_complete_notify_change(void)2938{2939 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,2940 "wakeup_hotunplug_complete");2941}2942 2943/* sysfs adaptive kbd mode --------------------------------------------- */2944 2945static int adaptive_keyboard_get_mode(void);2946static int adaptive_keyboard_set_mode(int new_mode);2947 2948enum ADAPTIVE_KEY_MODE {2949 HOME_MODE,2950 WEB_BROWSER_MODE,2951 WEB_CONFERENCE_MODE,2952 FUNCTION_MODE,2953 LAYFLAT_MODE2954};2955 2956static ssize_t adaptive_kbd_mode_show(struct device *dev,2957 struct device_attribute *attr,2958 char *buf)2959{2960 int current_mode;2961 2962 current_mode = adaptive_keyboard_get_mode();2963 if (current_mode < 0)2964 return current_mode;2965 2966 return sysfs_emit(buf, "%d\n", current_mode);2967}2968 2969static ssize_t adaptive_kbd_mode_store(struct device *dev,2970 struct device_attribute *attr,2971 const char *buf, size_t count)2972{2973 unsigned long t;2974 int res;2975 2976 if (parse_strtoul(buf, LAYFLAT_MODE, &t))2977 return -EINVAL;2978 2979 res = adaptive_keyboard_set_mode(t);2980 return (res < 0) ? res : count;2981}2982 2983static DEVICE_ATTR_RW(adaptive_kbd_mode);2984 2985static struct attribute *adaptive_kbd_attributes[] = {2986 &dev_attr_adaptive_kbd_mode.attr,2987 NULL2988};2989 2990static umode_t hadaptive_kbd_attr_is_visible(struct kobject *kobj,2991 struct attribute *attr, int n)2992{2993 return tp_features.has_adaptive_kbd ? attr->mode : 0;2994}2995 2996static const struct attribute_group adaptive_kbd_attr_group = {2997 .is_visible = hadaptive_kbd_attr_is_visible,2998 .attrs = adaptive_kbd_attributes,2999};3000 3001/* --------------------------------------------------------------------- */3002 3003static struct attribute *hotkey_attributes[] = {3004 &dev_attr_hotkey_enable.attr,3005 &dev_attr_hotkey_bios_enabled.attr,3006 &dev_attr_hotkey_bios_mask.attr,3007 &dev_attr_wakeup_reason.attr,3008 &dev_attr_wakeup_hotunplug_complete.attr,3009 &dev_attr_hotkey_mask.attr,3010 &dev_attr_hotkey_all_mask.attr,3011 &dev_attr_hotkey_adaptive_all_mask.attr,3012 &dev_attr_hotkey_recommended_mask.attr,3013 &dev_attr_hotkey_tablet_mode.attr,3014 &dev_attr_hotkey_radio_sw.attr,3015#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL3016 &dev_attr_hotkey_source_mask.attr,3017 &dev_attr_hotkey_poll_freq.attr,3018#endif3019 NULL3020};3021 3022static umode_t hotkey_attr_is_visible(struct kobject *kobj,3023 struct attribute *attr, int n)3024{3025 if (attr == &dev_attr_hotkey_tablet_mode.attr) {3026 if (!tp_features.hotkey_tablet)3027 return 0;3028 } else if (attr == &dev_attr_hotkey_radio_sw.attr) {3029 if (!tp_features.hotkey_wlsw)3030 return 0;3031 }3032 3033 return attr->mode;3034}3035 3036static const struct attribute_group hotkey_attr_group = {3037 .is_visible = hotkey_attr_is_visible,3038 .attrs = hotkey_attributes,3039};3040 3041/*3042 * Sync both the hw and sw blocking state of all switches3043 */3044static void tpacpi_send_radiosw_update(void)3045{3046 int wlsw;3047 3048 /*3049 * We must sync all rfkill controllers *before* issuing any3050 * rfkill input events, or we will race the rfkill core input3051 * handler.3052 *3053 * tpacpi_inputdev_send_mutex works as a synchronization point3054 * for the above.3055 *3056 * We optimize to avoid numerous calls to hotkey_get_wlsw.3057 */3058 3059 wlsw = hotkey_get_wlsw();3060 3061 /* Sync hw blocking state first if it is hw-blocked */3062 if (wlsw == TPACPI_RFK_RADIO_OFF)3063 tpacpi_rfk_update_hwblock_state(true);3064 3065 /* Sync hw blocking state last if it is hw-unblocked */3066 if (wlsw == TPACPI_RFK_RADIO_ON)3067 tpacpi_rfk_update_hwblock_state(false);3068 3069 /* Issue rfkill input event for WLSW switch */3070 if (!(wlsw < 0)) {3071 mutex_lock(&tpacpi_inputdev_send_mutex);3072 3073 input_report_switch(tpacpi_inputdev,3074 SW_RFKILL_ALL, (wlsw > 0));3075 input_sync(tpacpi_inputdev);3076 3077 mutex_unlock(&tpacpi_inputdev_send_mutex);3078 }3079 3080 /*3081 * this can be unconditional, as we will poll state again3082 * if userspace uses the notify to read data3083 */3084 hotkey_radio_sw_notify_change();3085}3086 3087static void hotkey_exit(void)3088{3089 mutex_lock(&hotkey_mutex);3090 hotkey_poll_stop_sync();3091 dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,3092 "restoring original HKEY status and mask\n");3093 /* yes, there is a bitwise or below, we want the3094 * functions to be called even if one of them fail */3095 if (((tp_features.hotkey_mask &&3096 hotkey_mask_set(hotkey_orig_mask)) |3097 hotkey_status_set(false)) != 0)3098 pr_err("failed to restore hot key mask to BIOS defaults\n");3099 3100 mutex_unlock(&hotkey_mutex);3101}3102 3103/*3104 * HKEY quirks:3105 * TPACPI_HK_Q_INIMASK: Supports FN+F3,FN+F4,FN+F123106 */3107 3108#define TPACPI_HK_Q_INIMASK 0x00013109 3110static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = {3111 TPACPI_Q_IBM('I', 'H', TPACPI_HK_Q_INIMASK), /* 600E */3112 TPACPI_Q_IBM('I', 'N', TPACPI_HK_Q_INIMASK), /* 600E */3113 TPACPI_Q_IBM('I', 'D', TPACPI_HK_Q_INIMASK), /* 770, 770E, 770ED */3114 TPACPI_Q_IBM('I', 'W', TPACPI_HK_Q_INIMASK), /* A20m */3115 TPACPI_Q_IBM('I', 'V', TPACPI_HK_Q_INIMASK), /* A20p */3116 TPACPI_Q_IBM('1', '0', TPACPI_HK_Q_INIMASK), /* A21e, A22e */3117 TPACPI_Q_IBM('K', 'U', TPACPI_HK_Q_INIMASK), /* A21e */3118 TPACPI_Q_IBM('K', 'X', TPACPI_HK_Q_INIMASK), /* A21m, A22m */3119 TPACPI_Q_IBM('K', 'Y', TPACPI_HK_Q_INIMASK), /* A21p, A22p */3120 TPACPI_Q_IBM('1', 'B', TPACPI_HK_Q_INIMASK), /* A22e */3121 TPACPI_Q_IBM('1', '3', TPACPI_HK_Q_INIMASK), /* A22m */3122 TPACPI_Q_IBM('1', 'E', TPACPI_HK_Q_INIMASK), /* A30/p (0) */3123 TPACPI_Q_IBM('1', 'C', TPACPI_HK_Q_INIMASK), /* R30 */3124 TPACPI_Q_IBM('1', 'F', TPACPI_HK_Q_INIMASK), /* R31 */3125 TPACPI_Q_IBM('I', 'Y', TPACPI_HK_Q_INIMASK), /* T20 */3126 TPACPI_Q_IBM('K', 'Z', TPACPI_HK_Q_INIMASK), /* T21 */3127 TPACPI_Q_IBM('1', '6', TPACPI_HK_Q_INIMASK), /* T22 */3128 TPACPI_Q_IBM('I', 'Z', TPACPI_HK_Q_INIMASK), /* X20, X21 */3129 TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */3130};3131 3132static int hotkey_init_tablet_mode(void)3133{3134 int in_tablet_mode = 0, res;3135 char *type = NULL;3136 3137 if (acpi_evalf(hkey_handle, &res, "GMMS", "qdd", 0)) {3138 int has_tablet_mode;3139 3140 in_tablet_mode = hotkey_gmms_get_tablet_mode(res,3141 &has_tablet_mode);3142 /*3143 * The Yoga 11e series has 2 accelerometers described by a3144 * BOSC0200 ACPI node. This setup relies on a Windows service3145 * which calls special ACPI methods on this node to report3146 * the laptop/tent/tablet mode to the EC. The bmc150 iio driver3147 * does not support this, so skip the hotkey on these models.3148 */3149 if (has_tablet_mode && !dual_accel_detect())3150 tp_features.hotkey_tablet = TP_HOTKEY_TABLET_USES_GMMS;3151 type = "GMMS";3152 } else if (acpi_evalf(hkey_handle, &res, "MHKG", "qd")) {3153 /* For X41t, X60t, X61t Tablets... */3154 tp_features.hotkey_tablet = TP_HOTKEY_TABLET_USES_MHKG;3155 in_tablet_mode = !!(res & TP_HOTKEY_TABLET_MASK);3156 type = "MHKG";3157 }3158 3159 if (!tp_features.hotkey_tablet)3160 return 0;3161 3162 pr_info("Tablet mode switch found (type: %s), currently in %s mode\n",3163 type, in_tablet_mode ? "tablet" : "laptop");3164 3165 return in_tablet_mode;3166}3167 3168static const struct key_entry keymap_ibm[] __initconst = {3169 /* Original hotkey mappings translated scancodes 0x00 - 0x1f */3170 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF1, { KEY_FN_F1 } },3171 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF2, { KEY_BATTERY } },3172 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF3, { KEY_COFFEE } },3173 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF4, { KEY_SLEEP } },3174 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF5, { KEY_WLAN } },3175 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF6, { KEY_FN_F6 } },3176 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF7, { KEY_SWITCHVIDEOMODE } },3177 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF8, { KEY_FN_F8 } },3178 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF9, { KEY_FN_F9 } },3179 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF10, { KEY_FN_F10 } },3180 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF11, { KEY_FN_F11 } },3181 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF12, { KEY_SUSPEND } },3182 /* Brightness: firmware always reacts, suppressed through hotkey_reserved_mask. */3183 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNHOME, { KEY_BRIGHTNESSUP } },3184 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNEND, { KEY_BRIGHTNESSDOWN } },3185 /* Thinklight: firmware always reacts, suppressed through hotkey_reserved_mask. */3186 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNPAGEUP, { KEY_KBDILLUMTOGGLE } },3187 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNSPACE, { KEY_ZOOM } },3188 /*3189 * Volume: firmware always reacts and reprograms the built-in *extra* mixer.3190 * Suppressed by default through hotkey_reserved_mask.3191 */3192 { KE_KEY, TP_ACPI_HOTKEYSCAN_VOLUMEUP, { KEY_VOLUMEUP } },3193 { KE_KEY, TP_ACPI_HOTKEYSCAN_VOLUMEDOWN, { KEY_VOLUMEDOWN } },3194 { KE_KEY, TP_ACPI_HOTKEYSCAN_MUTE, { KEY_MUTE } },3195 { KE_KEY, TP_ACPI_HOTKEYSCAN_THINKPAD, { KEY_VENDOR } },3196 { KE_END }3197};3198 3199static const struct key_entry keymap_lenovo[] __initconst = {3200 /* Original hotkey mappings translated scancodes 0x00 - 0x1f */3201 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF1, { KEY_FN_F1 } },3202 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF2, { KEY_COFFEE } },3203 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF3, { KEY_BATTERY } },3204 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF4, { KEY_SLEEP } },3205 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF5, { KEY_WLAN } },3206 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF6, { KEY_CAMERA, } },3207 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF7, { KEY_SWITCHVIDEOMODE } },3208 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF8, { KEY_FN_F8 } },3209 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF9, { KEY_FN_F9 } },3210 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF10, { KEY_FN_F10 } },3211 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF11, { KEY_FN_F11 } },3212 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF12, { KEY_SUSPEND } },3213 /*3214 * These should be enabled --only-- when ACPI video is disabled and3215 * are handled in a special way by the init code.3216 */3217 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNHOME, { KEY_BRIGHTNESSUP } },3218 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNEND, { KEY_BRIGHTNESSDOWN } },3219 /* Suppressed by default through hotkey_reserved_mask. */3220 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNPAGEUP, { KEY_KBDILLUMTOGGLE } },3221 { KE_KEY, TP_ACPI_HOTKEYSCAN_FNSPACE, { KEY_ZOOM } },3222 /*3223 * Volume: z60/z61, T60 (BIOS version?): firmware always reacts and3224 * reprograms the built-in *extra* mixer.3225 * T60?, T61, R60?, R61: firmware and EC tries to send these over3226 * the regular keyboard (not through tpacpi). There are still weird bugs3227 * re. MUTE. May cause the BIOS to interfere with the HDA mixer.3228 * Suppressed by default through hotkey_reserved_mask.3229 */3230 { KE_KEY, TP_ACPI_HOTKEYSCAN_VOLUMEUP, { KEY_VOLUMEUP } },3231 { KE_KEY, TP_ACPI_HOTKEYSCAN_VOLUMEDOWN, { KEY_VOLUMEDOWN } },3232 { KE_KEY, TP_ACPI_HOTKEYSCAN_MUTE, { KEY_MUTE } },3233 { KE_KEY, TP_ACPI_HOTKEYSCAN_THINKPAD, { KEY_VENDOR } },3234 { KE_KEY, TP_ACPI_HOTKEYSCAN_MICMUTE, { KEY_MICMUTE } },3235 { KE_KEY, TP_ACPI_HOTKEYSCAN_CONFIG, { KEY_CONFIG } },3236 { KE_KEY, TP_ACPI_HOTKEYSCAN_SEARCH, { KEY_SEARCH } },3237 { KE_KEY, TP_ACPI_HOTKEYSCAN_SCALE, { KEY_SCALE } },3238 { KE_KEY, TP_ACPI_HOTKEYSCAN_FILE, { KEY_FILE } },3239 /* Adaptive keyboard mappings for Carbon X1 2014 translated scancodes 0x20 - 0x33 */3240 { KE_KEY, TP_ACPI_HOTKEYSCAN_MUTE2, { KEY_RESERVED } },3241 { KE_KEY, TP_ACPI_HOTKEYSCAN_BRIGHTNESS_ZERO, { KEY_BRIGHTNESS_MIN } },3242 { KE_KEY, TP_ACPI_HOTKEYSCAN_CLIPPING_TOOL, { KEY_SELECTIVE_SCREENSHOT } },3243 { KE_KEY, TP_ACPI_HOTKEYSCAN_CLOUD, { KEY_XFER } },3244 { KE_KEY, TP_ACPI_HOTKEYSCAN_UNK9, { KEY_RESERVED } },3245 { KE_KEY, TP_ACPI_HOTKEYSCAN_VOICE, { KEY_VOICECOMMAND } },3246 { KE_KEY, TP_ACPI_HOTKEYSCAN_UNK10, { KEY_RESERVED } },3247 { KE_KEY, TP_ACPI_HOTKEYSCAN_GESTURES, { KEY_RESERVED } },3248 { KE_KEY, TP_ACPI_HOTKEYSCAN_UNK11, { KEY_RESERVED } },3249 { KE_KEY, TP_ACPI_HOTKEYSCAN_UNK12, { KEY_RESERVED } },3250 { KE_KEY, TP_ACPI_HOTKEYSCAN_UNK13, { KEY_RESERVED } },3251 { KE_KEY, TP_ACPI_HOTKEYSCAN_CONFIG2, { KEY_CONFIG } },3252 { KE_KEY, TP_ACPI_HOTKEYSCAN_NEW_TAB, { KEY_RESERVED } },3253 { KE_KEY, TP_ACPI_HOTKEYSCAN_RELOAD, { KEY_REFRESH } },3254 { KE_KEY, TP_ACPI_HOTKEYSCAN_BACK, { KEY_BACK } },3255 { KE_KEY, TP_ACPI_HOTKEYSCAN_MIC_DOWN, { KEY_RESERVED } },3256 { KE_KEY, TP_ACPI_HOTKEYSCAN_MIC_UP, { KEY_RESERVED } },3257 { KE_KEY, TP_ACPI_HOTKEYSCAN_MIC_CANCELLATION, { KEY_RESERVED } },3258 { KE_KEY, TP_ACPI_HOTKEYSCAN_CAMERA_MODE, { KEY_RESERVED } },3259 { KE_KEY, TP_ACPI_HOTKEYSCAN_ROTATE_DISPLAY, { KEY_RESERVED } },3260 /* Extended hotkeys mappings translated scancodes 0x34 - 0x4d */3261 { KE_KEY, TP_ACPI_HOTKEYSCAN_STAR, { KEY_BOOKMARKS } },3262 { KE_KEY, TP_ACPI_HOTKEYSCAN_CLIPPING_TOOL2, { KEY_SELECTIVE_SCREENSHOT } },3263 { KE_KEY, TP_ACPI_HOTKEYSCAN_CALCULATOR, { KEY_CALC } },3264 { KE_KEY, TP_ACPI_HOTKEYSCAN_BLUETOOTH, { KEY_BLUETOOTH } },3265 { KE_KEY, TP_ACPI_HOTKEYSCAN_KEYBOARD, { KEY_KEYBOARD } },3266 /* Used by "Lenovo Quick Clean" */3267 { KE_KEY, TP_ACPI_HOTKEYSCAN_FN_RIGHT_SHIFT, { KEY_FN_RIGHT_SHIFT } },3268 { KE_KEY, TP_ACPI_HOTKEYSCAN_NOTIFICATION_CENTER, { KEY_NOTIFICATION_CENTER } },3269 { KE_KEY, TP_ACPI_HOTKEYSCAN_PICKUP_PHONE, { KEY_PICKUP_PHONE } },3270 { KE_KEY, TP_ACPI_HOTKEYSCAN_HANGUP_PHONE, { KEY_HANGUP_PHONE } },3271 /*3272 * All mapping below are for raw untranslated hkey event codes mapped directly3273 * after switching to sparse keymap support. The mappings above use translated3274 * scancodes to preserve uAPI compatibility, see tpacpi_input_send_key().3275 */3276 { KE_KEY, 0x131d, { KEY_VENDOR } }, /* System debug info, similar to old ThinkPad key */3277 { KE_KEY, TP_HKEY_EV_TRACK_DOUBLETAP /* 0x8036 */, { KEY_PROG4 } },3278 { KE_END }3279};3280 3281static int __init hotkey_init(struct ibm_init_struct *iibm)3282{3283 enum keymap_index {3284 TPACPI_KEYMAP_IBM_GENERIC = 0,3285 TPACPI_KEYMAP_LENOVO_GENERIC,3286 };3287 3288 static const struct tpacpi_quirk tpacpi_keymap_qtable[] __initconst = {3289 /* Generic maps (fallback) */3290 {3291 .vendor = PCI_VENDOR_ID_IBM,3292 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,3293 .quirks = TPACPI_KEYMAP_IBM_GENERIC,3294 },3295 {3296 .vendor = PCI_VENDOR_ID_LENOVO,3297 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,3298 .quirks = TPACPI_KEYMAP_LENOVO_GENERIC,3299 },3300 };3301 3302 unsigned long keymap_id, quirks;3303 const struct key_entry *keymap;3304 bool radiosw_state = false;3305 bool tabletsw_state = false;3306 int hkeyv, res, status;3307 3308 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,3309 "initializing hotkey subdriver\n");3310 3311 BUG_ON(!tpacpi_inputdev);3312 BUG_ON(tpacpi_inputdev->open != NULL ||3313 tpacpi_inputdev->close != NULL);3314 3315 TPACPI_ACPIHANDLE_INIT(hkey);3316 mutex_init(&hotkey_mutex);3317 3318#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL3319 mutex_init(&hotkey_thread_data_mutex);3320#endif3321 3322 /* hotkey not supported on 570 */3323 tp_features.hotkey = hkey_handle != NULL;3324 3325 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,3326 "hotkeys are %s\n",3327 str_supported(tp_features.hotkey));3328 3329 if (!tp_features.hotkey)3330 return -ENODEV;3331 3332 quirks = tpacpi_check_quirks(tpacpi_hotkey_qtable,3333 ARRAY_SIZE(tpacpi_hotkey_qtable));3334 3335 tpacpi_disable_brightness_delay();3336 3337 /* mask not supported on 600e/x, 770e, 770x, A21e, A2xm/p,3338 A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking3339 for HKEY interface version 0x100 */3340 if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {3341 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,3342 "firmware HKEY interface version: 0x%x\n",3343 hkeyv);3344 3345 switch (hkeyv >> 8) {3346 case 1:3347 /*3348 * MHKV 0x100 in A31, R40, R40e,3349 * T4x, X31, and later3350 */3351 3352 /* Paranoia check AND init hotkey_all_mask */3353 if (!acpi_evalf(hkey_handle, &hotkey_all_mask,3354 "MHKA", "qd")) {3355 pr_err("missing MHKA handler, please report this to %s\n",3356 TPACPI_MAIL);3357 /* Fallback: pre-init for FN+F3,F4,F12 */3358 hotkey_all_mask = 0x080cU;3359 } else {3360 tp_features.hotkey_mask = 1;3361 }3362 break;3363 3364 case 2:3365 /*3366 * MHKV 0x200 in X1, T460s, X260, T560, X1 Tablet (2016)3367 */3368 3369 /* Paranoia check AND init hotkey_all_mask */3370 if (!acpi_evalf(hkey_handle, &hotkey_all_mask,3371 "MHKA", "dd", 1)) {3372 pr_err("missing MHKA handler, please report this to %s\n",3373 TPACPI_MAIL);3374 /* Fallback: pre-init for FN+F3,F4,F12 */3375 hotkey_all_mask = 0x080cU;3376 } else {3377 tp_features.hotkey_mask = 1;3378 }3379 3380 /*3381 * Check if we have an adaptive keyboard, like on the3382 * Lenovo Carbon X1 2014 (2nd Gen).3383 */3384 if (acpi_evalf(hkey_handle, &hotkey_adaptive_all_mask,3385 "MHKA", "dd", 2)) {3386 if (hotkey_adaptive_all_mask != 0)3387 tp_features.has_adaptive_kbd = true;3388 } else {3389 tp_features.has_adaptive_kbd = false;3390 hotkey_adaptive_all_mask = 0x0U;3391 }3392 break;3393 3394 default:3395 pr_err("unknown version of the HKEY interface: 0x%x\n",3396 hkeyv);3397 pr_err("please report this to %s\n", TPACPI_MAIL);3398 break;3399 }3400 }3401 3402 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,3403 "hotkey masks are %s\n",3404 str_supported(tp_features.hotkey_mask));3405 3406 /* Init hotkey_all_mask if not initialized yet */3407 if (!tp_features.hotkey_mask && !hotkey_all_mask &&3408 (quirks & TPACPI_HK_Q_INIMASK))3409 hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */3410 3411 /* Init hotkey_acpi_mask and hotkey_orig_mask */3412 if (tp_features.hotkey_mask) {3413 /* hotkey_source_mask *must* be zero for3414 * the first hotkey_mask_get to return hotkey_orig_mask */3415 mutex_lock(&hotkey_mutex);3416 res = hotkey_mask_get();3417 mutex_unlock(&hotkey_mutex);3418 if (res)3419 return res;3420 3421 hotkey_orig_mask = hotkey_acpi_mask;3422 } else {3423 hotkey_orig_mask = hotkey_all_mask;3424 hotkey_acpi_mask = hotkey_all_mask;3425 }3426 3427#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES3428 if (dbg_wlswemul) {3429 tp_features.hotkey_wlsw = 1;3430 radiosw_state = !!tpacpi_wlsw_emulstate;3431 pr_info("radio switch emulation enabled\n");3432 } else3433#endif3434 /* Not all thinkpads have a hardware radio switch */3435 if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {3436 tp_features.hotkey_wlsw = 1;3437 radiosw_state = !!status;3438 pr_info("radio switch found; radios are %s\n", str_enabled_disabled(status & BIT(0)));3439 }3440 3441 tabletsw_state = hotkey_init_tablet_mode();3442 3443 /* Set up key map */3444 keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable,3445 ARRAY_SIZE(tpacpi_keymap_qtable));3446 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,3447 "using keymap number %lu\n", keymap_id);3448 3449 /* Keys which should be reserved on both IBM and Lenovo models */3450 hotkey_reserved_mask = TP_ACPI_HKEY_KBD_LIGHT_MASK |3451 TP_ACPI_HKEY_VOLUP_MASK |3452 TP_ACPI_HKEY_VOLDWN_MASK |3453 TP_ACPI_HKEY_MUTE_MASK;3454 /*3455 * Reserve brightness up/down unconditionally on IBM models, on Lenovo3456 * models these are disabled based on acpi_video_get_backlight_type().3457 */3458 if (keymap_id == TPACPI_KEYMAP_IBM_GENERIC) {3459 hotkey_reserved_mask |= TP_ACPI_HKEY_BRGHTUP_MASK |3460 TP_ACPI_HKEY_BRGHTDWN_MASK;3461 keymap = keymap_ibm;3462 } else {3463 keymap = keymap_lenovo;3464 }3465 3466 res = sparse_keymap_setup(tpacpi_inputdev, keymap, NULL);3467 if (res)3468 return res;3469 3470 if (tp_features.hotkey_wlsw) {3471 input_set_capability(tpacpi_inputdev, EV_SW, SW_RFKILL_ALL);3472 input_report_switch(tpacpi_inputdev,3473 SW_RFKILL_ALL, radiosw_state);3474 }3475 if (tp_features.hotkey_tablet) {3476 input_set_capability(tpacpi_inputdev, EV_SW, SW_TABLET_MODE);3477 input_report_switch(tpacpi_inputdev,3478 SW_TABLET_MODE, tabletsw_state);3479 }3480 3481 /* Do not issue duplicate brightness change events to3482 * userspace. tpacpi_detect_brightness_capabilities() must have3483 * been called before this point */3484 if (acpi_video_get_backlight_type() != acpi_backlight_vendor) {3485 pr_info("This ThinkPad has standard ACPI backlight brightness control, supported by the ACPI video driver\n");3486 pr_notice("Disabling thinkpad-acpi brightness events by default...\n");3487 3488 /* Disable brightness up/down on Lenovo thinkpads when3489 * ACPI is handling them, otherwise it is plain impossible3490 * for userspace to do something even remotely sane */3491 hotkey_reserved_mask |= TP_ACPI_HKEY_BRGHTUP_MASK |3492 TP_ACPI_HKEY_BRGHTDWN_MASK;3493 }3494 3495#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL3496 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK3497 & ~hotkey_all_mask3498 & ~hotkey_reserved_mask;3499 3500 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,3501 "hotkey source mask 0x%08x, polling freq %u\n",3502 hotkey_source_mask, hotkey_poll_freq);3503#endif3504 3505 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,3506 "enabling firmware HKEY event interface...\n");3507 res = hotkey_status_set(true);3508 if (res) {3509 hotkey_exit();3510 return res;3511 }3512 mutex_lock(&hotkey_mutex);3513 res = hotkey_mask_set(((hotkey_all_mask & ~hotkey_reserved_mask)3514 | hotkey_driver_mask)3515 & ~hotkey_source_mask);3516 mutex_unlock(&hotkey_mutex);3517 if (res < 0 && res != -ENXIO) {3518 hotkey_exit();3519 return res;3520 }3521 hotkey_user_mask = (hotkey_acpi_mask | hotkey_source_mask)3522 & ~hotkey_reserved_mask;3523 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,3524 "initial masks: user=0x%08x, fw=0x%08x, poll=0x%08x\n",3525 hotkey_user_mask, hotkey_acpi_mask, hotkey_source_mask);3526 3527 tpacpi_inputdev->open = &hotkey_inputdev_open;3528 tpacpi_inputdev->close = &hotkey_inputdev_close;3529 3530 hotkey_poll_setup_safe(true);3531 3532 /* Enable doubletap by default */3533 tp_features.trackpoint_doubletap = 1;3534 3535 return 0;3536}3537 3538/* Thinkpad X1 Carbon support 5 modes including Home mode, Web browser3539 * mode, Web conference mode, Function mode and Lay-flat mode.3540 * We support Home mode and Function mode currently.3541 *3542 * Will consider support rest of modes in future.3543 *3544 */3545static const int adaptive_keyboard_modes[] = {3546 HOME_MODE,3547/* WEB_BROWSER_MODE = 2,3548 WEB_CONFERENCE_MODE = 3, */3549 FUNCTION_MODE3550};3551 3552/* press Fn key a while second, it will switch to Function Mode. Then3553 * release Fn key, previous mode be restored.3554 */3555static bool adaptive_keyboard_mode_is_saved;3556static int adaptive_keyboard_prev_mode;3557 3558static int adaptive_keyboard_get_mode(void)3559{3560 int mode = 0;3561 3562 if (!acpi_evalf(hkey_handle, &mode, "GTRW", "dd", 0)) {3563 pr_err("Cannot read adaptive keyboard mode\n");3564 return -EIO;3565 }3566 3567 return mode;3568}3569 3570static int adaptive_keyboard_set_mode(int new_mode)3571{3572 if (new_mode < 0 ||3573 new_mode > LAYFLAT_MODE)3574 return -EINVAL;3575 3576 if (!acpi_evalf(hkey_handle, NULL, "STRW", "vd", new_mode)) {3577 pr_err("Cannot set adaptive keyboard mode\n");3578 return -EIO;3579 }3580 3581 return 0;3582}3583 3584static int adaptive_keyboard_get_next_mode(int mode)3585{3586 size_t i;3587 size_t max_mode = ARRAY_SIZE(adaptive_keyboard_modes) - 1;3588 3589 for (i = 0; i <= max_mode; i++) {3590 if (adaptive_keyboard_modes[i] == mode)3591 break;3592 }3593 3594 if (i >= max_mode)3595 i = 0;3596 else3597 i++;3598 3599 return adaptive_keyboard_modes[i];3600}3601 3602static void adaptive_keyboard_change_row(void)3603{3604 int mode;3605 3606 if (adaptive_keyboard_mode_is_saved) {3607 mode = adaptive_keyboard_prev_mode;3608 adaptive_keyboard_mode_is_saved = false;3609 } else {3610 mode = adaptive_keyboard_get_mode();3611 if (mode < 0)3612 return;3613 mode = adaptive_keyboard_get_next_mode(mode);3614 }3615 3616 adaptive_keyboard_set_mode(mode);3617}3618 3619static void adaptive_keyboard_s_quickview_row(void)3620{3621 int mode;3622 3623 mode = adaptive_keyboard_get_mode();3624 if (mode < 0)3625 return;3626 3627 adaptive_keyboard_prev_mode = mode;3628 adaptive_keyboard_mode_is_saved = true;3629 3630 adaptive_keyboard_set_mode(FUNCTION_MODE);3631}3632 3633/* 0x1000-0x1FFF: key presses */3634static bool hotkey_notify_hotkey(const u32 hkey, bool *send_acpi_ev)3635{3636 /* Never send ACPI netlink events for original hotkeys (hkey: 0x1001 - 0x1020) */3637 if (hkey >= TP_HKEY_EV_ORIG_KEY_START && hkey <= TP_HKEY_EV_ORIG_KEY_END) {3638 *send_acpi_ev = false;3639 3640 /* Original hotkeys may be polled from NVRAM instead */3641 unsigned int scancode = hkey - TP_HKEY_EV_ORIG_KEY_START;3642 if (hotkey_source_mask & (1 << scancode))3643 return true;3644 }3645 3646 return tpacpi_input_send_key(hkey, send_acpi_ev);3647}3648 3649/* 0x2000-0x2FFF: Wakeup reason */3650static bool hotkey_notify_wakeup(const u32 hkey, bool *send_acpi_ev)3651{3652 switch (hkey) {3653 case TP_HKEY_EV_WKUP_S3_UNDOCK: /* suspend, undock */3654 case TP_HKEY_EV_WKUP_S4_UNDOCK: /* hibernation, undock */3655 hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK;3656 *send_acpi_ev = false;3657 break;3658 3659 case TP_HKEY_EV_WKUP_S3_BAYEJ: /* suspend, bay eject */3660 case TP_HKEY_EV_WKUP_S4_BAYEJ: /* hibernation, bay eject */3661 hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ;3662 *send_acpi_ev = false;3663 break;3664 3665 case TP_HKEY_EV_WKUP_S3_BATLOW: /* Battery on critical low level/S3 */3666 case TP_HKEY_EV_WKUP_S4_BATLOW: /* Battery on critical low level/S4 */3667 pr_alert("EMERGENCY WAKEUP: battery almost empty\n");3668 /* how to auto-heal: */3669 /* 2313: woke up from S3, go to S4/S5 */3670 /* 2413: woke up from S4, go to S5 */3671 break;3672 3673 default:3674 return false;3675 }3676 3677 if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) {3678 pr_info("woke up due to a hot-unplug request...\n");3679 hotkey_wakeup_reason_notify_change();3680 }3681 return true;3682}3683 3684/* 0x4000-0x4FFF: dock-related events */3685static bool hotkey_notify_dockevent(const u32 hkey, bool *send_acpi_ev)3686{3687 switch (hkey) {3688 case TP_HKEY_EV_UNDOCK_ACK:3689 /* ACPI undock operation completed after wakeup */3690 hotkey_autosleep_ack = 1;3691 pr_info("undocked\n");3692 hotkey_wakeup_hotunplug_complete_notify_change();3693 return true;3694 3695 case TP_HKEY_EV_HOTPLUG_DOCK: /* docked to port replicator */3696 pr_info("docked into hotplug port replicator\n");3697 return true;3698 case TP_HKEY_EV_HOTPLUG_UNDOCK: /* undocked from port replicator */3699 pr_info("undocked from hotplug port replicator\n");3700 return true;3701 3702 /*3703 * Deliberately ignore attaching and detaching the keybord cover to avoid3704 * duplicates from intel-vbtn, which already emits SW_TABLET_MODE events3705 * to userspace.3706 *3707 * Please refer to the following thread for more information and a preliminary3708 * implementation using the GTOP ("Get Tablet OPtions") interface that could be3709 * extended to other attachment options of the ThinkPad X1 Tablet series, such as3710 * the Pico cartridge dock module:3711 * https://lore.kernel.org/platform-driver-x86/38cb8265-1e30-d547-9e12-b4ae290be737@a-kobel.de/3712 */3713 case TP_HKEY_EV_KBD_COVER_ATTACH:3714 case TP_HKEY_EV_KBD_COVER_DETACH:3715 *send_acpi_ev = false;3716 return true;3717 3718 default:3719 return false;3720 }3721}3722 3723/* 0x5000-0x5FFF: human interface helpers */3724static bool hotkey_notify_usrevent(const u32 hkey, bool *send_acpi_ev)3725{3726 switch (hkey) {3727 case TP_HKEY_EV_PEN_INSERTED: /* X61t: tablet pen inserted into bay */3728 case TP_HKEY_EV_PEN_REMOVED: /* X61t: tablet pen removed from bay */3729 return true;3730 3731 case TP_HKEY_EV_TABLET_TABLET: /* X41t-X61t: tablet mode */3732 case TP_HKEY_EV_TABLET_NOTEBOOK: /* X41t-X61t: normal mode */3733 tpacpi_input_send_tabletsw();3734 hotkey_tablet_mode_notify_change();3735 *send_acpi_ev = false;3736 return true;3737 3738 case TP_HKEY_EV_LID_CLOSE: /* Lid closed */3739 case TP_HKEY_EV_LID_OPEN: /* Lid opened */3740 case TP_HKEY_EV_BRGHT_CHANGED: /* brightness changed */3741 /* do not propagate these events */3742 *send_acpi_ev = false;3743 return true;3744 3745 default:3746 return false;3747 }3748}3749 3750static void thermal_dump_all_sensors(void);3751static void palmsensor_refresh(void);3752 3753/* 0x6000-0x6FFF: thermal alarms/notices and keyboard events */3754static bool hotkey_notify_6xxx(const u32 hkey, bool *send_acpi_ev)3755{3756 switch (hkey) {3757 case TP_HKEY_EV_THM_TABLE_CHANGED:3758 pr_debug("EC reports: Thermal Table has changed\n");3759 /* recommended action: do nothing, we don't have3760 * Lenovo ATM information */3761 return true;3762 case TP_HKEY_EV_THM_CSM_COMPLETED:3763 pr_debug("EC reports: Thermal Control Command set completed (DYTC)\n");3764 /* Thermal event - pass on to event handler */3765 tpacpi_driver_event(hkey);3766 return true;3767 case TP_HKEY_EV_THM_TRANSFM_CHANGED:3768 pr_debug("EC reports: Thermal Transformation changed (GMTS)\n");3769 /* recommended action: do nothing, we don't have3770 * Lenovo ATM information */3771 return true;3772 case TP_HKEY_EV_ALARM_BAT_HOT:3773 pr_crit("THERMAL ALARM: battery is too hot!\n");3774 /* recommended action: warn user through gui */3775 break;3776 case TP_HKEY_EV_ALARM_BAT_XHOT:3777 pr_alert("THERMAL EMERGENCY: battery is extremely hot!\n");3778 /* recommended action: immediate sleep/hibernate */3779 break;3780 case TP_HKEY_EV_ALARM_SENSOR_HOT:3781 pr_crit("THERMAL ALARM: a sensor reports something is too hot!\n");3782 /* recommended action: warn user through gui, that */3783 /* some internal component is too hot */3784 break;3785 case TP_HKEY_EV_ALARM_SENSOR_XHOT:3786 pr_alert("THERMAL EMERGENCY: a sensor reports something is extremely hot!\n");3787 /* recommended action: immediate sleep/hibernate */3788 break;3789 case TP_HKEY_EV_AC_CHANGED:3790 /* X120e, X121e, X220, X220i, X220t, X230, T420, T420s, W520:3791 * AC status changed; can be triggered by plugging or3792 * unplugging AC adapter, docking or undocking. */3793 3794 fallthrough;3795 3796 case TP_HKEY_EV_KEY_NUMLOCK:3797 case TP_HKEY_EV_KEY_FN:3798 /* key press events, we just ignore them as long as the EC3799 * is still reporting them in the normal keyboard stream */3800 *send_acpi_ev = false;3801 return true;3802 3803 case TP_HKEY_EV_KEY_FN_ESC:3804 /* Get the media key status to force the status LED to update */3805 acpi_evalf(hkey_handle, NULL, "GMKS", "v");3806 *send_acpi_ev = false;3807 return true;3808 3809 case TP_HKEY_EV_TABLET_CHANGED:3810 tpacpi_input_send_tabletsw();3811 hotkey_tablet_mode_notify_change();3812 *send_acpi_ev = false;3813 return true;3814 3815 case TP_HKEY_EV_PALM_DETECTED:3816 case TP_HKEY_EV_PALM_UNDETECTED:3817 /* palm detected - pass on to event handler */3818 palmsensor_refresh();3819 return true;3820 3821 default:3822 /* report simply as unknown, no sensor dump */3823 return false;3824 }3825 3826 thermal_dump_all_sensors();3827 return true;3828}3829 3830static bool hotkey_notify_8xxx(const u32 hkey, bool *send_acpi_ev)3831{3832 switch (hkey) {3833 case TP_HKEY_EV_TRACK_DOUBLETAP:3834 if (tp_features.trackpoint_doubletap)3835 tpacpi_input_send_key(hkey, send_acpi_ev);3836 3837 return true;3838 default:3839 return false;3840 }3841}3842 3843static void hotkey_notify(struct ibm_struct *ibm, u32 event)3844{3845 u32 hkey;3846 bool send_acpi_ev;3847 bool known_ev;3848 3849 if (event != 0x80) {3850 pr_err("unknown HKEY notification event %d\n", event);3851 /* forward it to userspace, maybe it knows how to handle it */3852 acpi_bus_generate_netlink_event(3853 ibm->acpi->device->pnp.device_class,3854 dev_name(&ibm->acpi->device->dev),3855 event, 0);3856 return;3857 }3858 3859 while (1) {3860 if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {3861 pr_err("failed to retrieve HKEY event\n");3862 return;3863 }3864 3865 if (hkey == 0) {3866 /* queue empty */3867 return;3868 }3869 3870 send_acpi_ev = true;3871 known_ev = false;3872 3873 switch (hkey >> 12) {3874 case 1:3875 /* 0x1000-0x1FFF: key presses */3876 known_ev = hotkey_notify_hotkey(hkey, &send_acpi_ev);3877 break;3878 case 2:3879 /* 0x2000-0x2FFF: Wakeup reason */3880 known_ev = hotkey_notify_wakeup(hkey, &send_acpi_ev);3881 break;3882 case 3:3883 /* 0x3000-0x3FFF: bay-related wakeups */3884 switch (hkey) {3885 case TP_HKEY_EV_BAYEJ_ACK:3886 hotkey_autosleep_ack = 1;3887 pr_info("bay ejected\n");3888 hotkey_wakeup_hotunplug_complete_notify_change();3889 known_ev = true;3890 break;3891 case TP_HKEY_EV_OPTDRV_EJ:3892 /* FIXME: kick libata if SATA link offline */3893 known_ev = true;3894 break;3895 }3896 break;3897 case 4:3898 /* 0x4000-0x4FFF: dock-related events */3899 known_ev = hotkey_notify_dockevent(hkey, &send_acpi_ev);3900 break;3901 case 5:3902 /* 0x5000-0x5FFF: human interface helpers */3903 known_ev = hotkey_notify_usrevent(hkey, &send_acpi_ev);3904 break;3905 case 6:3906 /* 0x6000-0x6FFF: thermal alarms/notices and3907 * keyboard events */3908 known_ev = hotkey_notify_6xxx(hkey, &send_acpi_ev);3909 break;3910 case 7:3911 /* 0x7000-0x7FFF: misc */3912 if (tp_features.hotkey_wlsw &&3913 hkey == TP_HKEY_EV_RFKILL_CHANGED) {3914 tpacpi_send_radiosw_update();3915 send_acpi_ev = false;3916 known_ev = true;3917 }3918 break;3919 case 8:3920 /* 0x8000-0x8FFF: misc2 */3921 known_ev = hotkey_notify_8xxx(hkey, &send_acpi_ev);3922 break;3923 }3924 if (!known_ev) {3925 pr_notice("unhandled HKEY event 0x%04x\n", hkey);3926 pr_notice("please report the conditions when this event happened to %s\n",3927 TPACPI_MAIL);3928 }3929 3930 /* netlink events */3931 if (send_acpi_ev) {3932 acpi_bus_generate_netlink_event(3933 ibm->acpi->device->pnp.device_class,3934 dev_name(&ibm->acpi->device->dev),3935 event, hkey);3936 }3937 }3938}3939 3940static void hotkey_suspend(void)3941{3942 /* Do these on suspend, we get the events on early resume! */3943 hotkey_wakeup_reason = TP_ACPI_WAKEUP_NONE;3944 hotkey_autosleep_ack = 0;3945 3946 /* save previous mode of adaptive keyboard of X1 Carbon */3947 if (tp_features.has_adaptive_kbd) {3948 if (!acpi_evalf(hkey_handle, &adaptive_keyboard_prev_mode,3949 "GTRW", "dd", 0)) {3950 pr_err("Cannot read adaptive keyboard mode.\n");3951 }3952 }3953}3954 3955static void hotkey_resume(void)3956{3957 tpacpi_disable_brightness_delay();3958 3959 mutex_lock(&hotkey_mutex);3960 if (hotkey_status_set(true) < 0 ||3961 hotkey_mask_set(hotkey_acpi_mask) < 0)3962 pr_err("error while attempting to reset the event firmware interface\n");3963 mutex_unlock(&hotkey_mutex);3964 3965 tpacpi_send_radiosw_update();3966 tpacpi_input_send_tabletsw();3967 hotkey_tablet_mode_notify_change();3968 hotkey_wakeup_reason_notify_change();3969 hotkey_wakeup_hotunplug_complete_notify_change();3970 hotkey_poll_setup_safe(false);3971 3972 /* restore previous mode of adapive keyboard of X1 Carbon */3973 if (tp_features.has_adaptive_kbd) {3974 if (!acpi_evalf(hkey_handle, NULL, "STRW", "vd",3975 adaptive_keyboard_prev_mode)) {3976 pr_err("Cannot set adaptive keyboard mode.\n");3977 }3978 }3979}3980 3981/* procfs -------------------------------------------------------------- */3982static int hotkey_read(struct seq_file *m)3983{3984 int res, status;3985 3986 if (!tp_features.hotkey) {3987 seq_printf(m, "status:\t\tnot supported\n");3988 return 0;3989 }3990 3991 if (mutex_lock_killable(&hotkey_mutex))3992 return -ERESTARTSYS;3993 res = hotkey_status_get(&status);3994 if (!res)3995 res = hotkey_mask_get();3996 mutex_unlock(&hotkey_mutex);3997 if (res)3998 return res;3999 4000 seq_printf(m, "status:\t\t%s\n", str_enabled_disabled(status & BIT(0)));4001 if (hotkey_all_mask) {4002 seq_printf(m, "mask:\t\t0x%08x\n", hotkey_user_mask);4003 seq_printf(m, "commands:\tenable, disable, reset, <mask>\n");4004 } else {4005 seq_printf(m, "mask:\t\tnot supported\n");4006 seq_printf(m, "commands:\tenable, disable, reset\n");4007 }4008 4009 return 0;4010}4011 4012static void hotkey_enabledisable_warn(bool enable)4013{4014 tpacpi_log_usertask("procfs hotkey enable/disable");4015 if (!WARN((tpacpi_lifecycle == TPACPI_LIFE_RUNNING || !enable),4016 pr_fmt("hotkey enable/disable functionality has been removed from the driver. Hotkeys are always enabled.\n")))4017 pr_err("Please remove the hotkey=enable module parameter, it is deprecated. Hotkeys are always enabled.\n");4018}4019 4020static int hotkey_write(char *buf)4021{4022 int res;4023 u32 mask;4024 char *cmd;4025 4026 if (!tp_features.hotkey)4027 return -ENODEV;4028 4029 if (mutex_lock_killable(&hotkey_mutex))4030 return -ERESTARTSYS;4031 4032 mask = hotkey_user_mask;4033 4034 res = 0;4035 while ((cmd = strsep(&buf, ","))) {4036 if (strstarts(cmd, "enable")) {4037 hotkey_enabledisable_warn(1);4038 } else if (strstarts(cmd, "disable")) {4039 hotkey_enabledisable_warn(0);4040 res = -EPERM;4041 } else if (strstarts(cmd, "reset")) {4042 mask = (hotkey_all_mask | hotkey_source_mask)4043 & ~hotkey_reserved_mask;4044 } else if (sscanf(cmd, "0x%x", &mask) == 1) {4045 /* mask set */4046 } else if (sscanf(cmd, "%x", &mask) == 1) {4047 /* mask set */4048 } else {4049 res = -EINVAL;4050 goto errexit;4051 }4052 }4053 4054 if (!res) {4055 tpacpi_disclose_usertask("procfs hotkey",4056 "set mask to 0x%08x\n", mask);4057 res = hotkey_user_mask_set(mask);4058 }4059 4060errexit:4061 mutex_unlock(&hotkey_mutex);4062 return res;4063}4064 4065static const struct acpi_device_id ibm_htk_device_ids[] = {4066 {TPACPI_ACPI_IBM_HKEY_HID, 0},4067 {TPACPI_ACPI_LENOVO_HKEY_HID, 0},4068 {TPACPI_ACPI_LENOVO_HKEY_V2_HID, 0},4069 {"", 0},4070};4071 4072static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = {4073 .hid = ibm_htk_device_ids,4074 .notify = hotkey_notify,4075 .handle = &hkey_handle,4076 .type = ACPI_DEVICE_NOTIFY,4077};4078 4079static struct ibm_struct hotkey_driver_data = {4080 .name = "hotkey",4081 .read = hotkey_read,4082 .write = hotkey_write,4083 .exit = hotkey_exit,4084 .resume = hotkey_resume,4085 .suspend = hotkey_suspend,4086 .acpi = &ibm_hotkey_acpidriver,4087};4088 4089/*************************************************************************4090 * Bluetooth subdriver4091 */4092 4093enum {4094 /* ACPI GBDC/SBDC bits */4095 TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */4096 TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */4097 TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume:4098 0 = disable, 1 = enable */4099};4100 4101enum {4102 /* ACPI \BLTH commands */4103 TP_ACPI_BLTH_GET_ULTRAPORT_ID = 0x00, /* Get Ultraport BT ID */4104 TP_ACPI_BLTH_GET_PWR_ON_RESUME = 0x01, /* Get power-on-resume state */4105 TP_ACPI_BLTH_PWR_ON_ON_RESUME = 0x02, /* Resume powered on */4106 TP_ACPI_BLTH_PWR_OFF_ON_RESUME = 0x03, /* Resume powered off */4107 TP_ACPI_BLTH_SAVE_STATE = 0x05, /* Save state for S4/S5 */4108};4109 4110#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw"4111 4112static int bluetooth_get_status(void)4113{4114 int status;4115 4116#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES4117 if (dbg_bluetoothemul)4118 return (tpacpi_bluetooth_emulstate) ?4119 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;4120#endif4121 4122 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))4123 return -EIO;4124 4125 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ?4126 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;4127}4128 4129static int bluetooth_set_status(enum tpacpi_rfkill_state state)4130{4131 int status;4132 4133 vdbg_printk(TPACPI_DBG_RFKILL, "will attempt to %s bluetooth\n",4134 str_enable_disable(state == TPACPI_RFK_RADIO_ON));4135 4136#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES4137 if (dbg_bluetoothemul) {4138 tpacpi_bluetooth_emulstate = (state == TPACPI_RFK_RADIO_ON);4139 return 0;4140 }4141#endif4142 4143 if (state == TPACPI_RFK_RADIO_ON)4144 status = TP_ACPI_BLUETOOTH_RADIOSSW4145 | TP_ACPI_BLUETOOTH_RESUMECTRL;4146 else4147 status = 0;4148 4149 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))4150 return -EIO;4151 4152 return 0;4153}4154 4155/* sysfs bluetooth enable ---------------------------------------------- */4156static ssize_t bluetooth_enable_show(struct device *dev,4157 struct device_attribute *attr,4158 char *buf)4159{4160 return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_BLUETOOTH_SW_ID,4161 attr, buf);4162}4163 4164static ssize_t bluetooth_enable_store(struct device *dev,4165 struct device_attribute *attr,4166 const char *buf, size_t count)4167{4168 return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_BLUETOOTH_SW_ID,4169 attr, buf, count);4170}4171 4172static DEVICE_ATTR_RW(bluetooth_enable);4173 4174/* --------------------------------------------------------------------- */4175 4176static struct attribute *bluetooth_attributes[] = {4177 &dev_attr_bluetooth_enable.attr,4178 NULL4179};4180 4181static umode_t bluetooth_attr_is_visible(struct kobject *kobj,4182 struct attribute *attr, int n)4183{4184 return tp_features.bluetooth ? attr->mode : 0;4185}4186 4187static const struct attribute_group bluetooth_attr_group = {4188 .is_visible = bluetooth_attr_is_visible,4189 .attrs = bluetooth_attributes,4190};4191 4192static const struct tpacpi_rfk_ops bluetooth_tprfk_ops = {4193 .get_status = bluetooth_get_status,4194 .set_status = bluetooth_set_status,4195};4196 4197static void bluetooth_shutdown(void)4198{4199 /* Order firmware to save current state to NVRAM */4200 if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",4201 TP_ACPI_BLTH_SAVE_STATE))4202 pr_notice("failed to save bluetooth state to NVRAM\n");4203 else4204 vdbg_printk(TPACPI_DBG_RFKILL,4205 "bluetooth state saved to NVRAM\n");4206}4207 4208static void bluetooth_exit(void)4209{4210 tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);4211 bluetooth_shutdown();4212}4213 4214static const struct dmi_system_id fwbug_list[] __initconst = {4215 {4216 .ident = "ThinkPad E485",4217 .driver_data = &quirk_btusb_bug,4218 .matches = {4219 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),4220 DMI_MATCH(DMI_BOARD_NAME, "20KU"),4221 },4222 },4223 {4224 .ident = "ThinkPad E585",4225 .driver_data = &quirk_btusb_bug,4226 .matches = {4227 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),4228 DMI_MATCH(DMI_BOARD_NAME, "20KV"),4229 },4230 },4231 {4232 .ident = "ThinkPad A285 - 20MW",4233 .driver_data = &quirk_btusb_bug,4234 .matches = {4235 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),4236 DMI_MATCH(DMI_BOARD_NAME, "20MW"),4237 },4238 },4239 {4240 .ident = "ThinkPad A285 - 20MX",4241 .driver_data = &quirk_btusb_bug,4242 .matches = {4243 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),4244 DMI_MATCH(DMI_BOARD_NAME, "20MX"),4245 },4246 },4247 {4248 .ident = "ThinkPad A485 - 20MU",4249 .driver_data = &quirk_btusb_bug,4250 .matches = {4251 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),4252 DMI_MATCH(DMI_BOARD_NAME, "20MU"),4253 },4254 },4255 {4256 .ident = "ThinkPad A485 - 20MV",4257 .driver_data = &quirk_btusb_bug,4258 .matches = {4259 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),4260 DMI_MATCH(DMI_BOARD_NAME, "20MV"),4261 },4262 },4263 {}4264};4265 4266static const struct pci_device_id fwbug_cards_ids[] __initconst = {4267 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x24F3) },4268 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x24FD) },4269 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2526) },4270 {}4271};4272 4273 4274static int __init have_bt_fwbug(void)4275{4276 /*4277 * Some AMD based ThinkPads have a firmware bug that calling4278 * "GBDC" will cause bluetooth on Intel wireless cards blocked4279 */4280 if (tp_features.quirks && tp_features.quirks->btusb_bug &&4281 pci_dev_present(fwbug_cards_ids)) {4282 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,4283 FW_BUG "disable bluetooth subdriver for Intel cards\n");4284 return 1;4285 } else4286 return 0;4287}4288 4289static int __init bluetooth_init(struct ibm_init_struct *iibm)4290{4291 int res;4292 int status = 0;4293 4294 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,4295 "initializing bluetooth subdriver\n");4296 4297 TPACPI_ACPIHANDLE_INIT(hkey);4298 4299 /* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,4300 G4x, R30, R31, R40e, R50e, T20-22, X20-21 */4301 tp_features.bluetooth = !have_bt_fwbug() && hkey_handle &&4302 acpi_evalf(hkey_handle, &status, "GBDC", "qd");4303 4304 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,4305 "bluetooth is %s, status 0x%02x\n",4306 str_supported(tp_features.bluetooth),4307 status);4308 4309#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES4310 if (dbg_bluetoothemul) {4311 tp_features.bluetooth = 1;4312 pr_info("bluetooth switch emulation enabled\n");4313 } else4314#endif4315 if (tp_features.bluetooth &&4316 !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {4317 /* no bluetooth hardware present in system */4318 tp_features.bluetooth = 0;4319 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,4320 "bluetooth hardware not installed\n");4321 }4322 4323 if (!tp_features.bluetooth)4324 return -ENODEV;4325 4326 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,4327 &bluetooth_tprfk_ops,4328 RFKILL_TYPE_BLUETOOTH,4329 TPACPI_RFK_BLUETOOTH_SW_NAME,4330 true);4331 return res;4332}4333 4334/* procfs -------------------------------------------------------------- */4335static int bluetooth_read(struct seq_file *m)4336{4337 return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, m);4338}4339 4340static int bluetooth_write(char *buf)4341{4342 return tpacpi_rfk_procfs_write(TPACPI_RFK_BLUETOOTH_SW_ID, buf);4343}4344 4345static struct ibm_struct bluetooth_driver_data = {4346 .name = "bluetooth",4347 .read = bluetooth_read,4348 .write = bluetooth_write,4349 .exit = bluetooth_exit,4350 .shutdown = bluetooth_shutdown,4351};4352 4353/*************************************************************************4354 * Wan subdriver4355 */4356 4357enum {4358 /* ACPI GWAN/SWAN bits */4359 TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */4360 TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */4361 TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume:4362 0 = disable, 1 = enable */4363};4364 4365#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"4366 4367static int wan_get_status(void)4368{4369 int status;4370 4371#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES4372 if (dbg_wwanemul)4373 return (tpacpi_wwan_emulstate) ?4374 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;4375#endif4376 4377 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))4378 return -EIO;4379 4380 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ?4381 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;4382}4383 4384static int wan_set_status(enum tpacpi_rfkill_state state)4385{4386 int status;4387 4388 vdbg_printk(TPACPI_DBG_RFKILL, "will attempt to %s wwan\n",4389 str_enable_disable(state == TPACPI_RFK_RADIO_ON));4390 4391#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES4392 if (dbg_wwanemul) {4393 tpacpi_wwan_emulstate = (state == TPACPI_RFK_RADIO_ON);4394 return 0;4395 }4396#endif4397 4398 if (state == TPACPI_RFK_RADIO_ON)4399 status = TP_ACPI_WANCARD_RADIOSSW4400 | TP_ACPI_WANCARD_RESUMECTRL;4401 else4402 status = 0;4403 4404 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))4405 return -EIO;4406 4407 return 0;4408}4409 4410/* sysfs wan enable ---------------------------------------------------- */4411static ssize_t wan_enable_show(struct device *dev,4412 struct device_attribute *attr,4413 char *buf)4414{4415 return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_WWAN_SW_ID,4416 attr, buf);4417}4418 4419static ssize_t wan_enable_store(struct device *dev,4420 struct device_attribute *attr,4421 const char *buf, size_t count)4422{4423 return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_WWAN_SW_ID,4424 attr, buf, count);4425}4426 4427static DEVICE_ATTR(wwan_enable, S_IWUSR | S_IRUGO,4428 wan_enable_show, wan_enable_store);4429 4430/* --------------------------------------------------------------------- */4431 4432static struct attribute *wan_attributes[] = {4433 &dev_attr_wwan_enable.attr,4434 NULL4435};4436 4437static umode_t wan_attr_is_visible(struct kobject *kobj, struct attribute *attr,4438 int n)4439{4440 return tp_features.wan ? attr->mode : 0;4441}4442 4443static const struct attribute_group wan_attr_group = {4444 .is_visible = wan_attr_is_visible,4445 .attrs = wan_attributes,4446};4447 4448static const struct tpacpi_rfk_ops wan_tprfk_ops = {4449 .get_status = wan_get_status,4450 .set_status = wan_set_status,4451};4452 4453static void wan_shutdown(void)4454{4455 /* Order firmware to save current state to NVRAM */4456 if (!acpi_evalf(NULL, NULL, "\\WGSV", "vd",4457 TP_ACPI_WGSV_SAVE_STATE))4458 pr_notice("failed to save WWAN state to NVRAM\n");4459 else4460 vdbg_printk(TPACPI_DBG_RFKILL,4461 "WWAN state saved to NVRAM\n");4462}4463 4464static void wan_exit(void)4465{4466 tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);4467 wan_shutdown();4468}4469 4470static int __init wan_init(struct ibm_init_struct *iibm)4471{4472 int res;4473 int status = 0;4474 4475 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,4476 "initializing wan subdriver\n");4477 4478 TPACPI_ACPIHANDLE_INIT(hkey);4479 4480 tp_features.wan = hkey_handle &&4481 acpi_evalf(hkey_handle, &status, "GWAN", "qd");4482 4483 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,4484 "wan is %s, status 0x%02x\n",4485 str_supported(tp_features.wan),4486 status);4487 4488#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES4489 if (dbg_wwanemul) {4490 tp_features.wan = 1;4491 pr_info("wwan switch emulation enabled\n");4492 } else4493#endif4494 if (tp_features.wan &&4495 !(status & TP_ACPI_WANCARD_HWPRESENT)) {4496 /* no wan hardware present in system */4497 tp_features.wan = 0;4498 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,4499 "wan hardware not installed\n");4500 }4501 4502 if (!tp_features.wan)4503 return -ENODEV;4504 4505 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,4506 &wan_tprfk_ops,4507 RFKILL_TYPE_WWAN,4508 TPACPI_RFK_WWAN_SW_NAME,4509 true);4510 return res;4511}4512 4513/* procfs -------------------------------------------------------------- */4514static int wan_read(struct seq_file *m)4515{4516 return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, m);4517}4518 4519static int wan_write(char *buf)4520{4521 return tpacpi_rfk_procfs_write(TPACPI_RFK_WWAN_SW_ID, buf);4522}4523 4524static struct ibm_struct wan_driver_data = {4525 .name = "wan",4526 .read = wan_read,4527 .write = wan_write,4528 .exit = wan_exit,4529 .shutdown = wan_shutdown,4530};4531 4532/*************************************************************************4533 * UWB subdriver4534 */4535 4536enum {4537 /* ACPI GUWB/SUWB bits */4538 TP_ACPI_UWB_HWPRESENT = 0x01, /* UWB hw available */4539 TP_ACPI_UWB_RADIOSSW = 0x02, /* UWB radio enabled */4540};4541 4542#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw"4543 4544static int uwb_get_status(void)4545{4546 int status;4547 4548#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES4549 if (dbg_uwbemul)4550 return (tpacpi_uwb_emulstate) ?4551 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;4552#endif4553 4554 if (!acpi_evalf(hkey_handle, &status, "GUWB", "d"))4555 return -EIO;4556 4557 return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ?4558 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;4559}4560 4561static int uwb_set_status(enum tpacpi_rfkill_state state)4562{4563 int status;4564 4565 vdbg_printk(TPACPI_DBG_RFKILL, "will attempt to %s UWB\n",4566 str_enable_disable(state == TPACPI_RFK_RADIO_ON));4567 4568#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES4569 if (dbg_uwbemul) {4570 tpacpi_uwb_emulstate = (state == TPACPI_RFK_RADIO_ON);4571 return 0;4572 }4573#endif4574 4575 if (state == TPACPI_RFK_RADIO_ON)4576 status = TP_ACPI_UWB_RADIOSSW;4577 else4578 status = 0;4579 4580 if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status))4581 return -EIO;4582 4583 return 0;4584}4585 4586/* --------------------------------------------------------------------- */4587 4588static const struct tpacpi_rfk_ops uwb_tprfk_ops = {4589 .get_status = uwb_get_status,4590 .set_status = uwb_set_status,4591};4592 4593static void uwb_exit(void)4594{4595 tpacpi_destroy_rfkill(TPACPI_RFK_UWB_SW_ID);4596}4597 4598static int __init uwb_init(struct ibm_init_struct *iibm)4599{4600 int res;4601 int status = 0;4602 4603 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,4604 "initializing uwb subdriver\n");4605 4606 TPACPI_ACPIHANDLE_INIT(hkey);4607 4608 tp_features.uwb = hkey_handle &&4609 acpi_evalf(hkey_handle, &status, "GUWB", "qd");4610 4611 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,4612 "uwb is %s, status 0x%02x\n",4613 str_supported(tp_features.uwb),4614 status);4615 4616#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES4617 if (dbg_uwbemul) {4618 tp_features.uwb = 1;4619 pr_info("uwb switch emulation enabled\n");4620 } else4621#endif4622 if (tp_features.uwb &&4623 !(status & TP_ACPI_UWB_HWPRESENT)) {4624 /* no uwb hardware present in system */4625 tp_features.uwb = 0;4626 dbg_printk(TPACPI_DBG_INIT,4627 "uwb hardware not installed\n");4628 }4629 4630 if (!tp_features.uwb)4631 return -ENODEV;4632 4633 res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,4634 &uwb_tprfk_ops,4635 RFKILL_TYPE_UWB,4636 TPACPI_RFK_UWB_SW_NAME,4637 false);4638 return res;4639}4640 4641static struct ibm_struct uwb_driver_data = {4642 .name = "uwb",4643 .exit = uwb_exit,4644 .flags.experimental = 1,4645};4646 4647/*************************************************************************4648 * Video subdriver4649 */4650 4651#ifdef CONFIG_THINKPAD_ACPI_VIDEO4652 4653enum video_access_mode {4654 TPACPI_VIDEO_NONE = 0,4655 TPACPI_VIDEO_570, /* 570 */4656 TPACPI_VIDEO_770, /* 600e/x, 770e, 770x */4657 TPACPI_VIDEO_NEW, /* all others */4658};4659 4660enum { /* video status flags, based on VIDEO_570 */4661 TP_ACPI_VIDEO_S_LCD = 0x01, /* LCD output enabled */4662 TP_ACPI_VIDEO_S_CRT = 0x02, /* CRT output enabled */4663 TP_ACPI_VIDEO_S_DVI = 0x08, /* DVI output enabled */4664};4665 4666enum { /* TPACPI_VIDEO_570 constants */4667 TP_ACPI_VIDEO_570_PHSCMD = 0x87, /* unknown magic constant :( */4668 TP_ACPI_VIDEO_570_PHSMASK = 0x03, /* PHS bits that map to4669 * video_status_flags */4670 TP_ACPI_VIDEO_570_PHS2CMD = 0x8b, /* unknown magic constant :( */4671 TP_ACPI_VIDEO_570_PHS2SET = 0x80, /* unknown magic constant :( */4672};4673 4674static enum video_access_mode video_supported;4675static int video_orig_autosw;4676 4677static int video_autosw_get(void);4678static int video_autosw_set(int enable);4679 4680TPACPI_HANDLE(vid, root,4681 "\\_SB.PCI.AGP.VGA", /* 570 */4682 "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */4683 "\\_SB.PCI0.VID0", /* 770e */4684 "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */4685 "\\_SB.PCI0.AGP.VGA", /* X100e and a few others */4686 "\\_SB.PCI0.AGP.VID", /* all others */4687 ); /* R30, R31 */4688 4689TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID"); /* G41 */4690 4691static int __init video_init(struct ibm_init_struct *iibm)4692{4693 int ivga;4694 4695 vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n");4696 4697 TPACPI_ACPIHANDLE_INIT(vid);4698 if (tpacpi_is_ibm())4699 TPACPI_ACPIHANDLE_INIT(vid2);4700 4701 if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga)4702 /* G41, assume IVGA doesn't change */4703 vid_handle = vid2_handle;4704 4705 if (!vid_handle)4706 /* video switching not supported on R30, R31 */4707 video_supported = TPACPI_VIDEO_NONE;4708 else if (tpacpi_is_ibm() &&4709 acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd"))4710 /* 570 */4711 video_supported = TPACPI_VIDEO_570;4712 else if (tpacpi_is_ibm() &&4713 acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd"))4714 /* 600e/x, 770e, 770x */4715 video_supported = TPACPI_VIDEO_770;4716 else4717 /* all others */4718 video_supported = TPACPI_VIDEO_NEW;4719 4720 vdbg_printk(TPACPI_DBG_INIT, "video is %s, mode %d\n",4721 str_supported(video_supported != TPACPI_VIDEO_NONE),4722 video_supported);4723 4724 return (video_supported != TPACPI_VIDEO_NONE) ? 0 : -ENODEV;4725}4726 4727static void video_exit(void)4728{4729 dbg_printk(TPACPI_DBG_EXIT,4730 "restoring original video autoswitch mode\n");4731 if (video_autosw_set(video_orig_autosw))4732 pr_err("error while trying to restore original video autoswitch mode\n");4733}4734 4735static int video_outputsw_get(void)4736{4737 int status = 0;4738 int i;4739 4740 switch (video_supported) {4741 case TPACPI_VIDEO_570:4742 if (!acpi_evalf(NULL, &i, "\\_SB.PHS", "dd",4743 TP_ACPI_VIDEO_570_PHSCMD))4744 return -EIO;4745 status = i & TP_ACPI_VIDEO_570_PHSMASK;4746 break;4747 case TPACPI_VIDEO_770:4748 if (!acpi_evalf(NULL, &i, "\\VCDL", "d"))4749 return -EIO;4750 if (i)4751 status |= TP_ACPI_VIDEO_S_LCD;4752 if (!acpi_evalf(NULL, &i, "\\VCDC", "d"))4753 return -EIO;4754 if (i)4755 status |= TP_ACPI_VIDEO_S_CRT;4756 break;4757 case TPACPI_VIDEO_NEW:4758 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1) ||4759 !acpi_evalf(NULL, &i, "\\VCDC", "d"))4760 return -EIO;4761 if (i)4762 status |= TP_ACPI_VIDEO_S_CRT;4763 4764 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0) ||4765 !acpi_evalf(NULL, &i, "\\VCDL", "d"))4766 return -EIO;4767 if (i)4768 status |= TP_ACPI_VIDEO_S_LCD;4769 if (!acpi_evalf(NULL, &i, "\\VCDD", "d"))4770 return -EIO;4771 if (i)4772 status |= TP_ACPI_VIDEO_S_DVI;4773 break;4774 default:4775 return -ENOSYS;4776 }4777 4778 return status;4779}4780 4781static int video_outputsw_set(int status)4782{4783 int autosw;4784 int res = 0;4785 4786 switch (video_supported) {4787 case TPACPI_VIDEO_570:4788 res = acpi_evalf(NULL, NULL,4789 "\\_SB.PHS2", "vdd",4790 TP_ACPI_VIDEO_570_PHS2CMD,4791 status | TP_ACPI_VIDEO_570_PHS2SET);4792 break;4793 case TPACPI_VIDEO_770:4794 autosw = video_autosw_get();4795 if (autosw < 0)4796 return autosw;4797 4798 res = video_autosw_set(1);4799 if (res)4800 return res;4801 res = acpi_evalf(vid_handle, NULL,4802 "ASWT", "vdd", status * 0x100, 0);4803 if (!autosw && video_autosw_set(autosw)) {4804 pr_err("video auto-switch left enabled due to error\n");4805 return -EIO;4806 }4807 break;4808 case TPACPI_VIDEO_NEW:4809 res = acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80) &&4810 acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1);4811 break;4812 default:4813 return -ENOSYS;4814 }4815 4816 return (res) ? 0 : -EIO;4817}4818 4819static int video_autosw_get(void)4820{4821 int autosw = 0;4822 4823 switch (video_supported) {4824 case TPACPI_VIDEO_570:4825 if (!acpi_evalf(vid_handle, &autosw, "SWIT", "d"))4826 return -EIO;4827 break;4828 case TPACPI_VIDEO_770:4829 case TPACPI_VIDEO_NEW:4830 if (!acpi_evalf(vid_handle, &autosw, "^VDEE", "d"))4831 return -EIO;4832 break;4833 default:4834 return -ENOSYS;4835 }4836 4837 return autosw & 1;4838}4839 4840static int video_autosw_set(int enable)4841{4842 if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", (enable) ? 1 : 0))4843 return -EIO;4844 return 0;4845}4846 4847static int video_outputsw_cycle(void)4848{4849 int autosw = video_autosw_get();4850 int res;4851 4852 if (autosw < 0)4853 return autosw;4854 4855 switch (video_supported) {4856 case TPACPI_VIDEO_570:4857 res = video_autosw_set(1);4858 if (res)4859 return res;4860 res = acpi_evalf(ec_handle, NULL, "_Q16", "v");4861 break;4862 case TPACPI_VIDEO_770:4863 case TPACPI_VIDEO_NEW:4864 res = video_autosw_set(1);4865 if (res)4866 return res;4867 res = acpi_evalf(vid_handle, NULL, "VSWT", "v");4868 break;4869 default:4870 return -ENOSYS;4871 }4872 if (!autosw && video_autosw_set(autosw)) {4873 pr_err("video auto-switch left enabled due to error\n");4874 return -EIO;4875 }4876 4877 return (res) ? 0 : -EIO;4878}4879 4880static int video_expand_toggle(void)4881{4882 switch (video_supported) {4883 case TPACPI_VIDEO_570:4884 return acpi_evalf(ec_handle, NULL, "_Q17", "v") ?4885 0 : -EIO;4886 case TPACPI_VIDEO_770:4887 return acpi_evalf(vid_handle, NULL, "VEXP", "v") ?4888 0 : -EIO;4889 case TPACPI_VIDEO_NEW:4890 return acpi_evalf(NULL, NULL, "\\VEXP", "v") ?4891 0 : -EIO;4892 default:4893 return -ENOSYS;4894 }4895 /* not reached */4896}4897 4898static int video_read(struct seq_file *m)4899{4900 int status, autosw;4901 4902 if (video_supported == TPACPI_VIDEO_NONE) {4903 seq_printf(m, "status:\t\tnot supported\n");4904 return 0;4905 }4906 4907 /* Even reads can crash X.org, so... */4908 if (!capable(CAP_SYS_ADMIN))4909 return -EPERM;4910 4911 status = video_outputsw_get();4912 if (status < 0)4913 return status;4914 4915 autosw = video_autosw_get();4916 if (autosw < 0)4917 return autosw;4918 4919 seq_printf(m, "status:\t\tsupported\n");4920 seq_printf(m, "lcd:\t\t%s\n", str_enabled_disabled(status & BIT(0)));4921 seq_printf(m, "crt:\t\t%s\n", str_enabled_disabled(status & BIT(1)));4922 if (video_supported == TPACPI_VIDEO_NEW)4923 seq_printf(m, "dvi:\t\t%s\n", str_enabled_disabled(status & BIT(3)));4924 seq_printf(m, "auto:\t\t%s\n", str_enabled_disabled(autosw & BIT(0)));4925 seq_printf(m, "commands:\tlcd_enable, lcd_disable\n");4926 seq_printf(m, "commands:\tcrt_enable, crt_disable\n");4927 if (video_supported == TPACPI_VIDEO_NEW)4928 seq_printf(m, "commands:\tdvi_enable, dvi_disable\n");4929 seq_printf(m, "commands:\tauto_enable, auto_disable\n");4930 seq_printf(m, "commands:\tvideo_switch, expand_toggle\n");4931 4932 return 0;4933}4934 4935static int video_write(char *buf)4936{4937 char *cmd;4938 int enable, disable, status;4939 int res;4940 4941 if (video_supported == TPACPI_VIDEO_NONE)4942 return -ENODEV;4943 4944 /* Even reads can crash X.org, let alone writes... */4945 if (!capable(CAP_SYS_ADMIN))4946 return -EPERM;4947 4948 enable = 0;4949 disable = 0;4950 4951 while ((cmd = strsep(&buf, ","))) {4952 if (strstarts(cmd, "lcd_enable")) {4953 enable |= TP_ACPI_VIDEO_S_LCD;4954 } else if (strstarts(cmd, "lcd_disable")) {4955 disable |= TP_ACPI_VIDEO_S_LCD;4956 } else if (strstarts(cmd, "crt_enable")) {4957 enable |= TP_ACPI_VIDEO_S_CRT;4958 } else if (strstarts(cmd, "crt_disable")) {4959 disable |= TP_ACPI_VIDEO_S_CRT;4960 } else if (video_supported == TPACPI_VIDEO_NEW &&4961 strstarts(cmd, "dvi_enable")) {4962 enable |= TP_ACPI_VIDEO_S_DVI;4963 } else if (video_supported == TPACPI_VIDEO_NEW &&4964 strstarts(cmd, "dvi_disable")) {4965 disable |= TP_ACPI_VIDEO_S_DVI;4966 } else if (strstarts(cmd, "auto_enable")) {4967 res = video_autosw_set(1);4968 if (res)4969 return res;4970 } else if (strstarts(cmd, "auto_disable")) {4971 res = video_autosw_set(0);4972 if (res)4973 return res;4974 } else if (strstarts(cmd, "video_switch")) {4975 res = video_outputsw_cycle();4976 if (res)4977 return res;4978 } else if (strstarts(cmd, "expand_toggle")) {4979 res = video_expand_toggle();4980 if (res)4981 return res;4982 } else4983 return -EINVAL;4984 }4985 4986 if (enable || disable) {4987 status = video_outputsw_get();4988 if (status < 0)4989 return status;4990 res = video_outputsw_set((status & ~disable) | enable);4991 if (res)4992 return res;4993 }4994 4995 return 0;4996}4997 4998static struct ibm_struct video_driver_data = {4999 .name = "video",5000 .read = video_read,5001 .write = video_write,5002 .exit = video_exit,5003};5004 5005#endif /* CONFIG_THINKPAD_ACPI_VIDEO */5006 5007/*************************************************************************5008 * Keyboard backlight subdriver5009 */5010 5011static enum led_brightness kbdlight_brightness;5012static DEFINE_MUTEX(kbdlight_mutex);5013 5014static int kbdlight_set_level(int level)5015{5016 int ret = 0;5017 5018 if (!hkey_handle)5019 return -ENXIO;5020 5021 mutex_lock(&kbdlight_mutex);5022 5023 if (!acpi_evalf(hkey_handle, NULL, "MLCS", "dd", level))5024 ret = -EIO;5025 else5026 kbdlight_brightness = level;5027 5028 mutex_unlock(&kbdlight_mutex);5029 5030 return ret;5031}5032 5033static int kbdlight_get_level(void)5034{5035 int status = 0;5036 5037 if (!hkey_handle)5038 return -ENXIO;5039 5040 if (!acpi_evalf(hkey_handle, &status, "MLCG", "dd", 0))5041 return -EIO;5042 5043 if (status < 0)5044 return status;5045 5046 return status & 0x3;5047}5048 5049static bool kbdlight_is_supported(void)5050{5051 int status = 0;5052 5053 if (!hkey_handle)5054 return false;5055 5056 if (!acpi_has_method(hkey_handle, "MLCG")) {5057 vdbg_printk(TPACPI_DBG_INIT, "kbdlight MLCG is unavailable\n");5058 return false;5059 }5060 5061 if (!acpi_evalf(hkey_handle, &status, "MLCG", "qdd", 0)) {5062 vdbg_printk(TPACPI_DBG_INIT, "kbdlight MLCG failed\n");5063 return false;5064 }5065 5066 if (status < 0) {5067 vdbg_printk(TPACPI_DBG_INIT, "kbdlight MLCG err: %d\n", status);5068 return false;5069 }5070 5071 vdbg_printk(TPACPI_DBG_INIT, "kbdlight MLCG returned 0x%x\n", status);5072 /*5073 * Guessed test for keyboard backlight:5074 *5075 * Machines with backlight keyboard return:5076 * b010100000010000000XX - ThinkPad X1 Carbon 3rd5077 * b110100010010000000XX - ThinkPad x2305078 * b010100000010000000XX - ThinkPad x2405079 * b010100000010000000XX - ThinkPad W5415080 * (XX is current backlight level)5081 *5082 * Machines without backlight keyboard return:5083 * b10100001000000000000 - ThinkPad x2305084 * b10110001000000000000 - ThinkPad E4305085 * b00000000000000000000 - ThinkPad E4505086 *5087 * Candidate BITs for detection test (XOR):5088 * b010000000010000000005089 * ^5090 */5091 return status & BIT(9);5092}5093 5094static int kbdlight_sysfs_set(struct led_classdev *led_cdev,5095 enum led_brightness brightness)5096{5097 return kbdlight_set_level(brightness);5098}5099 5100static enum led_brightness kbdlight_sysfs_get(struct led_classdev *led_cdev)5101{5102 int level;5103 5104 level = kbdlight_get_level();5105 if (level < 0)5106 return 0;5107 5108 return level;5109}5110 5111static struct tpacpi_led_classdev tpacpi_led_kbdlight = {5112 .led_classdev = {5113 .name = "tpacpi::kbd_backlight",5114 .max_brightness = 2,5115 .flags = LED_BRIGHT_HW_CHANGED,5116 .brightness_set_blocking = &kbdlight_sysfs_set,5117 .brightness_get = &kbdlight_sysfs_get,5118 }5119};5120 5121static int __init kbdlight_init(struct ibm_init_struct *iibm)5122{5123 int rc;5124 5125 vdbg_printk(TPACPI_DBG_INIT, "initializing kbdlight subdriver\n");5126 5127 TPACPI_ACPIHANDLE_INIT(hkey);5128 5129 if (!kbdlight_is_supported()) {5130 tp_features.kbdlight = 0;5131 vdbg_printk(TPACPI_DBG_INIT, "kbdlight is unsupported\n");5132 return -ENODEV;5133 }5134 5135 kbdlight_brightness = kbdlight_sysfs_get(NULL);5136 tp_features.kbdlight = 1;5137 5138 rc = led_classdev_register(&tpacpi_pdev->dev,5139 &tpacpi_led_kbdlight.led_classdev);5140 if (rc < 0) {5141 tp_features.kbdlight = 0;5142 return rc;5143 }5144 5145 tpacpi_hotkey_driver_mask_set(hotkey_driver_mask |5146 TP_ACPI_HKEY_KBD_LIGHT_MASK);5147 return 0;5148}5149 5150static void kbdlight_exit(void)5151{5152 led_classdev_unregister(&tpacpi_led_kbdlight.led_classdev);5153}5154 5155static int kbdlight_set_level_and_update(int level)5156{5157 int ret;5158 struct led_classdev *led_cdev;5159 5160 ret = kbdlight_set_level(level);5161 led_cdev = &tpacpi_led_kbdlight.led_classdev;5162 5163 if (ret == 0 && !(led_cdev->flags & LED_SUSPENDED))5164 led_cdev->brightness = level;5165 5166 return ret;5167}5168 5169static int kbdlight_read(struct seq_file *m)5170{5171 int level;5172 5173 if (!tp_features.kbdlight) {5174 seq_printf(m, "status:\t\tnot supported\n");5175 } else {5176 level = kbdlight_get_level();5177 if (level < 0)5178 seq_printf(m, "status:\t\terror %d\n", level);5179 else5180 seq_printf(m, "status:\t\t%d\n", level);5181 seq_printf(m, "commands:\t0, 1, 2\n");5182 }5183 5184 return 0;5185}5186 5187static int kbdlight_write(char *buf)5188{5189 char *cmd;5190 int res, level = -EINVAL;5191 5192 if (!tp_features.kbdlight)5193 return -ENODEV;5194 5195 while ((cmd = strsep(&buf, ","))) {5196 res = kstrtoint(cmd, 10, &level);5197 if (res < 0)5198 return res;5199 }5200 5201 if (level >= 3 || level < 0)5202 return -EINVAL;5203 5204 return kbdlight_set_level_and_update(level);5205}5206 5207static void kbdlight_suspend(void)5208{5209 struct led_classdev *led_cdev;5210 5211 if (!tp_features.kbdlight)5212 return;5213 5214 led_cdev = &tpacpi_led_kbdlight.led_classdev;5215 led_update_brightness(led_cdev);5216 led_classdev_suspend(led_cdev);5217}5218 5219static void kbdlight_resume(void)5220{5221 if (!tp_features.kbdlight)5222 return;5223 5224 led_classdev_resume(&tpacpi_led_kbdlight.led_classdev);5225}5226 5227static struct ibm_struct kbdlight_driver_data = {5228 .name = "kbdlight",5229 .read = kbdlight_read,5230 .write = kbdlight_write,5231 .suspend = kbdlight_suspend,5232 .resume = kbdlight_resume,5233 .exit = kbdlight_exit,5234};5235 5236/*************************************************************************5237 * Light (thinklight) subdriver5238 */5239 5240TPACPI_HANDLE(lght, root, "\\LGHT"); /* A21e, A2xm/p, T20-22, X20-21 */5241TPACPI_HANDLE(ledb, ec, "LEDB"); /* G4x */5242 5243static int light_get_status(void)5244{5245 int status = 0;5246 5247 if (tp_features.light_status) {5248 if (!acpi_evalf(ec_handle, &status, "KBLT", "d"))5249 return -EIO;5250 return (!!status);5251 }5252 5253 return -ENXIO;5254}5255 5256static int light_set_status(int status)5257{5258 int rc;5259 5260 if (tp_features.light) {5261 if (cmos_handle) {5262 rc = acpi_evalf(cmos_handle, NULL, NULL, "vd",5263 (status) ?5264 TP_CMOS_THINKLIGHT_ON :5265 TP_CMOS_THINKLIGHT_OFF);5266 } else {5267 rc = acpi_evalf(lght_handle, NULL, NULL, "vd",5268 (status) ? 1 : 0);5269 }5270 return (rc) ? 0 : -EIO;5271 }5272 5273 return -ENXIO;5274}5275 5276static int light_sysfs_set(struct led_classdev *led_cdev,5277 enum led_brightness brightness)5278{5279 return light_set_status((brightness != LED_OFF) ?5280 TPACPI_LED_ON : TPACPI_LED_OFF);5281}5282 5283static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev)5284{5285 return (light_get_status() == 1) ? LED_ON : LED_OFF;5286}5287 5288static struct tpacpi_led_classdev tpacpi_led_thinklight = {5289 .led_classdev = {5290 .name = "tpacpi::thinklight",5291 .max_brightness = 1,5292 .brightness_set_blocking = &light_sysfs_set,5293 .brightness_get = &light_sysfs_get,5294 }5295};5296 5297static int __init light_init(struct ibm_init_struct *iibm)5298{5299 int rc;5300 5301 vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");5302 5303 if (tpacpi_is_ibm()) {5304 TPACPI_ACPIHANDLE_INIT(ledb);5305 TPACPI_ACPIHANDLE_INIT(lght);5306 }5307 TPACPI_ACPIHANDLE_INIT(cmos);5308 5309 /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */5310 tp_features.light = (cmos_handle || lght_handle) && !ledb_handle;5311 5312 if (tp_features.light)5313 /* light status not supported on5314 570, 600e/x, 770e, 770x, G4x, R30, R31, R32, X20 */5315 tp_features.light_status =5316 acpi_evalf(ec_handle, NULL, "KBLT", "qv");5317 5318 vdbg_printk(TPACPI_DBG_INIT, "light is %s, light status is %s\n",5319 str_supported(tp_features.light),5320 str_supported(tp_features.light_status));5321 5322 if (!tp_features.light)5323 return -ENODEV;5324 5325 rc = led_classdev_register(&tpacpi_pdev->dev,5326 &tpacpi_led_thinklight.led_classdev);5327 5328 if (rc < 0) {5329 tp_features.light = 0;5330 tp_features.light_status = 0;5331 } else {5332 rc = 0;5333 }5334 5335 return rc;5336}5337 5338static void light_exit(void)5339{5340 led_classdev_unregister(&tpacpi_led_thinklight.led_classdev);5341}5342 5343static int light_read(struct seq_file *m)5344{5345 int status;5346 5347 if (!tp_features.light) {5348 seq_printf(m, "status:\t\tnot supported\n");5349 } else if (!tp_features.light_status) {5350 seq_printf(m, "status:\t\tunknown\n");5351 seq_printf(m, "commands:\ton, off\n");5352 } else {5353 status = light_get_status();5354 if (status < 0)5355 return status;5356 seq_printf(m, "status:\t\t%s\n", str_on_off(status & BIT(0)));5357 seq_printf(m, "commands:\ton, off\n");5358 }5359 5360 return 0;5361}5362 5363static int light_write(char *buf)5364{5365 char *cmd;5366 int newstatus = 0;5367 5368 if (!tp_features.light)5369 return -ENODEV;5370 5371 while ((cmd = strsep(&buf, ","))) {5372 if (strstarts(cmd, "on")) {5373 newstatus = 1;5374 } else if (strstarts(cmd, "off")) {5375 newstatus = 0;5376 } else5377 return -EINVAL;5378 }5379 5380 return light_set_status(newstatus);5381}5382 5383static struct ibm_struct light_driver_data = {5384 .name = "light",5385 .read = light_read,5386 .write = light_write,5387 .exit = light_exit,5388};5389 5390/*************************************************************************5391 * CMOS subdriver5392 */5393 5394/* sysfs cmos_command -------------------------------------------------- */5395static ssize_t cmos_command_store(struct device *dev,5396 struct device_attribute *attr,5397 const char *buf, size_t count)5398{5399 unsigned long cmos_cmd;5400 int res;5401 5402 if (parse_strtoul(buf, 21, &cmos_cmd))5403 return -EINVAL;5404 5405 res = issue_thinkpad_cmos_command(cmos_cmd);5406 return (res) ? res : count;5407}5408 5409static DEVICE_ATTR_WO(cmos_command);5410 5411static struct attribute *cmos_attributes[] = {5412 &dev_attr_cmos_command.attr,5413 NULL5414};5415 5416static umode_t cmos_attr_is_visible(struct kobject *kobj,5417 struct attribute *attr, int n)5418{5419 return cmos_handle ? attr->mode : 0;5420}5421 5422static const struct attribute_group cmos_attr_group = {5423 .is_visible = cmos_attr_is_visible,5424 .attrs = cmos_attributes,5425};5426 5427/* --------------------------------------------------------------------- */5428 5429static int __init cmos_init(struct ibm_init_struct *iibm)5430{5431 vdbg_printk(TPACPI_DBG_INIT,5432 "initializing cmos commands subdriver\n");5433 5434 TPACPI_ACPIHANDLE_INIT(cmos);5435 5436 vdbg_printk(TPACPI_DBG_INIT, "cmos commands are %s\n",5437 str_supported(cmos_handle != NULL));5438 5439 return cmos_handle ? 0 : -ENODEV;5440}5441 5442static int cmos_read(struct seq_file *m)5443{5444 /* cmos not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,5445 R30, R31, T20-22, X20-21 */5446 if (!cmos_handle)5447 seq_printf(m, "status:\t\tnot supported\n");5448 else {5449 seq_printf(m, "status:\t\tsupported\n");5450 seq_printf(m, "commands:\t<cmd> (<cmd> is 0-21)\n");5451 }5452 5453 return 0;5454}5455 5456static int cmos_write(char *buf)5457{5458 char *cmd;5459 int cmos_cmd, res;5460 5461 while ((cmd = strsep(&buf, ","))) {5462 if (sscanf(cmd, "%u", &cmos_cmd) == 1 &&5463 cmos_cmd >= 0 && cmos_cmd <= 21) {5464 /* cmos_cmd set */5465 } else5466 return -EINVAL;5467 5468 res = issue_thinkpad_cmos_command(cmos_cmd);5469 if (res)5470 return res;5471 }5472 5473 return 0;5474}5475 5476static struct ibm_struct cmos_driver_data = {5477 .name = "cmos",5478 .read = cmos_read,5479 .write = cmos_write,5480};5481 5482/*************************************************************************5483 * LED subdriver5484 */5485 5486enum led_access_mode {5487 TPACPI_LED_NONE = 0,5488 TPACPI_LED_570, /* 570 */5489 TPACPI_LED_OLD, /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */5490 TPACPI_LED_NEW, /* all others */5491};5492 5493enum { /* For TPACPI_LED_OLD */5494 TPACPI_LED_EC_HLCL = 0x0c, /* EC reg to get led to power on */5495 TPACPI_LED_EC_HLBL = 0x0d, /* EC reg to blink a lit led */5496 TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */5497};5498 5499static enum led_access_mode led_supported;5500 5501static acpi_handle led_handle;5502 5503#define TPACPI_LED_NUMLEDS 165504static struct tpacpi_led_classdev *tpacpi_leds;5505static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS];5506static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = {5507 /* there's a limit of 19 chars + NULL before 2.6.26 */5508 "tpacpi::power",5509 "tpacpi:orange:batt",5510 "tpacpi:green:batt",5511 "tpacpi::dock_active",5512 "tpacpi::bay_active",5513 "tpacpi::dock_batt",5514 "tpacpi::unknown_led",5515 "tpacpi::standby",5516 "tpacpi::dock_status1",5517 "tpacpi::dock_status2",5518 "tpacpi::lid_logo_dot",5519 "tpacpi::unknown_led3",5520 "tpacpi::thinkvantage",5521};5522#define TPACPI_SAFE_LEDS 0x1481U5523 5524static inline bool tpacpi_is_led_restricted(const unsigned int led)5525{5526#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS5527 return false;5528#else5529 return (1U & (TPACPI_SAFE_LEDS >> led)) == 0;5530#endif5531}5532 5533static int led_get_status(const unsigned int led)5534{5535 int status;5536 enum led_status_t led_s;5537 5538 switch (led_supported) {5539 case TPACPI_LED_570:5540 if (!acpi_evalf(ec_handle,5541 &status, "GLED", "dd", 1 << led))5542 return -EIO;5543 led_s = (status == 0) ?5544 TPACPI_LED_OFF :5545 ((status == 1) ?5546 TPACPI_LED_ON :5547 TPACPI_LED_BLINK);5548 tpacpi_led_state_cache[led] = led_s;5549 return led_s;5550 default:5551 return -ENXIO;5552 }5553 5554 /* not reached */5555}5556 5557static int led_set_status(const unsigned int led,5558 const enum led_status_t ledstatus)5559{5560 /* off, on, blink. Index is led_status_t */5561 static const unsigned int led_sled_arg1[] = { 0, 1, 3 };5562 static const unsigned int led_led_arg1[] = { 0, 0x80, 0xc0 };5563 5564 int rc = 0;5565 5566 switch (led_supported) {5567 case TPACPI_LED_570:5568 /* 570 */5569 if (unlikely(led > 7))5570 return -EINVAL;5571 if (unlikely(tpacpi_is_led_restricted(led)))5572 return -EPERM;5573 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",5574 (1 << led), led_sled_arg1[ledstatus]))5575 return -EIO;5576 break;5577 case TPACPI_LED_OLD:5578 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */5579 if (unlikely(led > 7))5580 return -EINVAL;5581 if (unlikely(tpacpi_is_led_restricted(led)))5582 return -EPERM;5583 rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led));5584 if (rc >= 0)5585 rc = ec_write(TPACPI_LED_EC_HLBL,5586 (ledstatus == TPACPI_LED_BLINK) << led);5587 if (rc >= 0)5588 rc = ec_write(TPACPI_LED_EC_HLCL,5589 (ledstatus != TPACPI_LED_OFF) << led);5590 break;5591 case TPACPI_LED_NEW:5592 /* all others */5593 if (unlikely(led >= TPACPI_LED_NUMLEDS))5594 return -EINVAL;5595 if (unlikely(tpacpi_is_led_restricted(led)))5596 return -EPERM;5597 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",5598 led, led_led_arg1[ledstatus]))5599 return -EIO;5600 break;5601 default:5602 return -ENXIO;5603 }5604 5605 if (!rc)5606 tpacpi_led_state_cache[led] = ledstatus;5607 5608 return rc;5609}5610 5611static int led_sysfs_set(struct led_classdev *led_cdev,5612 enum led_brightness brightness)5613{5614 struct tpacpi_led_classdev *data = container_of(led_cdev,5615 struct tpacpi_led_classdev, led_classdev);5616 enum led_status_t new_state;5617 5618 if (brightness == LED_OFF)5619 new_state = TPACPI_LED_OFF;5620 else if (tpacpi_led_state_cache[data->led] != TPACPI_LED_BLINK)5621 new_state = TPACPI_LED_ON;5622 else5623 new_state = TPACPI_LED_BLINK;5624 5625 return led_set_status(data->led, new_state);5626}5627 5628static int led_sysfs_blink_set(struct led_classdev *led_cdev,5629 unsigned long *delay_on, unsigned long *delay_off)5630{5631 struct tpacpi_led_classdev *data = container_of(led_cdev,5632 struct tpacpi_led_classdev, led_classdev);5633 5634 /* Can we choose the flash rate? */5635 if (*delay_on == 0 && *delay_off == 0) {5636 /* yes. set them to the hardware blink rate (1 Hz) */5637 *delay_on = 500; /* ms */5638 *delay_off = 500; /* ms */5639 } else if ((*delay_on != 500) || (*delay_off != 500))5640 return -EINVAL;5641 5642 return led_set_status(data->led, TPACPI_LED_BLINK);5643}5644 5645static enum led_brightness led_sysfs_get(struct led_classdev *led_cdev)5646{5647 int rc;5648 5649 struct tpacpi_led_classdev *data = container_of(led_cdev,5650 struct tpacpi_led_classdev, led_classdev);5651 5652 rc = led_get_status(data->led);5653 5654 if (rc == TPACPI_LED_OFF || rc < 0)5655 rc = LED_OFF; /* no error handling in led class :( */5656 else5657 rc = LED_FULL;5658 5659 return rc;5660}5661 5662static void led_exit(void)5663{5664 unsigned int i;5665 5666 for (i = 0; i < TPACPI_LED_NUMLEDS; i++)5667 led_classdev_unregister(&tpacpi_leds[i].led_classdev);5668 5669 kfree(tpacpi_leds);5670}5671 5672static int __init tpacpi_init_led(unsigned int led)5673{5674 /* LEDs with no name don't get registered */5675 if (!tpacpi_led_names[led])5676 return 0;5677 5678 tpacpi_leds[led].led_classdev.brightness_set_blocking = &led_sysfs_set;5679 tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set;5680 if (led_supported == TPACPI_LED_570)5681 tpacpi_leds[led].led_classdev.brightness_get = &led_sysfs_get;5682 5683 tpacpi_leds[led].led_classdev.name = tpacpi_led_names[led];5684 tpacpi_leds[led].led_classdev.flags = LED_RETAIN_AT_SHUTDOWN;5685 tpacpi_leds[led].led = led;5686 5687 return led_classdev_register(&tpacpi_pdev->dev, &tpacpi_leds[led].led_classdev);5688}5689 5690static const struct tpacpi_quirk led_useful_qtable[] __initconst = {5691 TPACPI_Q_IBM('1', 'E', 0x009f), /* A30 */5692 TPACPI_Q_IBM('1', 'N', 0x009f), /* A31 */5693 TPACPI_Q_IBM('1', 'G', 0x009f), /* A31 */5694 5695 TPACPI_Q_IBM('1', 'I', 0x0097), /* T30 */5696 TPACPI_Q_IBM('1', 'R', 0x0097), /* T40, T41, T42, R50, R51 */5697 TPACPI_Q_IBM('7', '0', 0x0097), /* T43, R52 */5698 TPACPI_Q_IBM('1', 'Y', 0x0097), /* T43 */5699 TPACPI_Q_IBM('1', 'W', 0x0097), /* R50e */5700 TPACPI_Q_IBM('1', 'V', 0x0097), /* R51 */5701 TPACPI_Q_IBM('7', '8', 0x0097), /* R51e */5702 TPACPI_Q_IBM('7', '6', 0x0097), /* R52 */5703 5704 TPACPI_Q_IBM('1', 'K', 0x00bf), /* X30 */5705 TPACPI_Q_IBM('1', 'Q', 0x00bf), /* X31, X32 */5706 TPACPI_Q_IBM('1', 'U', 0x00bf), /* X40 */5707 TPACPI_Q_IBM('7', '4', 0x00bf), /* X41 */5708 TPACPI_Q_IBM('7', '5', 0x00bf), /* X41t */5709 5710 TPACPI_Q_IBM('7', '9', 0x1f97), /* T60 (1) */5711 TPACPI_Q_IBM('7', '7', 0x1f97), /* Z60* (1) */5712 TPACPI_Q_IBM('7', 'F', 0x1f97), /* Z61* (1) */5713 TPACPI_Q_IBM('7', 'B', 0x1fb7), /* X60 (1) */5714 5715 /* (1) - may have excess leds enabled on MSB */5716 5717 /* Defaults (order matters, keep last, don't reorder!) */5718 { /* Lenovo */5719 .vendor = PCI_VENDOR_ID_LENOVO,5720 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,5721 .quirks = 0x1fffU,5722 },5723 { /* IBM ThinkPads with no EC version string */5724 .vendor = PCI_VENDOR_ID_IBM,5725 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_UNKNOWN,5726 .quirks = 0x00ffU,5727 },5728 { /* IBM ThinkPads with EC version string */5729 .vendor = PCI_VENDOR_ID_IBM,5730 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,5731 .quirks = 0x00bfU,5732 },5733};5734 5735static enum led_access_mode __init led_init_detect_mode(void)5736{5737 acpi_status status;5738 5739 if (tpacpi_is_ibm()) {5740 /* 570 */5741 status = acpi_get_handle(ec_handle, "SLED", &led_handle);5742 if (ACPI_SUCCESS(status))5743 return TPACPI_LED_570;5744 5745 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */5746 status = acpi_get_handle(ec_handle, "SYSL", &led_handle);5747 if (ACPI_SUCCESS(status))5748 return TPACPI_LED_OLD;5749 }5750 5751 /* most others */5752 status = acpi_get_handle(ec_handle, "LED", &led_handle);5753 if (ACPI_SUCCESS(status))5754 return TPACPI_LED_NEW;5755 5756 /* R30, R31, and unknown firmwares */5757 led_handle = NULL;5758 return TPACPI_LED_NONE;5759}5760 5761static int __init led_init(struct ibm_init_struct *iibm)5762{5763 unsigned int i;5764 int rc;5765 unsigned long useful_leds;5766 5767 vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");5768 5769 led_supported = led_init_detect_mode();5770 5771 if (led_supported != TPACPI_LED_NONE) {5772 useful_leds = tpacpi_check_quirks(led_useful_qtable,5773 ARRAY_SIZE(led_useful_qtable));5774 5775 if (!useful_leds) {5776 led_handle = NULL;5777 led_supported = TPACPI_LED_NONE;5778 }5779 }5780 5781 vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n",5782 str_supported(led_supported), led_supported);5783 5784 if (led_supported == TPACPI_LED_NONE)5785 return -ENODEV;5786 5787 tpacpi_leds = kcalloc(TPACPI_LED_NUMLEDS, sizeof(*tpacpi_leds),5788 GFP_KERNEL);5789 if (!tpacpi_leds) {5790 pr_err("Out of memory for LED data\n");5791 return -ENOMEM;5792 }5793 5794 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {5795 tpacpi_leds[i].led = -1;5796 5797 if (!tpacpi_is_led_restricted(i) && test_bit(i, &useful_leds)) {5798 rc = tpacpi_init_led(i);5799 if (rc < 0) {5800 led_exit();5801 return rc;5802 }5803 }5804 }5805 5806#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS5807 pr_notice("warning: userspace override of important firmware LEDs is enabled\n");5808#endif5809 return 0;5810}5811 5812#define str_led_status(s) ((s) >= TPACPI_LED_BLINK ? "blinking" : str_on_off(s))5813 5814static int led_read(struct seq_file *m)5815{5816 if (!led_supported) {5817 seq_printf(m, "status:\t\tnot supported\n");5818 return 0;5819 }5820 seq_printf(m, "status:\t\tsupported\n");5821 5822 if (led_supported == TPACPI_LED_570) {5823 /* 570 */5824 int i, status;5825 for (i = 0; i < 8; i++) {5826 status = led_get_status(i);5827 if (status < 0)5828 return -EIO;5829 seq_printf(m, "%d:\t\t%s\n", i, str_led_status(status));5830 }5831 }5832 5833 seq_printf(m, "commands:\t<led> on, <led> off, <led> blink (<led> is 0-15)\n");5834 5835 return 0;5836}5837 5838static int led_write(char *buf)5839{5840 char *cmd;5841 int led, rc;5842 enum led_status_t s;5843 5844 if (!led_supported)5845 return -ENODEV;5846 5847 while ((cmd = strsep(&buf, ","))) {5848 if (sscanf(cmd, "%d", &led) != 1)5849 return -EINVAL;5850 5851 if (led < 0 || led > (TPACPI_LED_NUMLEDS - 1))5852 return -ENODEV;5853 5854 if (tpacpi_leds[led].led < 0)5855 return -ENODEV;5856 5857 if (strstr(cmd, "off")) {5858 s = TPACPI_LED_OFF;5859 } else if (strstr(cmd, "on")) {5860 s = TPACPI_LED_ON;5861 } else if (strstr(cmd, "blink")) {5862 s = TPACPI_LED_BLINK;5863 } else {5864 return -EINVAL;5865 }5866 5867 rc = led_set_status(led, s);5868 if (rc < 0)5869 return rc;5870 }5871 5872 return 0;5873}5874 5875static struct ibm_struct led_driver_data = {5876 .name = "led",5877 .read = led_read,5878 .write = led_write,5879 .exit = led_exit,5880};5881 5882/*************************************************************************5883 * Beep subdriver5884 */5885 5886TPACPI_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */5887 5888#define TPACPI_BEEP_Q1 0x00015889 5890static const struct tpacpi_quirk beep_quirk_table[] __initconst = {5891 TPACPI_Q_IBM('I', 'M', TPACPI_BEEP_Q1), /* 570 */5892 TPACPI_Q_IBM('I', 'U', TPACPI_BEEP_Q1), /* 570E - unverified */5893};5894 5895static int __init beep_init(struct ibm_init_struct *iibm)5896{5897 unsigned long quirks;5898 5899 vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n");5900 5901 TPACPI_ACPIHANDLE_INIT(beep);5902 5903 vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n",5904 str_supported(beep_handle != NULL));5905 5906 quirks = tpacpi_check_quirks(beep_quirk_table,5907 ARRAY_SIZE(beep_quirk_table));5908 5909 tp_features.beep_needs_two_args = !!(quirks & TPACPI_BEEP_Q1);5910 5911 return (beep_handle) ? 0 : -ENODEV;5912}5913 5914static int beep_read(struct seq_file *m)5915{5916 if (!beep_handle)5917 seq_printf(m, "status:\t\tnot supported\n");5918 else {5919 seq_printf(m, "status:\t\tsupported\n");5920 seq_printf(m, "commands:\t<cmd> (<cmd> is 0-17)\n");5921 }5922 5923 return 0;5924}5925 5926static int beep_write(char *buf)5927{5928 char *cmd;5929 int beep_cmd;5930 5931 if (!beep_handle)5932 return -ENODEV;5933 5934 while ((cmd = strsep(&buf, ","))) {5935 if (sscanf(cmd, "%u", &beep_cmd) == 1 &&5936 beep_cmd >= 0 && beep_cmd <= 17) {5937 /* beep_cmd set */5938 } else5939 return -EINVAL;5940 if (tp_features.beep_needs_two_args) {5941 if (!acpi_evalf(beep_handle, NULL, NULL, "vdd",5942 beep_cmd, 0))5943 return -EIO;5944 } else {5945 if (!acpi_evalf(beep_handle, NULL, NULL, "vd",5946 beep_cmd))5947 return -EIO;5948 }5949 }5950 5951 return 0;5952}5953 5954static struct ibm_struct beep_driver_data = {5955 .name = "beep",5956 .read = beep_read,5957 .write = beep_write,5958};5959 5960/*************************************************************************5961 * Thermal subdriver5962 */5963 5964enum thermal_access_mode {5965 TPACPI_THERMAL_NONE = 0, /* No thermal support */5966 TPACPI_THERMAL_ACPI_TMP07, /* Use ACPI TMP0-7 */5967 TPACPI_THERMAL_ACPI_UPDT, /* Use ACPI TMP0-7 with UPDT */5968 TPACPI_THERMAL_TPEC_8, /* Use ACPI EC regs, 8 sensors */5969 TPACPI_THERMAL_TPEC_12, /* Use ACPI EC regs, 12 sensors */5970 TPACPI_THERMAL_TPEC_16, /* Use ACPI EC regs, 16 sensors */5971};5972 5973enum { /* TPACPI_THERMAL_TPEC_* */5974 TP_EC_THERMAL_TMP0 = 0x78, /* ACPI EC regs TMP 0..7 */5975 TP_EC_THERMAL_TMP8 = 0xC0, /* ACPI EC regs TMP 8..15 */5976 TP_EC_THERMAL_TMP0_NS = 0xA8, /* ACPI EC Non-Standard regs TMP 0..7 */5977 TP_EC_THERMAL_TMP8_NS = 0xB8, /* ACPI EC Non-standard regs TMP 8..11 */5978 TP_EC_FUNCREV = 0xEF, /* ACPI EC Functional revision */5979 TP_EC_THERMAL_TMP_NA = -128, /* ACPI EC sensor not available */5980 5981 TPACPI_THERMAL_SENSOR_NA = -128000, /* Sensor not available */5982};5983 5984 5985#define TPACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */5986struct ibm_thermal_sensors_struct {5987 s32 temp[TPACPI_MAX_THERMAL_SENSORS];5988};5989 5990static const struct tpacpi_quirk thermal_quirk_table[] __initconst = {5991 /* Non-standard address for thermal registers on some ThinkPads */5992 TPACPI_Q_LNV3('R', '1', 'F', true), /* L13 Yoga Gen 2 */5993 TPACPI_Q_LNV3('N', '2', 'U', true), /* X13 Yoga Gen 2*/5994 TPACPI_Q_LNV3('R', '0', 'R', true), /* L380 */5995 TPACPI_Q_LNV3('R', '1', '5', true), /* L13 Yoga Gen 1*/5996 TPACPI_Q_LNV3('R', '1', '0', true), /* L390 */5997 TPACPI_Q_LNV3('N', '2', 'L', true), /* X13 Yoga Gen 1*/5998 TPACPI_Q_LNV3('R', '0', 'T', true), /* 11e Gen5 GL*/5999 TPACPI_Q_LNV3('R', '1', 'D', true), /* 11e Gen5 GL-R*/6000 TPACPI_Q_LNV3('R', '0', 'V', true), /* 11e Gen5 KL-Y*/6001};6002 6003static enum thermal_access_mode thermal_read_mode;6004static bool thermal_use_labels;6005static bool thermal_with_ns_address; /* Non-standard thermal reg address */6006 6007/* Function to check thermal read mode */6008static enum thermal_access_mode __init thermal_read_mode_check(void)6009{6010 u8 t, ta1, ta2, ver = 0;6011 int i;6012 int acpi_tmp7;6013 6014 acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");6015 6016 if (thinkpad_id.ec_model) {6017 /*6018 * Direct EC access mode: sensors at registers 0x78-0x7F,6019 * 0xC0-0xC7. Registers return 0x00 for non-implemented,6020 * thermal sensors return 0x80 when not available.6021 *6022 * In some special cases (when Power Supply ID is 0xC2)6023 * above rule causes thermal control issues. Offset 0xEF6024 * determines EC version. 0xC0-0xC7 are not thermal registers6025 * in Ver 3.6026 */6027 if (!acpi_ec_read(TP_EC_FUNCREV, &ver))6028 pr_warn("Thinkpad ACPI EC unable to access EC version\n");6029 6030 /* Quirks to check non-standard EC */6031 thermal_with_ns_address = tpacpi_check_quirks(thermal_quirk_table,6032 ARRAY_SIZE(thermal_quirk_table));6033 6034 /* Support for Thinkpads with non-standard address */6035 if (thermal_with_ns_address) {6036 pr_info("ECFW with non-standard thermal registers found\n");6037 return TPACPI_THERMAL_TPEC_12;6038 }6039 6040 ta1 = ta2 = 0;6041 for (i = 0; i < 8; i++) {6042 if (acpi_ec_read(TP_EC_THERMAL_TMP0 + i, &t)) {6043 ta1 |= t;6044 } else {6045 ta1 = 0;6046 break;6047 }6048 if (ver < 3) {6049 if (acpi_ec_read(TP_EC_THERMAL_TMP8 + i, &t)) {6050 ta2 |= t;6051 } else {6052 ta1 = 0;6053 break;6054 }6055 }6056 }6057 6058 if (ta1 == 0) {6059 /* This is sheer paranoia, but we handle it anyway */6060 if (acpi_tmp7) {6061 pr_err("ThinkPad ACPI EC access misbehaving, falling back to ACPI TMPx access mode\n");6062 return TPACPI_THERMAL_ACPI_TMP07;6063 }6064 pr_err("ThinkPad ACPI EC access misbehaving, disabling thermal sensors access\n");6065 return TPACPI_THERMAL_NONE;6066 }6067 6068 if (ver >= 3) {6069 thermal_use_labels = true;6070 return TPACPI_THERMAL_TPEC_8;6071 }6072 6073 return (ta2 != 0) ? TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8;6074 }6075 6076 if (acpi_tmp7) {6077 if (tpacpi_is_ibm() && acpi_evalf(ec_handle, NULL, "UPDT", "qv")) {6078 /* 600e/x, 770e, 770x */6079 return TPACPI_THERMAL_ACPI_UPDT;6080 }6081 /* IBM/LENOVO DSDT EC.TMPx access, max 8 sensors */6082 return TPACPI_THERMAL_ACPI_TMP07;6083 }6084 6085 /* temperatures not supported on 570, G4x, R30, R31, R32 */6086 return TPACPI_THERMAL_NONE;6087}6088 6089/* idx is zero-based */6090static int thermal_get_sensor(int idx, s32 *value)6091{6092 int t;6093 s8 tmp;6094 char tmpi[5];6095 6096 t = TP_EC_THERMAL_TMP0;6097 6098 switch (thermal_read_mode) {6099#if TPACPI_MAX_THERMAL_SENSORS >= 166100 case TPACPI_THERMAL_TPEC_16:6101 if (idx >= 8 && idx <= 15) {6102 t = TP_EC_THERMAL_TMP8;6103 idx -= 8;6104 }6105#endif6106 fallthrough;6107 case TPACPI_THERMAL_TPEC_8:6108 if (idx <= 7) {6109 if (!acpi_ec_read(t + idx, &tmp))6110 return -EIO;6111 *value = tmp * 1000;6112 return 0;6113 }6114 break;6115 6116 /* The Non-standard EC uses 12 Thermal areas */6117 case TPACPI_THERMAL_TPEC_12:6118 if (idx >= 12)6119 return -EINVAL;6120 6121 t = idx < 8 ? TP_EC_THERMAL_TMP0_NS + idx :6122 TP_EC_THERMAL_TMP8_NS + (idx - 8);6123 6124 if (!acpi_ec_read(t, &tmp))6125 return -EIO;6126 6127 *value = tmp * MILLIDEGREE_PER_DEGREE;6128 return 0;6129 6130 case TPACPI_THERMAL_ACPI_UPDT:6131 if (idx <= 7) {6132 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);6133 if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))6134 return -EIO;6135 if (!acpi_evalf(ec_handle, &t, tmpi, "d"))6136 return -EIO;6137 *value = (t - 2732) * 100;6138 return 0;6139 }6140 break;6141 6142 case TPACPI_THERMAL_ACPI_TMP07:6143 if (idx <= 7) {6144 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);6145 if (!acpi_evalf(ec_handle, &t, tmpi, "d"))6146 return -EIO;6147 if (t > 127 || t < -127)6148 t = TP_EC_THERMAL_TMP_NA;6149 *value = t * 1000;6150 return 0;6151 }6152 break;6153 6154 case TPACPI_THERMAL_NONE:6155 default:6156 return -ENOSYS;6157 }6158 6159 return -EINVAL;6160}6161 6162static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)6163{6164 int res, i, n;6165 6166 if (!s)6167 return -EINVAL;6168 6169 if (thermal_read_mode == TPACPI_THERMAL_TPEC_16)6170 n = 16;6171 else if (thermal_read_mode == TPACPI_THERMAL_TPEC_12)6172 n = 12;6173 else6174 n = 8;6175 6176 for (i = 0 ; i < n; i++) {6177 res = thermal_get_sensor(i, &s->temp[i]);6178 if (res)6179 return res;6180 }6181 6182 return n;6183}6184 6185static void thermal_dump_all_sensors(void)6186{6187 int n, i;6188 struct ibm_thermal_sensors_struct t;6189 6190 n = thermal_get_sensors(&t);6191 if (n <= 0)6192 return;6193 6194 pr_notice("temperatures (Celsius):");6195 6196 for (i = 0; i < n; i++) {6197 if (t.temp[i] != TPACPI_THERMAL_SENSOR_NA)6198 pr_cont(" %d", (int)(t.temp[i] / 1000));6199 else6200 pr_cont(" N/A");6201 }6202 6203 pr_cont("\n");6204}6205 6206/* sysfs temp##_input -------------------------------------------------- */6207 6208static ssize_t thermal_temp_input_show(struct device *dev,6209 struct device_attribute *attr,6210 char *buf)6211{6212 struct sensor_device_attribute *sensor_attr =6213 to_sensor_dev_attr(attr);6214 int idx = sensor_attr->index;6215 s32 value;6216 int res;6217 6218 res = thermal_get_sensor(idx, &value);6219 if (res)6220 return res;6221 if (value == TPACPI_THERMAL_SENSOR_NA)6222 return -ENXIO;6223 6224 return sysfs_emit(buf, "%d\n", value);6225}6226 6227#define THERMAL_SENSOR_ATTR_TEMP(_idxA, _idxB) \6228 SENSOR_ATTR(temp##_idxA##_input, S_IRUGO, \6229 thermal_temp_input_show, NULL, _idxB)6230 6231static struct sensor_device_attribute sensor_dev_attr_thermal_temp_input[] = {6232 THERMAL_SENSOR_ATTR_TEMP(1, 0),6233 THERMAL_SENSOR_ATTR_TEMP(2, 1),6234 THERMAL_SENSOR_ATTR_TEMP(3, 2),6235 THERMAL_SENSOR_ATTR_TEMP(4, 3),6236 THERMAL_SENSOR_ATTR_TEMP(5, 4),6237 THERMAL_SENSOR_ATTR_TEMP(6, 5),6238 THERMAL_SENSOR_ATTR_TEMP(7, 6),6239 THERMAL_SENSOR_ATTR_TEMP(8, 7),6240 THERMAL_SENSOR_ATTR_TEMP(9, 8),6241 THERMAL_SENSOR_ATTR_TEMP(10, 9),6242 THERMAL_SENSOR_ATTR_TEMP(11, 10),6243 THERMAL_SENSOR_ATTR_TEMP(12, 11),6244 THERMAL_SENSOR_ATTR_TEMP(13, 12),6245 THERMAL_SENSOR_ATTR_TEMP(14, 13),6246 THERMAL_SENSOR_ATTR_TEMP(15, 14),6247 THERMAL_SENSOR_ATTR_TEMP(16, 15),6248};6249 6250#define THERMAL_ATTRS(X) \6251 &sensor_dev_attr_thermal_temp_input[X].dev_attr.attr6252 6253static struct attribute *thermal_temp_input_attr[] = {6254 THERMAL_ATTRS(0),6255 THERMAL_ATTRS(1),6256 THERMAL_ATTRS(2),6257 THERMAL_ATTRS(3),6258 THERMAL_ATTRS(4),6259 THERMAL_ATTRS(5),6260 THERMAL_ATTRS(6),6261 THERMAL_ATTRS(7),6262 THERMAL_ATTRS(8),6263 THERMAL_ATTRS(9),6264 THERMAL_ATTRS(10),6265 THERMAL_ATTRS(11),6266 THERMAL_ATTRS(12),6267 THERMAL_ATTRS(13),6268 THERMAL_ATTRS(14),6269 THERMAL_ATTRS(15),6270 NULL6271};6272 6273#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)6274 6275static umode_t thermal_attr_is_visible(struct kobject *kobj,6276 struct attribute *attr, int n)6277{6278 struct device_attribute *dev_attr = to_dev_attr(attr);6279 struct sensor_device_attribute *sensor_attr =6280 to_sensor_dev_attr(dev_attr);6281 6282 int idx = sensor_attr->index;6283 6284 switch (thermal_read_mode) {6285 case TPACPI_THERMAL_NONE:6286 return 0;6287 6288 case TPACPI_THERMAL_ACPI_TMP07:6289 case TPACPI_THERMAL_ACPI_UPDT:6290 case TPACPI_THERMAL_TPEC_8:6291 if (idx >= 8)6292 return 0;6293 break;6294 6295 case TPACPI_THERMAL_TPEC_12:6296 if (idx >= 12)6297 return 0;6298 break;6299 6300 default:6301 break;6302 6303 }6304 6305 return attr->mode;6306}6307 6308static const struct attribute_group thermal_attr_group = {6309 .is_visible = thermal_attr_is_visible,6310 .attrs = thermal_temp_input_attr,6311};6312 6313#undef THERMAL_SENSOR_ATTR_TEMP6314#undef THERMAL_ATTRS6315 6316static ssize_t temp1_label_show(struct device *dev, struct device_attribute *attr, char *buf)6317{6318 return sysfs_emit(buf, "CPU\n");6319}6320static DEVICE_ATTR_RO(temp1_label);6321 6322static ssize_t temp2_label_show(struct device *dev, struct device_attribute *attr, char *buf)6323{6324 return sysfs_emit(buf, "GPU\n");6325}6326static DEVICE_ATTR_RO(temp2_label);6327 6328static struct attribute *temp_label_attributes[] = {6329 &dev_attr_temp1_label.attr,6330 &dev_attr_temp2_label.attr,6331 NULL6332};6333 6334static umode_t temp_label_attr_is_visible(struct kobject *kobj,6335 struct attribute *attr, int n)6336{6337 return thermal_use_labels ? attr->mode : 0;6338}6339 6340static const struct attribute_group temp_label_attr_group = {6341 .is_visible = temp_label_attr_is_visible,6342 .attrs = temp_label_attributes,6343};6344 6345/* --------------------------------------------------------------------- */6346 6347static int __init thermal_init(struct ibm_init_struct *iibm)6348{6349 vdbg_printk(TPACPI_DBG_INIT, "initializing thermal subdriver\n");6350 6351 thermal_read_mode = thermal_read_mode_check();6352 6353 vdbg_printk(TPACPI_DBG_INIT, "thermal is %s, mode %d\n",6354 str_supported(thermal_read_mode != TPACPI_THERMAL_NONE),6355 thermal_read_mode);6356 6357 return thermal_read_mode != TPACPI_THERMAL_NONE ? 0 : -ENODEV;6358}6359 6360static int thermal_read(struct seq_file *m)6361{6362 int n, i;6363 struct ibm_thermal_sensors_struct t;6364 6365 n = thermal_get_sensors(&t);6366 if (unlikely(n < 0))6367 return n;6368 6369 seq_printf(m, "temperatures:\t");6370 6371 if (n > 0) {6372 for (i = 0; i < (n - 1); i++)6373 seq_printf(m, "%d ", t.temp[i] / 1000);6374 seq_printf(m, "%d\n", t.temp[i] / 1000);6375 } else6376 seq_printf(m, "not supported\n");6377 6378 return 0;6379}6380 6381static struct ibm_struct thermal_driver_data = {6382 .name = "thermal",6383 .read = thermal_read,6384};6385 6386/*************************************************************************6387 * Backlight/brightness subdriver6388 */6389 6390#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"6391 6392/*6393 * ThinkPads can read brightness from two places: EC HBRV (0x31), or6394 * CMOS NVRAM byte 0x5E, bits 0-3.6395 *6396 * EC HBRV (0x31) has the following layout6397 * Bit 7: unknown function6398 * Bit 6: unknown function6399 * Bit 5: Z: honour scale changes, NZ: ignore scale changes6400 * Bit 4: must be set to zero to avoid problems6401 * Bit 3-0: backlight brightness level6402 *6403 * brightness_get_raw returns status data in the HBRV layout6404 *6405 * WARNING: The X61 has been verified to use HBRV for something else, so6406 * this should be used _only_ on IBM ThinkPads, and maybe with some careful6407 * testing on the very early *60 Lenovo models...6408 */6409 6410enum {6411 TP_EC_BACKLIGHT = 0x31,6412 6413 /* TP_EC_BACKLIGHT bitmasks */6414 TP_EC_BACKLIGHT_LVLMSK = 0x1F,6415 TP_EC_BACKLIGHT_CMDMSK = 0xE0,6416 TP_EC_BACKLIGHT_MAPSW = 0x20,6417};6418 6419enum tpacpi_brightness_access_mode {6420 TPACPI_BRGHT_MODE_AUTO = 0, /* Not implemented yet */6421 TPACPI_BRGHT_MODE_EC, /* EC control */6422 TPACPI_BRGHT_MODE_UCMS_STEP, /* UCMS step-based control */6423 TPACPI_BRGHT_MODE_ECNVRAM, /* EC control w/ NVRAM store */6424 TPACPI_BRGHT_MODE_MAX6425};6426 6427static struct backlight_device *ibm_backlight_device;6428 6429static enum tpacpi_brightness_access_mode brightness_mode =6430 TPACPI_BRGHT_MODE_MAX;6431 6432static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */6433 6434static struct mutex brightness_mutex;6435 6436/* NVRAM brightness access */6437static unsigned int tpacpi_brightness_nvram_get(void)6438{6439 u8 lnvram;6440 6441 lockdep_assert_held(&brightness_mutex);6442 6443 lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)6444 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)6445 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;6446 lnvram &= bright_maxlvl;6447 6448 return lnvram;6449}6450 6451static void tpacpi_brightness_checkpoint_nvram(void)6452{6453 u8 lec = 0;6454 u8 b_nvram;6455 6456 if (brightness_mode != TPACPI_BRGHT_MODE_ECNVRAM)6457 return;6458 6459 vdbg_printk(TPACPI_DBG_BRGHT,6460 "trying to checkpoint backlight level to NVRAM...\n");6461 6462 if (mutex_lock_killable(&brightness_mutex) < 0)6463 return;6464 6465 if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))6466 goto unlock;6467 lec &= TP_EC_BACKLIGHT_LVLMSK;6468 b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);6469 6470 if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)6471 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {6472 /* NVRAM needs update */6473 b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<6474 TP_NVRAM_POS_LEVEL_BRIGHTNESS);6475 b_nvram |= lec;6476 nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);6477 dbg_printk(TPACPI_DBG_BRGHT,6478 "updated NVRAM backlight level to %u (0x%02x)\n",6479 (unsigned int) lec, (unsigned int) b_nvram);6480 } else6481 vdbg_printk(TPACPI_DBG_BRGHT,6482 "NVRAM backlight level already is %u (0x%02x)\n",6483 (unsigned int) lec, (unsigned int) b_nvram);6484 6485unlock:6486 mutex_unlock(&brightness_mutex);6487}6488 6489 6490static int tpacpi_brightness_get_raw(int *status)6491{6492 u8 lec = 0;6493 6494 lockdep_assert_held(&brightness_mutex);6495 6496 switch (brightness_mode) {6497 case TPACPI_BRGHT_MODE_UCMS_STEP:6498 *status = tpacpi_brightness_nvram_get();6499 return 0;6500 case TPACPI_BRGHT_MODE_EC:6501 case TPACPI_BRGHT_MODE_ECNVRAM:6502 if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))6503 return -EIO;6504 *status = lec;6505 return 0;6506 default:6507 return -ENXIO;6508 }6509}6510 6511/* do NOT call with illegal backlight level value */6512static int tpacpi_brightness_set_ec(unsigned int value)6513{6514 u8 lec = 0;6515 6516 lockdep_assert_held(&brightness_mutex);6517 6518 if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))6519 return -EIO;6520 6521 if (unlikely(!acpi_ec_write(TP_EC_BACKLIGHT,6522 (lec & TP_EC_BACKLIGHT_CMDMSK) |6523 (value & TP_EC_BACKLIGHT_LVLMSK))))6524 return -EIO;6525 6526 return 0;6527}6528 6529static int tpacpi_brightness_set_ucmsstep(unsigned int value)6530{6531 int cmos_cmd, inc;6532 unsigned int current_value, i;6533 6534 lockdep_assert_held(&brightness_mutex);6535 6536 current_value = tpacpi_brightness_nvram_get();6537 6538 if (value == current_value)6539 return 0;6540 6541 cmos_cmd = (value > current_value) ?6542 TP_CMOS_BRIGHTNESS_UP :6543 TP_CMOS_BRIGHTNESS_DOWN;6544 inc = (value > current_value) ? 1 : -1;6545 6546 for (i = current_value; i != value; i += inc)6547 if (issue_thinkpad_cmos_command(cmos_cmd))6548 return -EIO;6549 6550 return 0;6551}6552 6553/* May return EINTR which can always be mapped to ERESTARTSYS */6554static int brightness_set(unsigned int value)6555{6556 int res;6557 6558 if (value > bright_maxlvl)6559 return -EINVAL;6560 6561 vdbg_printk(TPACPI_DBG_BRGHT,6562 "set backlight level to %d\n", value);6563 6564 res = mutex_lock_killable(&brightness_mutex);6565 if (res < 0)6566 return res;6567 6568 switch (brightness_mode) {6569 case TPACPI_BRGHT_MODE_EC:6570 case TPACPI_BRGHT_MODE_ECNVRAM:6571 res = tpacpi_brightness_set_ec(value);6572 break;6573 case TPACPI_BRGHT_MODE_UCMS_STEP:6574 res = tpacpi_brightness_set_ucmsstep(value);6575 break;6576 default:6577 res = -ENXIO;6578 }6579 6580 mutex_unlock(&brightness_mutex);6581 return res;6582}6583 6584/* sysfs backlight class ----------------------------------------------- */6585 6586static int brightness_update_status(struct backlight_device *bd)6587{6588 int level = backlight_get_brightness(bd);6589 6590 dbg_printk(TPACPI_DBG_BRGHT,6591 "backlight: attempt to set level to %d\n",6592 level);6593 6594 /* it is the backlight class's job (caller) to handle6595 * EINTR and other errors properly */6596 return brightness_set(level);6597}6598 6599static int brightness_get(struct backlight_device *bd)6600{6601 int status, res;6602 6603 res = mutex_lock_killable(&brightness_mutex);6604 if (res < 0)6605 return 0;6606 6607 res = tpacpi_brightness_get_raw(&status);6608 6609 mutex_unlock(&brightness_mutex);6610 6611 if (res < 0)6612 return 0;6613 6614 return status & TP_EC_BACKLIGHT_LVLMSK;6615}6616 6617static void tpacpi_brightness_notify_change(void)6618{6619 backlight_force_update(ibm_backlight_device,6620 BACKLIGHT_UPDATE_HOTKEY);6621}6622 6623static const struct backlight_ops ibm_backlight_data = {6624 .get_brightness = brightness_get,6625 .update_status = brightness_update_status,6626};6627 6628/* --------------------------------------------------------------------- */6629 6630static int __init tpacpi_evaluate_bcl(struct acpi_device *adev, void *not_used)6631{6632 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };6633 union acpi_object *obj;6634 acpi_status status;6635 int rc;6636 6637 status = acpi_evaluate_object(adev->handle, "_BCL", NULL, &buffer);6638 if (ACPI_FAILURE(status))6639 return 0;6640 6641 obj = buffer.pointer;6642 if (!obj || obj->type != ACPI_TYPE_PACKAGE) {6643 acpi_handle_info(adev->handle,6644 "Unknown _BCL data, please report this to %s\n",6645 TPACPI_MAIL);6646 rc = 0;6647 } else {6648 rc = obj->package.count;6649 }6650 kfree(obj);6651 6652 return rc;6653}6654 6655/*6656 * Call _BCL method of video device. On some ThinkPads this will6657 * switch the firmware to the ACPI brightness control mode.6658 */6659 6660static int __init tpacpi_query_bcl_levels(acpi_handle handle)6661{6662 struct acpi_device *device;6663 6664 device = acpi_fetch_acpi_dev(handle);6665 if (!device)6666 return 0;6667 6668 return acpi_dev_for_each_child(device, tpacpi_evaluate_bcl, NULL);6669}6670 6671 6672/*6673 * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map6674 */6675static unsigned int __init tpacpi_check_std_acpi_brightness_support(void)6676{6677 acpi_handle video_device;6678 int bcl_levels = 0;6679 6680 tpacpi_acpi_handle_locate("video", NULL, &video_device);6681 if (video_device)6682 bcl_levels = tpacpi_query_bcl_levels(video_device);6683 6684 tp_features.bright_acpimode = (bcl_levels > 0);6685 6686 return (bcl_levels > 2) ? (bcl_levels - 2) : 0;6687}6688 6689/*6690 * These are only useful for models that have only one possibility6691 * of GPU. If the BIOS model handles both ATI and Intel, don't use6692 * these quirks.6693 */6694#define TPACPI_BRGHT_Q_NOEC 0x0001 /* Must NOT use EC HBRV */6695#define TPACPI_BRGHT_Q_EC 0x0002 /* Should or must use EC HBRV */6696#define TPACPI_BRGHT_Q_ASK 0x8000 /* Ask for user report */6697 6698static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {6699 /* Models with ATI GPUs known to require ECNVRAM mode */6700 TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */6701 6702 /* Models with ATI GPUs that can use ECNVRAM */6703 TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC), /* R50,51 T40-42 */6704 TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),6705 TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_EC), /* R52 */6706 TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),6707 6708 /* Models with Intel Extreme Graphics 2 */6709 TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), /* X40 */6710 TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),6711 TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),6712 6713 /* Models with Intel GMA900 */6714 TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */6715 TPACPI_Q_IBM('7', '4', TPACPI_BRGHT_Q_NOEC), /* X41 */6716 TPACPI_Q_IBM('7', '5', TPACPI_BRGHT_Q_NOEC), /* X41 Tablet */6717};6718 6719/*6720 * Returns < 0 for error, otherwise sets tp_features.bright_*6721 * and bright_maxlvl.6722 */6723static void __init tpacpi_detect_brightness_capabilities(void)6724{6725 unsigned int b;6726 6727 vdbg_printk(TPACPI_DBG_INIT,6728 "detecting firmware brightness interface capabilities\n");6729 6730 /* we could run a quirks check here (same table used by6731 * brightness_init) if needed */6732 6733 /*6734 * We always attempt to detect acpi support, so as to switch6735 * Lenovo Vista BIOS to ACPI brightness mode even if we are not6736 * going to publish a backlight interface6737 */6738 b = tpacpi_check_std_acpi_brightness_support();6739 switch (b) {6740 case 16:6741 bright_maxlvl = 15;6742 break;6743 case 8:6744 case 0:6745 bright_maxlvl = 7;6746 break;6747 default:6748 tp_features.bright_unkfw = 1;6749 bright_maxlvl = b - 1;6750 }6751 pr_debug("detected %u brightness levels\n", bright_maxlvl + 1);6752}6753 6754static int __init brightness_init(struct ibm_init_struct *iibm)6755{6756 struct backlight_properties props;6757 int b;6758 unsigned long quirks;6759 6760 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");6761 6762 mutex_init(&brightness_mutex);6763 6764 quirks = tpacpi_check_quirks(brightness_quirk_table,6765 ARRAY_SIZE(brightness_quirk_table));6766 6767 /* tpacpi_detect_brightness_capabilities() must have run already */6768 6769 /* if it is unknown, we don't handle it: it wouldn't be safe */6770 if (tp_features.bright_unkfw)6771 return -ENODEV;6772 6773 if (!brightness_enable) {6774 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,6775 "brightness support disabled by module parameter\n");6776 return -ENODEV;6777 }6778 6779 if (acpi_video_get_backlight_type() != acpi_backlight_vendor) {6780 if (brightness_enable > 1) {6781 pr_info("Standard ACPI backlight interface available, not loading native one\n");6782 return -ENODEV;6783 } else if (brightness_enable == 1) {6784 pr_warn("Cannot enable backlight brightness support, ACPI is already handling it. Refer to the acpi_backlight kernel parameter.\n");6785 return -ENODEV;6786 }6787 } else if (!tp_features.bright_acpimode) {6788 pr_notice("ACPI backlight interface not available\n");6789 return -ENODEV;6790 }6791 6792 pr_notice("ACPI native brightness control enabled\n");6793 6794 /*6795 * Check for module parameter bogosity, note that we6796 * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be6797 * able to detect "unspecified"6798 */6799 if (brightness_mode > TPACPI_BRGHT_MODE_MAX)6800 return -EINVAL;6801 6802 /* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */6803 if (brightness_mode == TPACPI_BRGHT_MODE_AUTO ||6804 brightness_mode == TPACPI_BRGHT_MODE_MAX) {6805 if (quirks & TPACPI_BRGHT_Q_EC)6806 brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;6807 else6808 brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;6809 6810 dbg_printk(TPACPI_DBG_BRGHT,6811 "driver auto-selected brightness_mode=%d\n",6812 brightness_mode);6813 }6814 6815 /* Safety */6816 if (!tpacpi_is_ibm() &&6817 (brightness_mode == TPACPI_BRGHT_MODE_ECNVRAM ||6818 brightness_mode == TPACPI_BRGHT_MODE_EC))6819 return -EINVAL;6820 6821 if (tpacpi_brightness_get_raw(&b) < 0)6822 return -ENODEV;6823 6824 memset(&props, 0, sizeof(struct backlight_properties));6825 props.type = BACKLIGHT_PLATFORM;6826 props.max_brightness = bright_maxlvl;6827 props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;6828 ibm_backlight_device = backlight_device_register(TPACPI_BACKLIGHT_DEV_NAME,6829 NULL, NULL,6830 &ibm_backlight_data,6831 &props);6832 if (IS_ERR(ibm_backlight_device)) {6833 int rc = PTR_ERR(ibm_backlight_device);6834 ibm_backlight_device = NULL;6835 pr_err("Could not register backlight device\n");6836 return rc;6837 }6838 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,6839 "brightness is supported\n");6840 6841 if (quirks & TPACPI_BRGHT_Q_ASK) {6842 pr_notice("brightness: will use unverified default: brightness_mode=%d\n",6843 brightness_mode);6844 pr_notice("brightness: please report to %s whether it works well or not on your ThinkPad\n",6845 TPACPI_MAIL);6846 }6847 6848 /* Added by mistake in early 2007. Probably useless, but it could6849 * be working around some unknown firmware problem where the value6850 * read at startup doesn't match the real hardware state... so leave6851 * it in place just in case */6852 backlight_update_status(ibm_backlight_device);6853 6854 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,6855 "brightness: registering brightness hotkeys as change notification\n");6856 tpacpi_hotkey_driver_mask_set(hotkey_driver_mask6857 | TP_ACPI_HKEY_BRGHTUP_MASK6858 | TP_ACPI_HKEY_BRGHTDWN_MASK);6859 return 0;6860}6861 6862static void brightness_suspend(void)6863{6864 tpacpi_brightness_checkpoint_nvram();6865}6866 6867static void brightness_shutdown(void)6868{6869 tpacpi_brightness_checkpoint_nvram();6870}6871 6872static void brightness_exit(void)6873{6874 if (ibm_backlight_device) {6875 vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_BRGHT,6876 "calling backlight_device_unregister()\n");6877 backlight_device_unregister(ibm_backlight_device);6878 }6879 6880 tpacpi_brightness_checkpoint_nvram();6881}6882 6883static int brightness_read(struct seq_file *m)6884{6885 int level;6886 6887 level = brightness_get(NULL);6888 if (level < 0) {6889 seq_printf(m, "level:\t\tunreadable\n");6890 } else {6891 seq_printf(m, "level:\t\t%d\n", level);6892 seq_printf(m, "commands:\tup, down\n");6893 seq_printf(m, "commands:\tlevel <level> (<level> is 0-%d)\n",6894 bright_maxlvl);6895 }6896 6897 return 0;6898}6899 6900static int brightness_write(char *buf)6901{6902 int level;6903 int rc;6904 char *cmd;6905 6906 level = brightness_get(NULL);6907 if (level < 0)6908 return level;6909 6910 while ((cmd = strsep(&buf, ","))) {6911 if (strstarts(cmd, "up")) {6912 if (level < bright_maxlvl)6913 level++;6914 } else if (strstarts(cmd, "down")) {6915 if (level > 0)6916 level--;6917 } else if (sscanf(cmd, "level %d", &level) == 1 &&6918 level >= 0 && level <= bright_maxlvl) {6919 /* new level set */6920 } else6921 return -EINVAL;6922 }6923 6924 tpacpi_disclose_usertask("procfs brightness",6925 "set level to %d\n", level);6926 6927 /*6928 * Now we know what the final level should be, so we try to set it.6929 * Doing it this way makes the syscall restartable in case of EINTR6930 */6931 rc = brightness_set(level);6932 if (!rc && ibm_backlight_device)6933 backlight_force_update(ibm_backlight_device,6934 BACKLIGHT_UPDATE_SYSFS);6935 return (rc == -EINTR) ? -ERESTARTSYS : rc;6936}6937 6938static struct ibm_struct brightness_driver_data = {6939 .name = "brightness",6940 .read = brightness_read,6941 .write = brightness_write,6942 .exit = brightness_exit,6943 .suspend = brightness_suspend,6944 .shutdown = brightness_shutdown,6945};6946 6947/*************************************************************************6948 * Volume subdriver6949 */6950 6951/*6952 * IBM ThinkPads have a simple volume controller with MUTE gating.6953 * Very early Lenovo ThinkPads follow the IBM ThinkPad spec.6954 *6955 * Since the *61 series (and probably also the later *60 series), Lenovo6956 * ThinkPads only implement the MUTE gate.6957 *6958 * EC register 0x306959 * Bit 6: MUTE (1 mutes sound)6960 * Bit 3-0: Volume6961 * Other bits should be zero as far as we know.6962 *6963 * This is also stored in CMOS NVRAM, byte 0x60, bit 6 (MUTE), and6964 * bits 3-0 (volume). Other bits in NVRAM may have other functions,6965 * such as bit 7 which is used to detect repeated presses of MUTE,6966 * and we leave them unchanged.6967 *6968 * On newer Lenovo ThinkPads, the EC can automatically change the volume6969 * in response to user input. Unfortunately, this rarely works well.6970 * The laptop changes the state of its internal MUTE gate and, on some6971 * models, sends KEY_MUTE, causing any user code that responds to the6972 * mute button to get confused. The hardware MUTE gate is also6973 * unnecessary, since user code can handle the mute button without6974 * kernel or EC help.6975 *6976 * To avoid confusing userspace, we simply disable all EC-based mute6977 * and volume controls when possible.6978 */6979 6980#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT6981 6982#define TPACPI_ALSA_DRVNAME "ThinkPad EC"6983#define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control"6984#define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME6985 6986#if SNDRV_CARDS <= 326987#define DEFAULT_ALSA_IDX ~((1 << (SNDRV_CARDS - 3)) - 1)6988#else6989#define DEFAULT_ALSA_IDX ~((1 << (32 - 3)) - 1)6990#endif6991static int alsa_index = DEFAULT_ALSA_IDX; /* last three slots */6992static char *alsa_id = "ThinkPadEC";6993static bool alsa_enable = SNDRV_DEFAULT_ENABLE1;6994 6995struct tpacpi_alsa_data {6996 struct snd_card *card;6997 struct snd_ctl_elem_id *ctl_mute_id;6998 struct snd_ctl_elem_id *ctl_vol_id;6999};7000 7001static struct snd_card *alsa_card;7002 7003enum {7004 TP_EC_AUDIO = 0x30,7005 7006 /* TP_EC_AUDIO bits */7007 TP_EC_AUDIO_MUTESW = 6,7008 7009 /* TP_EC_AUDIO bitmasks */7010 TP_EC_AUDIO_LVL_MSK = 0x0F,7011 TP_EC_AUDIO_MUTESW_MSK = (1 << TP_EC_AUDIO_MUTESW),7012 7013 /* Maximum volume */7014 TP_EC_VOLUME_MAX = 14,7015};7016 7017enum tpacpi_volume_access_mode {7018 TPACPI_VOL_MODE_AUTO = 0, /* Not implemented yet */7019 TPACPI_VOL_MODE_EC, /* Pure EC control */7020 TPACPI_VOL_MODE_UCMS_STEP, /* UCMS step-based control: N/A */7021 TPACPI_VOL_MODE_ECNVRAM, /* EC control w/ NVRAM store */7022 TPACPI_VOL_MODE_MAX7023};7024 7025enum tpacpi_volume_capabilities {7026 TPACPI_VOL_CAP_AUTO = 0, /* Use white/blacklist */7027 TPACPI_VOL_CAP_VOLMUTE, /* Output vol and mute */7028 TPACPI_VOL_CAP_MUTEONLY, /* Output mute only */7029 TPACPI_VOL_CAP_MAX7030};7031 7032enum tpacpi_mute_btn_mode {7033 TP_EC_MUTE_BTN_LATCH = 0, /* Mute mutes; up/down unmutes */7034 /* We don't know what mode 1 is. */7035 TP_EC_MUTE_BTN_NONE = 2, /* Mute and up/down are just keys */7036 TP_EC_MUTE_BTN_TOGGLE = 3, /* Mute toggles; up/down unmutes */7037};7038 7039static enum tpacpi_volume_access_mode volume_mode =7040 TPACPI_VOL_MODE_MAX;7041 7042static enum tpacpi_volume_capabilities volume_capabilities;7043static bool volume_control_allowed;7044static bool software_mute_requested = true;7045static bool software_mute_active;7046static int software_mute_orig_mode;7047 7048/*7049 * Used to syncronize writers to TP_EC_AUDIO and7050 * TP_NVRAM_ADDR_MIXER, as we need to do read-modify-write7051 */7052static struct mutex volume_mutex;7053 7054static void tpacpi_volume_checkpoint_nvram(void)7055{7056 u8 lec = 0;7057 u8 b_nvram;7058 u8 ec_mask;7059 7060 if (volume_mode != TPACPI_VOL_MODE_ECNVRAM)7061 return;7062 if (!volume_control_allowed)7063 return;7064 if (software_mute_active)7065 return;7066 7067 vdbg_printk(TPACPI_DBG_MIXER,7068 "trying to checkpoint mixer state to NVRAM...\n");7069 7070 if (tp_features.mixer_no_level_control)7071 ec_mask = TP_EC_AUDIO_MUTESW_MSK;7072 else7073 ec_mask = TP_EC_AUDIO_MUTESW_MSK | TP_EC_AUDIO_LVL_MSK;7074 7075 if (mutex_lock_killable(&volume_mutex) < 0)7076 return;7077 7078 if (unlikely(!acpi_ec_read(TP_EC_AUDIO, &lec)))7079 goto unlock;7080 lec &= ec_mask;7081 b_nvram = nvram_read_byte(TP_NVRAM_ADDR_MIXER);7082 7083 if (lec != (b_nvram & ec_mask)) {7084 /* NVRAM needs update */7085 b_nvram &= ~ec_mask;7086 b_nvram |= lec;7087 nvram_write_byte(b_nvram, TP_NVRAM_ADDR_MIXER);7088 dbg_printk(TPACPI_DBG_MIXER,7089 "updated NVRAM mixer status to 0x%02x (0x%02x)\n",7090 (unsigned int) lec, (unsigned int) b_nvram);7091 } else {7092 vdbg_printk(TPACPI_DBG_MIXER,7093 "NVRAM mixer status already is 0x%02x (0x%02x)\n",7094 (unsigned int) lec, (unsigned int) b_nvram);7095 }7096 7097unlock:7098 mutex_unlock(&volume_mutex);7099}7100 7101static int volume_get_status_ec(u8 *status)7102{7103 u8 s;7104 7105 if (!acpi_ec_read(TP_EC_AUDIO, &s))7106 return -EIO;7107 7108 *status = s;7109 7110 dbg_printk(TPACPI_DBG_MIXER, "status 0x%02x\n", s);7111 7112 return 0;7113}7114 7115static int volume_get_status(u8 *status)7116{7117 return volume_get_status_ec(status);7118}7119 7120static int volume_set_status_ec(const u8 status)7121{7122 if (!acpi_ec_write(TP_EC_AUDIO, status))7123 return -EIO;7124 7125 dbg_printk(TPACPI_DBG_MIXER, "set EC mixer to 0x%02x\n", status);7126 7127 /*7128 * On X200s, and possibly on others, it can take a while for7129 * reads to become correct.7130 */7131 msleep(1);7132 7133 return 0;7134}7135 7136static int volume_set_status(const u8 status)7137{7138 return volume_set_status_ec(status);7139}7140 7141/* returns < 0 on error, 0 on no change, 1 on change */7142static int __volume_set_mute_ec(const bool mute)7143{7144 int rc;7145 u8 s, n;7146 7147 if (mutex_lock_killable(&volume_mutex) < 0)7148 return -EINTR;7149 7150 rc = volume_get_status_ec(&s);7151 if (rc)7152 goto unlock;7153 7154 n = (mute) ? s | TP_EC_AUDIO_MUTESW_MSK :7155 s & ~TP_EC_AUDIO_MUTESW_MSK;7156 7157 if (n != s) {7158 rc = volume_set_status_ec(n);7159 if (!rc)7160 rc = 1;7161 }7162 7163unlock:7164 mutex_unlock(&volume_mutex);7165 return rc;7166}7167 7168static int volume_alsa_set_mute(const bool mute)7169{7170 dbg_printk(TPACPI_DBG_MIXER, "ALSA: trying to %smute\n",7171 (mute) ? "" : "un");7172 return __volume_set_mute_ec(mute);7173}7174 7175static int volume_set_mute(const bool mute)7176{7177 int rc;7178 7179 dbg_printk(TPACPI_DBG_MIXER, "trying to %smute\n",7180 (mute) ? "" : "un");7181 7182 rc = __volume_set_mute_ec(mute);7183 return (rc < 0) ? rc : 0;7184}7185 7186/* returns < 0 on error, 0 on no change, 1 on change */7187static int __volume_set_volume_ec(const u8 vol)7188{7189 int rc;7190 u8 s, n;7191 7192 if (vol > TP_EC_VOLUME_MAX)7193 return -EINVAL;7194 7195 if (mutex_lock_killable(&volume_mutex) < 0)7196 return -EINTR;7197 7198 rc = volume_get_status_ec(&s);7199 if (rc)7200 goto unlock;7201 7202 n = (s & ~TP_EC_AUDIO_LVL_MSK) | vol;7203 7204 if (n != s) {7205 rc = volume_set_status_ec(n);7206 if (!rc)7207 rc = 1;7208 }7209 7210unlock:7211 mutex_unlock(&volume_mutex);7212 return rc;7213}7214 7215static int volume_set_software_mute(bool startup)7216{7217 int result;7218 7219 if (!tpacpi_is_lenovo())7220 return -ENODEV;7221 7222 if (startup) {7223 if (!acpi_evalf(ec_handle, &software_mute_orig_mode,7224 "HAUM", "qd"))7225 return -EIO;7226 7227 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,7228 "Initial HAUM setting was %d\n",7229 software_mute_orig_mode);7230 }7231 7232 if (!acpi_evalf(ec_handle, &result, "SAUM", "qdd",7233 (int)TP_EC_MUTE_BTN_NONE))7234 return -EIO;7235 7236 if (result != TP_EC_MUTE_BTN_NONE)7237 pr_warn("Unexpected SAUM result %d\n",7238 result);7239 7240 /*7241 * In software mute mode, the standard codec controls take7242 * precendence, so we unmute the ThinkPad HW switch at7243 * startup. Just on case there are SAUM-capable ThinkPads7244 * with level controls, set max HW volume as well.7245 */7246 if (tp_features.mixer_no_level_control)7247 result = volume_set_mute(false);7248 else7249 result = volume_set_status(TP_EC_VOLUME_MAX);7250 7251 if (result != 0)7252 pr_warn("Failed to unmute the HW mute switch\n");7253 7254 return 0;7255}7256 7257static void volume_exit_software_mute(void)7258{7259 int r;7260 7261 if (!acpi_evalf(ec_handle, &r, "SAUM", "qdd", software_mute_orig_mode)7262 || r != software_mute_orig_mode)7263 pr_warn("Failed to restore mute mode\n");7264}7265 7266static int volume_alsa_set_volume(const u8 vol)7267{7268 dbg_printk(TPACPI_DBG_MIXER,7269 "ALSA: trying to set volume level to %hu\n", vol);7270 return __volume_set_volume_ec(vol);7271}7272 7273static void volume_alsa_notify_change(void)7274{7275 struct tpacpi_alsa_data *d;7276 7277 if (alsa_card && alsa_card->private_data) {7278 d = alsa_card->private_data;7279 if (d->ctl_mute_id)7280 snd_ctl_notify(alsa_card,7281 SNDRV_CTL_EVENT_MASK_VALUE,7282 d->ctl_mute_id);7283 if (d->ctl_vol_id)7284 snd_ctl_notify(alsa_card,7285 SNDRV_CTL_EVENT_MASK_VALUE,7286 d->ctl_vol_id);7287 }7288}7289 7290static int volume_alsa_vol_info(struct snd_kcontrol *kcontrol,7291 struct snd_ctl_elem_info *uinfo)7292{7293 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;7294 uinfo->count = 1;7295 uinfo->value.integer.min = 0;7296 uinfo->value.integer.max = TP_EC_VOLUME_MAX;7297 return 0;7298}7299 7300static int volume_alsa_vol_get(struct snd_kcontrol *kcontrol,7301 struct snd_ctl_elem_value *ucontrol)7302{7303 u8 s;7304 int rc;7305 7306 rc = volume_get_status(&s);7307 if (rc < 0)7308 return rc;7309 7310 ucontrol->value.integer.value[0] = s & TP_EC_AUDIO_LVL_MSK;7311 return 0;7312}7313 7314static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol,7315 struct snd_ctl_elem_value *ucontrol)7316{7317 tpacpi_disclose_usertask("ALSA", "set volume to %ld\n",7318 ucontrol->value.integer.value[0]);7319 return volume_alsa_set_volume(ucontrol->value.integer.value[0]);7320}7321 7322#define volume_alsa_mute_info snd_ctl_boolean_mono_info7323 7324static int volume_alsa_mute_get(struct snd_kcontrol *kcontrol,7325 struct snd_ctl_elem_value *ucontrol)7326{7327 u8 s;7328 int rc;7329 7330 rc = volume_get_status(&s);7331 if (rc < 0)7332 return rc;7333 7334 ucontrol->value.integer.value[0] =7335 (s & TP_EC_AUDIO_MUTESW_MSK) ? 0 : 1;7336 return 0;7337}7338 7339static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol,7340 struct snd_ctl_elem_value *ucontrol)7341{7342 tpacpi_disclose_usertask("ALSA", "%smute\n",7343 ucontrol->value.integer.value[0] ?7344 "un" : "");7345 return volume_alsa_set_mute(!ucontrol->value.integer.value[0]);7346}7347 7348static struct snd_kcontrol_new volume_alsa_control_vol __initdata = {7349 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,7350 .name = "Console Playback Volume",7351 .index = 0,7352 .access = SNDRV_CTL_ELEM_ACCESS_READ,7353 .info = volume_alsa_vol_info,7354 .get = volume_alsa_vol_get,7355};7356 7357static struct snd_kcontrol_new volume_alsa_control_mute __initdata = {7358 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,7359 .name = "Console Playback Switch",7360 .index = 0,7361 .access = SNDRV_CTL_ELEM_ACCESS_READ,7362 .info = volume_alsa_mute_info,7363 .get = volume_alsa_mute_get,7364};7365 7366static void volume_suspend(void)7367{7368 tpacpi_volume_checkpoint_nvram();7369}7370 7371static void volume_resume(void)7372{7373 if (software_mute_active) {7374 if (volume_set_software_mute(false) < 0)7375 pr_warn("Failed to restore software mute\n");7376 } else {7377 volume_alsa_notify_change();7378 }7379}7380 7381static void volume_shutdown(void)7382{7383 tpacpi_volume_checkpoint_nvram();7384}7385 7386static void volume_exit(void)7387{7388 if (alsa_card) {7389 snd_card_free(alsa_card);7390 alsa_card = NULL;7391 }7392 7393 tpacpi_volume_checkpoint_nvram();7394 7395 if (software_mute_active)7396 volume_exit_software_mute();7397}7398 7399static int __init volume_create_alsa_mixer(void)7400{7401 struct snd_card *card;7402 struct tpacpi_alsa_data *data;7403 struct snd_kcontrol *ctl_vol;7404 struct snd_kcontrol *ctl_mute;7405 int rc;7406 7407 rc = snd_card_new(&tpacpi_pdev->dev,7408 alsa_index, alsa_id, THIS_MODULE,7409 sizeof(struct tpacpi_alsa_data), &card);7410 if (rc < 0 || !card) {7411 pr_err("Failed to create ALSA card structures: %d\n", rc);7412 return -ENODEV;7413 }7414 7415 BUG_ON(!card->private_data);7416 data = card->private_data;7417 data->card = card;7418 7419 strscpy(card->driver, TPACPI_ALSA_DRVNAME);7420 strscpy(card->shortname, TPACPI_ALSA_SHRTNAME);7421 snprintf(card->mixername, sizeof(card->mixername), "ThinkPad EC %s",7422 (thinkpad_id.ec_version_str) ?7423 thinkpad_id.ec_version_str : "(unknown)");7424 snprintf(card->longname, sizeof(card->longname),7425 "%s at EC reg 0x%02x, fw %s", card->shortname, TP_EC_AUDIO,7426 (thinkpad_id.ec_version_str) ?7427 thinkpad_id.ec_version_str : "unknown");7428 7429 if (volume_control_allowed) {7430 volume_alsa_control_vol.put = volume_alsa_vol_put;7431 volume_alsa_control_vol.access =7432 SNDRV_CTL_ELEM_ACCESS_READWRITE;7433 7434 volume_alsa_control_mute.put = volume_alsa_mute_put;7435 volume_alsa_control_mute.access =7436 SNDRV_CTL_ELEM_ACCESS_READWRITE;7437 }7438 7439 if (!tp_features.mixer_no_level_control) {7440 ctl_vol = snd_ctl_new1(&volume_alsa_control_vol, NULL);7441 rc = snd_ctl_add(card, ctl_vol);7442 if (rc < 0) {7443 pr_err("Failed to create ALSA volume control: %d\n",7444 rc);7445 goto err_exit;7446 }7447 data->ctl_vol_id = &ctl_vol->id;7448 }7449 7450 ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL);7451 rc = snd_ctl_add(card, ctl_mute);7452 if (rc < 0) {7453 pr_err("Failed to create ALSA mute control: %d\n", rc);7454 goto err_exit;7455 }7456 data->ctl_mute_id = &ctl_mute->id;7457 7458 rc = snd_card_register(card);7459 if (rc < 0) {7460 pr_err("Failed to register ALSA card: %d\n", rc);7461 goto err_exit;7462 }7463 7464 alsa_card = card;7465 return 0;7466 7467err_exit:7468 snd_card_free(card);7469 return -ENODEV;7470}7471 7472#define TPACPI_VOL_Q_MUTEONLY 0x0001 /* Mute-only control available */7473#define TPACPI_VOL_Q_LEVEL 0x0002 /* Volume control available */7474 7475static const struct tpacpi_quirk volume_quirk_table[] __initconst = {7476 /* Whitelist volume level on all IBM by default */7477 { .vendor = PCI_VENDOR_ID_IBM,7478 .bios = TPACPI_MATCH_ANY,7479 .ec = TPACPI_MATCH_ANY,7480 .quirks = TPACPI_VOL_Q_LEVEL },7481 7482 /* Lenovo models with volume control (needs confirmation) */7483 TPACPI_QEC_LNV('7', 'C', TPACPI_VOL_Q_LEVEL), /* R60/i */7484 TPACPI_QEC_LNV('7', 'E', TPACPI_VOL_Q_LEVEL), /* R60e/i */7485 TPACPI_QEC_LNV('7', '9', TPACPI_VOL_Q_LEVEL), /* T60/p */7486 TPACPI_QEC_LNV('7', 'B', TPACPI_VOL_Q_LEVEL), /* X60/s */7487 TPACPI_QEC_LNV('7', 'J', TPACPI_VOL_Q_LEVEL), /* X60t */7488 TPACPI_QEC_LNV('7', '7', TPACPI_VOL_Q_LEVEL), /* Z60 */7489 TPACPI_QEC_LNV('7', 'F', TPACPI_VOL_Q_LEVEL), /* Z61 */7490 7491 /* Whitelist mute-only on all Lenovo by default */7492 { .vendor = PCI_VENDOR_ID_LENOVO,7493 .bios = TPACPI_MATCH_ANY,7494 .ec = TPACPI_MATCH_ANY,7495 .quirks = TPACPI_VOL_Q_MUTEONLY }7496};7497 7498static int __init volume_init(struct ibm_init_struct *iibm)7499{7500 unsigned long quirks;7501 int rc;7502 7503 vdbg_printk(TPACPI_DBG_INIT, "initializing volume subdriver\n");7504 7505 mutex_init(&volume_mutex);7506 7507 /*7508 * Check for module parameter bogosity, note that we7509 * init volume_mode to TPACPI_VOL_MODE_MAX in order to be7510 * able to detect "unspecified"7511 */7512 if (volume_mode > TPACPI_VOL_MODE_MAX)7513 return -EINVAL;7514 7515 if (volume_mode == TPACPI_VOL_MODE_UCMS_STEP) {7516 pr_err("UCMS step volume mode not implemented, please contact %s\n",7517 TPACPI_MAIL);7518 return -ENODEV;7519 }7520 7521 if (volume_capabilities >= TPACPI_VOL_CAP_MAX)7522 return -EINVAL;7523 7524 /*7525 * The ALSA mixer is our primary interface.7526 * When disabled, don't install the subdriver at all7527 */7528 if (!alsa_enable) {7529 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,7530 "ALSA mixer disabled by parameter, not loading volume subdriver...\n");7531 return -ENODEV;7532 }7533 7534 quirks = tpacpi_check_quirks(volume_quirk_table,7535 ARRAY_SIZE(volume_quirk_table));7536 7537 switch (volume_capabilities) {7538 case TPACPI_VOL_CAP_AUTO:7539 if (quirks & TPACPI_VOL_Q_MUTEONLY)7540 tp_features.mixer_no_level_control = 1;7541 else if (quirks & TPACPI_VOL_Q_LEVEL)7542 tp_features.mixer_no_level_control = 0;7543 else7544 return -ENODEV; /* no mixer */7545 break;7546 case TPACPI_VOL_CAP_VOLMUTE:7547 tp_features.mixer_no_level_control = 0;7548 break;7549 case TPACPI_VOL_CAP_MUTEONLY:7550 tp_features.mixer_no_level_control = 1;7551 break;7552 default:7553 return -ENODEV;7554 }7555 7556 if (volume_capabilities != TPACPI_VOL_CAP_AUTO)7557 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,7558 "using user-supplied volume_capabilities=%d\n",7559 volume_capabilities);7560 7561 if (volume_mode == TPACPI_VOL_MODE_AUTO ||7562 volume_mode == TPACPI_VOL_MODE_MAX) {7563 volume_mode = TPACPI_VOL_MODE_ECNVRAM;7564 7565 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,7566 "driver auto-selected volume_mode=%d\n",7567 volume_mode);7568 } else {7569 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,7570 "using user-supplied volume_mode=%d\n",7571 volume_mode);7572 }7573 7574 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,7575 "mute is supported, volume control is %s\n",7576 str_supported(!tp_features.mixer_no_level_control));7577 7578 if (software_mute_requested && volume_set_software_mute(true) == 0) {7579 software_mute_active = true;7580 } else {7581 rc = volume_create_alsa_mixer();7582 if (rc) {7583 pr_err("Could not create the ALSA mixer interface\n");7584 return rc;7585 }7586 7587 pr_info("Console audio control enabled, mode: %s\n",7588 (volume_control_allowed) ?7589 "override (read/write)" :7590 "monitor (read only)");7591 }7592 7593 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,7594 "registering volume hotkeys as change notification\n");7595 tpacpi_hotkey_driver_mask_set(hotkey_driver_mask7596 | TP_ACPI_HKEY_VOLUP_MASK7597 | TP_ACPI_HKEY_VOLDWN_MASK7598 | TP_ACPI_HKEY_MUTE_MASK);7599 7600 return 0;7601}7602 7603static int volume_read(struct seq_file *m)7604{7605 u8 status;7606 7607 if (volume_get_status(&status) < 0) {7608 seq_printf(m, "level:\t\tunreadable\n");7609 } else {7610 if (tp_features.mixer_no_level_control)7611 seq_printf(m, "level:\t\tunsupported\n");7612 else7613 seq_printf(m, "level:\t\t%d\n",7614 status & TP_EC_AUDIO_LVL_MSK);7615 7616 seq_printf(m, "mute:\t\t%s\n", str_on_off(status & BIT(TP_EC_AUDIO_MUTESW)));7617 7618 if (volume_control_allowed) {7619 seq_printf(m, "commands:\tunmute, mute\n");7620 if (!tp_features.mixer_no_level_control) {7621 seq_printf(m, "commands:\tup, down\n");7622 seq_printf(m, "commands:\tlevel <level> (<level> is 0-%d)\n",7623 TP_EC_VOLUME_MAX);7624 }7625 }7626 }7627 7628 return 0;7629}7630 7631static int volume_write(char *buf)7632{7633 u8 s;7634 u8 new_level, new_mute;7635 int l;7636 char *cmd;7637 int rc;7638 7639 /*7640 * We do allow volume control at driver startup, so that the7641 * user can set initial state through the volume=... parameter hack.7642 */7643 if (!volume_control_allowed && tpacpi_lifecycle != TPACPI_LIFE_INIT) {7644 if (unlikely(!tp_warned.volume_ctrl_forbidden)) {7645 tp_warned.volume_ctrl_forbidden = 1;7646 pr_notice("Console audio control in monitor mode, changes are not allowed\n");7647 pr_notice("Use the volume_control=1 module parameter to enable volume control\n");7648 }7649 return -EPERM;7650 }7651 7652 rc = volume_get_status(&s);7653 if (rc < 0)7654 return rc;7655 7656 new_level = s & TP_EC_AUDIO_LVL_MSK;7657 new_mute = s & TP_EC_AUDIO_MUTESW_MSK;7658 7659 while ((cmd = strsep(&buf, ","))) {7660 if (!tp_features.mixer_no_level_control) {7661 if (strstarts(cmd, "up")) {7662 if (new_mute)7663 new_mute = 0;7664 else if (new_level < TP_EC_VOLUME_MAX)7665 new_level++;7666 continue;7667 } else if (strstarts(cmd, "down")) {7668 if (new_mute)7669 new_mute = 0;7670 else if (new_level > 0)7671 new_level--;7672 continue;7673 } else if (sscanf(cmd, "level %u", &l) == 1 &&7674 l >= 0 && l <= TP_EC_VOLUME_MAX) {7675 new_level = l;7676 continue;7677 }7678 }7679 if (strstarts(cmd, "mute"))7680 new_mute = TP_EC_AUDIO_MUTESW_MSK;7681 else if (strstarts(cmd, "unmute"))7682 new_mute = 0;7683 else7684 return -EINVAL;7685 }7686 7687 if (tp_features.mixer_no_level_control) {7688 tpacpi_disclose_usertask("procfs volume", "%smute\n",7689 new_mute ? "" : "un");7690 rc = volume_set_mute(!!new_mute);7691 } else {7692 tpacpi_disclose_usertask("procfs volume",7693 "%smute and set level to %d\n",7694 new_mute ? "" : "un", new_level);7695 rc = volume_set_status(new_mute | new_level);7696 }7697 volume_alsa_notify_change();7698 7699 return (rc == -EINTR) ? -ERESTARTSYS : rc;7700}7701 7702static struct ibm_struct volume_driver_data = {7703 .name = "volume",7704 .read = volume_read,7705 .write = volume_write,7706 .exit = volume_exit,7707 .suspend = volume_suspend,7708 .resume = volume_resume,7709 .shutdown = volume_shutdown,7710};7711 7712#else /* !CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */7713 7714#define alsa_card NULL7715 7716static inline void volume_alsa_notify_change(void)7717{7718}7719 7720static int __init volume_init(struct ibm_init_struct *iibm)7721{7722 pr_info("volume: disabled as there is no ALSA support in this kernel\n");7723 7724 return -ENODEV;7725}7726 7727static struct ibm_struct volume_driver_data = {7728 .name = "volume",7729};7730 7731#endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */7732 7733/*************************************************************************7734 * Fan subdriver7735 */7736 7737/*7738 * FAN ACCESS MODES7739 *7740 * TPACPI_FAN_RD_ACPI_GFAN:7741 * ACPI GFAN method: returns fan level7742 *7743 * see TPACPI_FAN_WR_ACPI_SFAN7744 * EC 0x2f (HFSP) not available if GFAN exists7745 *7746 * TPACPI_FAN_WR_ACPI_SFAN:7747 * ACPI SFAN method: sets fan level, 0 (stop) to 7 (max)7748 *7749 * EC 0x2f (HFSP) might be available *for reading*, but do not use7750 * it for writing.7751 *7752 * TPACPI_FAN_RD_ACPI_FANG:7753 * ACPI FANG method: returns fan control register7754 *7755 * Takes one parameter which is 0x8100 plus the offset to EC memory7756 * address 0xf500 and returns the byte at this address.7757 *7758 * 0xf500:7759 * When the value is less than 9 automatic mode is enabled7760 * 0xf502:7761 * Contains the current fan speed from 0-100%7762 * 0xf506:7763 * Bit 7 has to be set in order to enable manual control by7764 * writing a value >= 9 to 0xf5007765 *7766 * TPACPI_FAN_WR_ACPI_FANW:7767 * ACPI FANW method: sets fan control registers7768 *7769 * Takes 0x8100 plus the offset to EC memory address 0xf500 and the7770 * value to be written there as parameters.7771 *7772 * see TPACPI_FAN_RD_ACPI_FANG7773 *7774 * TPACPI_FAN_WR_TPEC:7775 * ThinkPad EC register 0x2f (HFSP): fan control loop mode7776 * Supported on almost all ThinkPads7777 *7778 * Fan speed changes of any sort (including those caused by the7779 * disengaged mode) are usually done slowly by the firmware as the7780 * maximum amount of fan duty cycle change per second seems to be7781 * limited.7782 *7783 * Reading is not available if GFAN exists.7784 * Writing is not available if SFAN exists.7785 *7786 * Bits7787 * 7 automatic mode engaged;7788 * (default operation mode of the ThinkPad)7789 * fan level is ignored in this mode.7790 * 6 full speed mode (takes precedence over bit 7);7791 * not available on all thinkpads. May disable7792 * the tachometer while the fan controller ramps up7793 * the speed (which can take up to a few *minutes*).7794 * Speeds up fan to 100% duty-cycle, which is far above7795 * the standard RPM levels. It is not impossible that7796 * it could cause hardware damage.7797 * 5-3 unused in some models. Extra bits for fan level7798 * in others, but still useless as all values above7799 * 7 map to the same speed as level 7 in these models.7800 * 2-0 fan level (0..7 usually)7801 * 0x00 = stop7802 * 0x07 = max (set when temperatures critical)7803 * Some ThinkPads may have other levels, see7804 * TPACPI_FAN_WR_ACPI_FANS (X31/X40/X41)7805 *7806 * FIRMWARE BUG: on some models, EC 0x2f might not be initialized at7807 * boot. Apparently the EC does not initialize it, so unless ACPI DSDT7808 * does so, its initial value is meaningless (0x07).7809 *7810 * For firmware bugs, refer to:7811 * https://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues7812 *7813 * ----7814 *7815 * ThinkPad EC register 0x84 (LSB), 0x85 (MSB):7816 * Main fan tachometer reading (in RPM)7817 *7818 * This register is present on all ThinkPads with a new-style EC, and7819 * it is known not to be present on the A21m/e, and T22, as there is7820 * something else in offset 0x84 according to the ACPI DSDT. Other7821 * ThinkPads from this same time period (and earlier) probably lack the7822 * tachometer as well.7823 *7824 * Unfortunately a lot of ThinkPads with new-style ECs but whose firmware7825 * was never fixed by IBM to report the EC firmware version string7826 * probably support the tachometer (like the early X models), so7827 * detecting it is quite hard. We need more data to know for sure.7828 *7829 * FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings7830 * might result.7831 *7832 * FIRMWARE BUG: may go stale while the EC is switching to full speed7833 * mode.7834 *7835 * For firmware bugs, refer to:7836 * https://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues7837 *7838 * ----7839 *7840 * ThinkPad EC register 0x31 bit 0 (only on select models)7841 *7842 * When bit 0 of EC register 0x31 is zero, the tachometer registers7843 * show the speed of the main fan. When bit 0 of EC register 0x317844 * is one, the tachometer registers show the speed of the auxiliary7845 * fan.7846 *7847 * Fan control seems to affect both fans, regardless of the state7848 * of this bit.7849 *7850 * So far, only the firmware for the X60/X61 non-tablet versions7851 * seem to support this (firmware TP-7M).7852 *7853 * TPACPI_FAN_WR_ACPI_FANS:7854 * ThinkPad X31, X40, X41. Not available in the X60.7855 *7856 * FANS ACPI handle: takes three arguments: low speed, medium speed,7857 * high speed. ACPI DSDT seems to map these three speeds to levels7858 * as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH7859 * (this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3")7860 *7861 * The speeds are stored on handles7862 * (FANA:FAN9), (FANC:FANB), (FANE:FAND).7863 *7864 * There are three default speed sets, accessible as handles:7865 * FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H7866 *7867 * ACPI DSDT switches which set is in use depending on various7868 * factors.7869 *7870 * TPACPI_FAN_WR_TPEC is also available and should be used to7871 * command the fan. The X31/X40/X41 seems to have 8 fan levels,7872 * but the ACPI tables just mention level 7.7873 *7874 * TPACPI_FAN_RD_TPEC_NS:7875 * This mode is used for a few ThinkPads (L13 Yoga Gen2, X13 Yoga Gen2 etc.)7876 * that are using non-standard EC locations for reporting fan speeds.7877 * Currently these platforms only provide fan rpm reporting.7878 *7879 */7880 7881#define FAN_RPM_CAL_CONST 491520 /* FAN RPM calculation offset for some non-standard ECFW */7882 7883#define FAN_NS_CTRL_STATUS BIT(2) /* Bit which determines control is enabled or not */7884#define FAN_NS_CTRL BIT(4) /* Bit which determines control is by host or EC */7885 7886enum { /* Fan control constants */7887 fan_status_offset = 0x2f, /* EC register 0x2f */7888 fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM)7889 * 0x84 must be read before 0x85 */7890 fan_select_offset = 0x31, /* EC register 0x31 (Firmware 7M)7891 bit 0 selects which fan is active */7892 7893 fan_status_offset_ns = 0x93, /* Special status/control offset for non-standard EC Fan1 */7894 fan2_status_offset_ns = 0x96, /* Special status/control offset for non-standard EC Fan2 */7895 fan_rpm_status_ns = 0x95, /* Special offset for Fan1 RPM status for non-standard EC */7896 fan2_rpm_status_ns = 0x98, /* Special offset for Fan2 RPM status for non-standard EC */7897 7898 TP_EC_FAN_FULLSPEED = 0x40, /* EC fan mode: full speed */7899 TP_EC_FAN_AUTO = 0x80, /* EC fan mode: auto fan control */7900 7901 TPACPI_FAN_LAST_LEVEL = 0x100, /* Use cached last-seen fan level */7902};7903 7904enum fan_status_access_mode {7905 TPACPI_FAN_NONE = 0, /* No fan status or control */7906 TPACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */7907 TPACPI_FAN_RD_ACPI_FANG, /* Use ACPI FANG */7908 TPACPI_FAN_RD_TPEC, /* Use ACPI EC regs 0x2f, 0x84-0x85 */7909 TPACPI_FAN_RD_TPEC_NS, /* Use non-standard ACPI EC regs (eg: L13 Yoga gen2 etc.) */7910};7911 7912enum fan_control_access_mode {7913 TPACPI_FAN_WR_NONE = 0, /* No fan control */7914 TPACPI_FAN_WR_ACPI_SFAN, /* Use ACPI SFAN */7915 TPACPI_FAN_WR_ACPI_FANW, /* Use ACPI FANW */7916 TPACPI_FAN_WR_TPEC, /* Use ACPI EC reg 0x2f */7917 TPACPI_FAN_WR_ACPI_FANS, /* Use ACPI FANS and EC reg 0x2f */7918};7919 7920enum fan_control_commands {7921 TPACPI_FAN_CMD_SPEED = 0x0001, /* speed command */7922 TPACPI_FAN_CMD_LEVEL = 0x0002, /* level command */7923 TPACPI_FAN_CMD_ENABLE = 0x0004, /* enable/disable cmd,7924 * and also watchdog cmd */7925};7926 7927static bool fan_control_allowed;7928 7929static enum fan_status_access_mode fan_status_access_mode;7930static enum fan_control_access_mode fan_control_access_mode;7931static enum fan_control_commands fan_control_commands;7932 7933static u8 fan_control_initial_status;7934static u8 fan_control_desired_level;7935static u8 fan_control_resume_level;7936static int fan_watchdog_maxinterval;7937 7938static bool fan_with_ns_addr;7939static bool ecfw_with_fan_dec_rpm;7940 7941static struct mutex fan_mutex;7942 7943static void fan_watchdog_fire(struct work_struct *ignored);7944static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire);7945 7946TPACPI_HANDLE(fans, ec, "FANS"); /* X31, X40, X41 */7947TPACPI_HANDLE(gfan, ec, "GFAN", /* 570 */7948 "\\FSPD", /* 600e/x, 770e, 770x */7949 ); /* all others */7950TPACPI_HANDLE(fang, ec, "FANG", /* E531 */7951 ); /* all others */7952TPACPI_HANDLE(sfan, ec, "SFAN", /* 570 */7953 "JFNS", /* 770x-JL */7954 ); /* all others */7955TPACPI_HANDLE(fanw, ec, "FANW", /* E531 */7956 ); /* all others */7957 7958/*7959 * Unitialized HFSP quirk: ACPI DSDT and EC fail to initialize the7960 * HFSP register at boot, so it contains 0x07 but the Thinkpad could7961 * be in auto mode (0x80).7962 *7963 * This is corrected by any write to HFSP either by the driver, or7964 * by the firmware.7965 *7966 * We assume 0x07 really means auto mode while this quirk is active,7967 * as this is far more likely than the ThinkPad being in level 7,7968 * which is only used by the firmware during thermal emergencies.7969 *7970 * Enable for TP-1Y (T43), TP-78 (R51e), TP-76 (R52),7971 * TP-70 (T43, R52), which are known to be buggy.7972 */7973 7974static void fan_quirk1_setup(void)7975{7976 if (fan_control_initial_status == 0x07) {7977 pr_notice("fan_init: initial fan status is unknown, assuming it is in auto mode\n");7978 tp_features.fan_ctrl_status_undef = 1;7979 }7980}7981 7982static void fan_quirk1_handle(u8 *fan_status)7983{7984 if (unlikely(tp_features.fan_ctrl_status_undef)) {7985 if (*fan_status != fan_control_initial_status) {7986 /* something changed the HFSP regisnter since7987 * driver init time, so it is not undefined7988 * anymore */7989 tp_features.fan_ctrl_status_undef = 0;7990 } else {7991 /* Return most likely status. In fact, it7992 * might be the only possible status */7993 *fan_status = TP_EC_FAN_AUTO;7994 }7995 }7996}7997 7998/* Select main fan on X60/X61, NOOP on others */7999static bool fan_select_fan1(void)8000{8001 if (tp_features.second_fan) {8002 u8 val;8003 8004 if (ec_read(fan_select_offset, &val) < 0)8005 return false;8006 val &= 0xFEU;8007 if (ec_write(fan_select_offset, val) < 0)8008 return false;8009 }8010 return true;8011}8012 8013/* Select secondary fan on X60/X61 */8014static bool fan_select_fan2(void)8015{8016 u8 val;8017 8018 if (!tp_features.second_fan)8019 return false;8020 8021 if (ec_read(fan_select_offset, &val) < 0)8022 return false;8023 val |= 0x01U;8024 if (ec_write(fan_select_offset, val) < 0)8025 return false;8026 8027 return true;8028}8029 8030static void fan_update_desired_level(u8 status)8031{8032 lockdep_assert_held(&fan_mutex);8033 8034 if ((status &8035 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {8036 if (status > 7)8037 fan_control_desired_level = 7;8038 else8039 fan_control_desired_level = status;8040 }8041}8042 8043static int fan_get_status(u8 *status)8044{8045 u8 s;8046 8047 /* TODO:8048 * Add TPACPI_FAN_RD_ACPI_FANS ? */8049 8050 switch (fan_status_access_mode) {8051 case TPACPI_FAN_RD_ACPI_GFAN: {8052 /* 570, 600e/x, 770e, 770x */8053 int res;8054 8055 if (unlikely(!acpi_evalf(gfan_handle, &res, NULL, "d")))8056 return -EIO;8057 8058 if (likely(status))8059 *status = res & 0x07;8060 8061 break;8062 }8063 case TPACPI_FAN_RD_ACPI_FANG: {8064 /* E531 */8065 int mode, speed;8066 8067 if (unlikely(!acpi_evalf(fang_handle, &mode, NULL, "dd", 0x8100)))8068 return -EIO;8069 if (unlikely(!acpi_evalf(fang_handle, &speed, NULL, "dd", 0x8102)))8070 return -EIO;8071 8072 if (likely(status)) {8073 *status = speed * 7 / 100;8074 if (mode < 9)8075 *status |= TP_EC_FAN_AUTO;8076 }8077 8078 break;8079 }8080 case TPACPI_FAN_RD_TPEC:8081 /* all except 570, 600e/x, 770e, 770x */8082 if (unlikely(!acpi_ec_read(fan_status_offset, &s)))8083 return -EIO;8084 8085 if (likely(status)) {8086 *status = s;8087 fan_quirk1_handle(status);8088 }8089 8090 break;8091 case TPACPI_FAN_RD_TPEC_NS:8092 /* Default mode is AUTO which means controlled by EC */8093 if (!acpi_ec_read(fan_status_offset_ns, &s))8094 return -EIO;8095 8096 if (status)8097 *status = s;8098 8099 break;8100 8101 default:8102 return -ENXIO;8103 }8104 8105 return 0;8106}8107 8108static int fan_get_status_safe(u8 *status)8109{8110 int rc;8111 u8 s;8112 8113 if (mutex_lock_killable(&fan_mutex))8114 return -ERESTARTSYS;8115 rc = fan_get_status(&s);8116 /* NS EC doesn't have register with level settings */8117 if (!rc && !fan_with_ns_addr)8118 fan_update_desired_level(s);8119 mutex_unlock(&fan_mutex);8120 8121 if (rc)8122 return rc;8123 if (status)8124 *status = s;8125 8126 return 0;8127}8128 8129static int fan_get_speed(unsigned int *speed)8130{8131 u8 hi, lo;8132 8133 switch (fan_status_access_mode) {8134 case TPACPI_FAN_RD_TPEC:8135 /* all except 570, 600e/x, 770e, 770x */8136 if (unlikely(!fan_select_fan1()))8137 return -EIO;8138 if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) ||8139 !acpi_ec_read(fan_rpm_offset + 1, &hi)))8140 return -EIO;8141 8142 if (likely(speed))8143 *speed = (hi << 8) | lo;8144 break;8145 case TPACPI_FAN_RD_TPEC_NS:8146 if (!acpi_ec_read(fan_rpm_status_ns, &lo))8147 return -EIO;8148 8149 if (speed)8150 *speed = lo ? FAN_RPM_CAL_CONST / lo : 0;8151 break;8152 8153 default:8154 return -ENXIO;8155 }8156 8157 return 0;8158}8159 8160static int fan2_get_speed(unsigned int *speed)8161{8162 u8 hi, lo, status;8163 bool rc;8164 8165 switch (fan_status_access_mode) {8166 case TPACPI_FAN_RD_TPEC:8167 /* all except 570, 600e/x, 770e, 770x */8168 if (unlikely(!fan_select_fan2()))8169 return -EIO;8170 rc = !acpi_ec_read(fan_rpm_offset, &lo) ||8171 !acpi_ec_read(fan_rpm_offset + 1, &hi);8172 fan_select_fan1(); /* play it safe */8173 if (rc)8174 return -EIO;8175 8176 if (likely(speed))8177 *speed = (hi << 8) | lo;8178 break;8179 8180 case TPACPI_FAN_RD_TPEC_NS:8181 rc = !acpi_ec_read(fan2_status_offset_ns, &status);8182 if (rc)8183 return -EIO;8184 if (!(status & FAN_NS_CTRL_STATUS)) {8185 pr_info("secondary fan control not supported\n");8186 return -EIO;8187 }8188 rc = !acpi_ec_read(fan2_rpm_status_ns, &lo);8189 if (rc)8190 return -EIO;8191 if (speed)8192 *speed = lo ? FAN_RPM_CAL_CONST / lo : 0;8193 break;8194 case TPACPI_FAN_RD_ACPI_FANG: {8195 /* E531 */8196 int speed_tmp;8197 8198 if (unlikely(!acpi_evalf(fang_handle, &speed_tmp, NULL, "dd", 0x8102)))8199 return -EIO;8200 8201 if (likely(speed))8202 *speed = speed_tmp * 65535 / 100;8203 break;8204 }8205 8206 default:8207 return -ENXIO;8208 }8209 8210 return 0;8211}8212 8213static int fan_set_level(int level)8214{8215 if (!fan_control_allowed)8216 return -EPERM;8217 8218 switch (fan_control_access_mode) {8219 case TPACPI_FAN_WR_ACPI_SFAN:8220 if ((level < 0) || (level > 7))8221 return -EINVAL;8222 8223 if (tp_features.second_fan_ctl) {8224 if (!fan_select_fan2() ||8225 !acpi_evalf(sfan_handle, NULL, NULL, "vd", level)) {8226 pr_warn("Couldn't set 2nd fan level, disabling support\n");8227 tp_features.second_fan_ctl = 0;8228 }8229 fan_select_fan1();8230 }8231 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))8232 return -EIO;8233 break;8234 8235 case TPACPI_FAN_WR_ACPI_FANS:8236 case TPACPI_FAN_WR_TPEC:8237 if (!(level & TP_EC_FAN_AUTO) &&8238 !(level & TP_EC_FAN_FULLSPEED) &&8239 ((level < 0) || (level > 7)))8240 return -EINVAL;8241 8242 /* safety net should the EC not support AUTO8243 * or FULLSPEED mode bits and just ignore them */8244 if (level & TP_EC_FAN_FULLSPEED)8245 level |= 7; /* safety min speed 7 */8246 else if (level & TP_EC_FAN_AUTO)8247 level |= 4; /* safety min speed 4 */8248 8249 if (tp_features.second_fan_ctl) {8250 if (!fan_select_fan2() ||8251 !acpi_ec_write(fan_status_offset, level)) {8252 pr_warn("Couldn't set 2nd fan level, disabling support\n");8253 tp_features.second_fan_ctl = 0;8254 }8255 fan_select_fan1();8256 8257 }8258 if (!acpi_ec_write(fan_status_offset, level))8259 return -EIO;8260 else8261 tp_features.fan_ctrl_status_undef = 0;8262 break;8263 8264 case TPACPI_FAN_WR_ACPI_FANW:8265 if (!(level & TP_EC_FAN_AUTO) && (level < 0 || level > 7))8266 return -EINVAL;8267 if (level & TP_EC_FAN_FULLSPEED)8268 return -EINVAL;8269 8270 if (level & TP_EC_FAN_AUTO) {8271 if (!acpi_evalf(fanw_handle, NULL, NULL, "vdd", 0x8106, 0x05)) {8272 return -EIO;8273 }8274 if (!acpi_evalf(fanw_handle, NULL, NULL, "vdd", 0x8100, 0x00)) {8275 return -EIO;8276 }8277 } else {8278 if (!acpi_evalf(fanw_handle, NULL, NULL, "vdd", 0x8106, 0x45)) {8279 return -EIO;8280 }8281 if (!acpi_evalf(fanw_handle, NULL, NULL, "vdd", 0x8100, 0xff)) {8282 return -EIO;8283 }8284 if (!acpi_evalf(fanw_handle, NULL, NULL, "vdd", 0x8102, level * 100 / 7)) {8285 return -EIO;8286 }8287 }8288 break;8289 8290 default:8291 return -ENXIO;8292 }8293 8294 vdbg_printk(TPACPI_DBG_FAN,8295 "fan control: set fan control register to 0x%02x\n", level);8296 return 0;8297}8298 8299static int fan_set_level_safe(int level)8300{8301 int rc;8302 8303 if (!fan_control_allowed)8304 return -EPERM;8305 8306 if (mutex_lock_killable(&fan_mutex))8307 return -ERESTARTSYS;8308 8309 if (level == TPACPI_FAN_LAST_LEVEL)8310 level = fan_control_desired_level;8311 8312 rc = fan_set_level(level);8313 if (!rc)8314 fan_update_desired_level(level);8315 8316 mutex_unlock(&fan_mutex);8317 return rc;8318}8319 8320static int fan_set_enable(void)8321{8322 u8 s = 0;8323 int rc;8324 8325 if (!fan_control_allowed)8326 return -EPERM;8327 8328 if (mutex_lock_killable(&fan_mutex))8329 return -ERESTARTSYS;8330 8331 switch (fan_control_access_mode) {8332 case TPACPI_FAN_WR_ACPI_FANS:8333 case TPACPI_FAN_WR_TPEC:8334 rc = fan_get_status(&s);8335 if (rc)8336 break;8337 8338 /* Don't go out of emergency fan mode */8339 if (s != 7) {8340 s &= 0x07;8341 s |= TP_EC_FAN_AUTO | 4; /* min fan speed 4 */8342 }8343 8344 if (!acpi_ec_write(fan_status_offset, s))8345 rc = -EIO;8346 else {8347 tp_features.fan_ctrl_status_undef = 0;8348 rc = 0;8349 }8350 break;8351 8352 case TPACPI_FAN_WR_ACPI_SFAN:8353 rc = fan_get_status(&s);8354 if (rc)8355 break;8356 8357 s &= 0x07;8358 8359 /* Set fan to at least level 4 */8360 s |= 4;8361 8362 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s))8363 rc = -EIO;8364 else8365 rc = 0;8366 break;8367 8368 case TPACPI_FAN_WR_ACPI_FANW:8369 if (!acpi_evalf(fanw_handle, NULL, NULL, "vdd", 0x8106, 0x05)) {8370 rc = -EIO;8371 break;8372 }8373 if (!acpi_evalf(fanw_handle, NULL, NULL, "vdd", 0x8100, 0x00)) {8374 rc = -EIO;8375 break;8376 }8377 8378 rc = 0;8379 break;8380 8381 default:8382 rc = -ENXIO;8383 }8384 8385 mutex_unlock(&fan_mutex);8386 8387 if (!rc)8388 vdbg_printk(TPACPI_DBG_FAN,8389 "fan control: set fan control register to 0x%02x\n",8390 s);8391 return rc;8392}8393 8394static int fan_set_disable(void)8395{8396 int rc;8397 8398 if (!fan_control_allowed)8399 return -EPERM;8400 8401 if (mutex_lock_killable(&fan_mutex))8402 return -ERESTARTSYS;8403 8404 rc = 0;8405 switch (fan_control_access_mode) {8406 case TPACPI_FAN_WR_ACPI_FANS:8407 case TPACPI_FAN_WR_TPEC:8408 if (!acpi_ec_write(fan_status_offset, 0x00))8409 rc = -EIO;8410 else {8411 fan_control_desired_level = 0;8412 tp_features.fan_ctrl_status_undef = 0;8413 }8414 break;8415 8416 case TPACPI_FAN_WR_ACPI_SFAN:8417 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))8418 rc = -EIO;8419 else8420 fan_control_desired_level = 0;8421 break;8422 8423 case TPACPI_FAN_WR_ACPI_FANW:8424 if (!acpi_evalf(fanw_handle, NULL, NULL, "vdd", 0x8106, 0x45)) {8425 rc = -EIO;8426 break;8427 }8428 if (!acpi_evalf(fanw_handle, NULL, NULL, "vdd", 0x8100, 0xff)) {8429 rc = -EIO;8430 break;8431 }8432 if (!acpi_evalf(fanw_handle, NULL, NULL, "vdd", 0x8102, 0x00)) {8433 rc = -EIO;8434 break;8435 }8436 rc = 0;8437 break;8438 8439 default:8440 rc = -ENXIO;8441 }8442 8443 if (!rc)8444 vdbg_printk(TPACPI_DBG_FAN,8445 "fan control: set fan control register to 0\n");8446 8447 mutex_unlock(&fan_mutex);8448 return rc;8449}8450 8451static int fan_set_speed(int speed)8452{8453 int rc;8454 8455 if (!fan_control_allowed)8456 return -EPERM;8457 8458 if (mutex_lock_killable(&fan_mutex))8459 return -ERESTARTSYS;8460 8461 rc = 0;8462 switch (fan_control_access_mode) {8463 case TPACPI_FAN_WR_ACPI_FANS:8464 if (speed >= 0 && speed <= 65535) {8465 if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",8466 speed, speed, speed))8467 rc = -EIO;8468 } else8469 rc = -EINVAL;8470 break;8471 8472 case TPACPI_FAN_WR_ACPI_FANW:8473 if (speed >= 0 && speed <= 65535) {8474 if (!acpi_evalf(fanw_handle, NULL, NULL, "vdd", 0x8106, 0x45)) {8475 rc = -EIO;8476 break;8477 }8478 if (!acpi_evalf(fanw_handle, NULL, NULL, "vdd", 0x8100, 0xff)) {8479 rc = -EIO;8480 break;8481 }8482 if (!acpi_evalf(fanw_handle, NULL, NULL, "vdd",8483 0x8102, speed * 100 / 65535))8484 rc = -EIO;8485 } else8486 rc = -EINVAL;8487 break;8488 8489 default:8490 rc = -ENXIO;8491 }8492 8493 mutex_unlock(&fan_mutex);8494 return rc;8495}8496 8497static void fan_watchdog_reset(void)8498{8499 if (fan_control_access_mode == TPACPI_FAN_WR_NONE)8500 return;8501 8502 if (fan_watchdog_maxinterval > 0 &&8503 tpacpi_lifecycle != TPACPI_LIFE_EXITING)8504 mod_delayed_work(tpacpi_wq, &fan_watchdog_task,8505 msecs_to_jiffies(fan_watchdog_maxinterval * 1000));8506 else8507 cancel_delayed_work(&fan_watchdog_task);8508}8509 8510static void fan_watchdog_fire(struct work_struct *ignored)8511{8512 int rc;8513 8514 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)8515 return;8516 8517 pr_notice("fan watchdog: enabling fan\n");8518 rc = fan_set_enable();8519 if (rc < 0) {8520 pr_err("fan watchdog: error %d while enabling fan, will try again later...\n",8521 rc);8522 /* reschedule for later */8523 fan_watchdog_reset();8524 }8525}8526 8527/*8528 * SYSFS fan layout: hwmon compatible (device)8529 *8530 * pwm*_enable:8531 * 0: "disengaged" mode8532 * 1: manual mode8533 * 2: native EC "auto" mode (recommended, hardware default)8534 *8535 * pwm*: set speed in manual mode, ignored otherwise.8536 * 0 is level 0; 255 is level 7. Intermediate points done with linear8537 * interpolation.8538 *8539 * fan*_input: tachometer reading, RPM8540 *8541 *8542 * SYSFS fan layout: extensions8543 *8544 * fan_watchdog (driver):8545 * fan watchdog interval in seconds, 0 disables (default), max 1208546 */8547 8548/* sysfs fan pwm1_enable ----------------------------------------------- */8549static ssize_t fan_pwm1_enable_show(struct device *dev,8550 struct device_attribute *attr,8551 char *buf)8552{8553 int res, mode;8554 u8 status;8555 8556 res = fan_get_status_safe(&status);8557 if (res)8558 return res;8559 8560 if (status & TP_EC_FAN_FULLSPEED) {8561 mode = 0;8562 } else if (status & TP_EC_FAN_AUTO) {8563 mode = 2;8564 } else8565 mode = 1;8566 8567 return sysfs_emit(buf, "%d\n", mode);8568}8569 8570static ssize_t fan_pwm1_enable_store(struct device *dev,8571 struct device_attribute *attr,8572 const char *buf, size_t count)8573{8574 unsigned long t;8575 int res, level;8576 8577 if (parse_strtoul(buf, 2, &t))8578 return -EINVAL;8579 8580 tpacpi_disclose_usertask("hwmon pwm1_enable",8581 "set fan mode to %lu\n", t);8582 8583 switch (t) {8584 case 0:8585 level = TP_EC_FAN_FULLSPEED;8586 break;8587 case 1:8588 level = TPACPI_FAN_LAST_LEVEL;8589 break;8590 case 2:8591 level = TP_EC_FAN_AUTO;8592 break;8593 case 3:8594 /* reserved for software-controlled auto mode */8595 return -ENOSYS;8596 default:8597 return -EINVAL;8598 }8599 8600 res = fan_set_level_safe(level);8601 if (res == -ENXIO)8602 return -EINVAL;8603 else if (res < 0)8604 return res;8605 8606 fan_watchdog_reset();8607 8608 return count;8609}8610 8611static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,8612 fan_pwm1_enable_show, fan_pwm1_enable_store);8613 8614/* sysfs fan pwm1 ------------------------------------------------------ */8615static ssize_t fan_pwm1_show(struct device *dev,8616 struct device_attribute *attr,8617 char *buf)8618{8619 int res;8620 u8 status;8621 8622 res = fan_get_status_safe(&status);8623 if (res)8624 return res;8625 8626 if ((status &8627 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0)8628 status = fan_control_desired_level;8629 8630 if (status > 7)8631 status = 7;8632 8633 return sysfs_emit(buf, "%u\n", (status * 255) / 7);8634}8635 8636static ssize_t fan_pwm1_store(struct device *dev,8637 struct device_attribute *attr,8638 const char *buf, size_t count)8639{8640 unsigned long s;8641 int rc;8642 u8 status, newlevel;8643 8644 if (parse_strtoul(buf, 255, &s))8645 return -EINVAL;8646 8647 tpacpi_disclose_usertask("hwmon pwm1",8648 "set fan speed to %lu\n", s);8649 8650 /* scale down from 0-255 to 0-7 */8651 newlevel = (s >> 5) & 0x07;8652 8653 if (mutex_lock_killable(&fan_mutex))8654 return -ERESTARTSYS;8655 8656 rc = fan_get_status(&status);8657 if (!rc && (status &8658 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {8659 rc = fan_set_level(newlevel);8660 if (rc == -ENXIO)8661 rc = -EINVAL;8662 else if (!rc) {8663 fan_update_desired_level(newlevel);8664 fan_watchdog_reset();8665 }8666 }8667 8668 mutex_unlock(&fan_mutex);8669 return (rc) ? rc : count;8670}8671 8672static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, fan_pwm1_show, fan_pwm1_store);8673 8674/* sysfs fan fan1_input ------------------------------------------------ */8675static ssize_t fan_fan1_input_show(struct device *dev,8676 struct device_attribute *attr,8677 char *buf)8678{8679 int res;8680 unsigned int speed;8681 8682 res = fan_get_speed(&speed);8683 if (res < 0)8684 return res;8685 8686 /* Check for fan speeds displayed in hexadecimal */8687 if (!ecfw_with_fan_dec_rpm)8688 return sysfs_emit(buf, "%u\n", speed);8689 else8690 return sysfs_emit(buf, "%x\n", speed);8691}8692 8693static DEVICE_ATTR(fan1_input, S_IRUGO, fan_fan1_input_show, NULL);8694 8695/* sysfs fan fan2_input ------------------------------------------------ */8696static ssize_t fan_fan2_input_show(struct device *dev,8697 struct device_attribute *attr,8698 char *buf)8699{8700 int res;8701 unsigned int speed;8702 8703 res = fan2_get_speed(&speed);8704 if (res < 0)8705 return res;8706 8707 /* Check for fan speeds displayed in hexadecimal */8708 if (!ecfw_with_fan_dec_rpm)8709 return sysfs_emit(buf, "%u\n", speed);8710 else8711 return sysfs_emit(buf, "%x\n", speed);8712}8713 8714static DEVICE_ATTR(fan2_input, S_IRUGO, fan_fan2_input_show, NULL);8715 8716/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */8717static ssize_t fan_watchdog_show(struct device_driver *drv, char *buf)8718{8719 return sysfs_emit(buf, "%u\n", fan_watchdog_maxinterval);8720}8721 8722static ssize_t fan_watchdog_store(struct device_driver *drv, const char *buf,8723 size_t count)8724{8725 unsigned long t;8726 8727 if (parse_strtoul(buf, 120, &t))8728 return -EINVAL;8729 8730 if (!fan_control_allowed)8731 return -EPERM;8732 8733 fan_watchdog_maxinterval = t;8734 fan_watchdog_reset();8735 8736 tpacpi_disclose_usertask("fan_watchdog", "set to %lu\n", t);8737 8738 return count;8739}8740static DRIVER_ATTR_RW(fan_watchdog);8741 8742/* --------------------------------------------------------------------- */8743 8744static struct attribute *fan_attributes[] = {8745 &dev_attr_pwm1_enable.attr,8746 &dev_attr_pwm1.attr,8747 &dev_attr_fan1_input.attr,8748 &dev_attr_fan2_input.attr,8749 NULL8750};8751 8752static umode_t fan_attr_is_visible(struct kobject *kobj, struct attribute *attr,8753 int n)8754{8755 if (fan_status_access_mode == TPACPI_FAN_NONE &&8756 fan_control_access_mode == TPACPI_FAN_WR_NONE)8757 return 0;8758 8759 if (attr == &dev_attr_fan2_input.attr) {8760 if (!tp_features.second_fan)8761 return 0;8762 }8763 8764 return attr->mode;8765}8766 8767static const struct attribute_group fan_attr_group = {8768 .is_visible = fan_attr_is_visible,8769 .attrs = fan_attributes,8770};8771 8772static struct attribute *fan_driver_attributes[] = {8773 &driver_attr_fan_watchdog.attr,8774 NULL8775};8776 8777static const struct attribute_group fan_driver_attr_group = {8778 .is_visible = fan_attr_is_visible,8779 .attrs = fan_driver_attributes,8780};8781 8782#define TPACPI_FAN_Q1 0x0001 /* Uninitialized HFSP */8783#define TPACPI_FAN_2FAN 0x0002 /* EC 0x31 bit 0 selects fan2 */8784#define TPACPI_FAN_2CTL 0x0004 /* selects fan2 control */8785#define TPACPI_FAN_NOFAN 0x0008 /* no fan available */8786#define TPACPI_FAN_NS 0x0010 /* For EC with non-Standard register addresses */8787#define TPACPI_FAN_DECRPM 0x0020 /* For ECFW's with RPM in register as decimal */8788 8789static const struct tpacpi_quirk fan_quirk_table[] __initconst = {8790 TPACPI_QEC_IBM('1', 'Y', TPACPI_FAN_Q1),8791 TPACPI_QEC_IBM('7', '8', TPACPI_FAN_Q1),8792 TPACPI_QEC_IBM('7', '6', TPACPI_FAN_Q1),8793 TPACPI_QEC_IBM('7', '0', TPACPI_FAN_Q1),8794 TPACPI_QEC_LNV('7', 'M', TPACPI_FAN_2FAN),8795 TPACPI_Q_LNV('N', '1', TPACPI_FAN_2FAN),8796 TPACPI_Q_LNV3('N', '1', 'D', TPACPI_FAN_2CTL), /* P70 */8797 TPACPI_Q_LNV3('N', '1', 'E', TPACPI_FAN_2CTL), /* P50 */8798 TPACPI_Q_LNV3('N', '1', 'T', TPACPI_FAN_2CTL), /* P71 */8799 TPACPI_Q_LNV3('N', '1', 'U', TPACPI_FAN_2CTL), /* P51 */8800 TPACPI_Q_LNV3('N', '2', 'C', TPACPI_FAN_2CTL), /* P52 / P72 */8801 TPACPI_Q_LNV3('N', '2', 'N', TPACPI_FAN_2CTL), /* P53 / P73 */8802 TPACPI_Q_LNV3('N', '2', 'E', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (1st gen) */8803 TPACPI_Q_LNV3('N', '2', 'O', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (2nd gen) */8804 TPACPI_Q_LNV3('N', '3', '0', TPACPI_FAN_2CTL), /* P15 (1st gen) / P15v (1st gen) */8805 TPACPI_Q_LNV3('N', '3', '7', TPACPI_FAN_2CTL), /* T15g (2nd gen) */8806 TPACPI_Q_LNV3('R', '1', 'F', TPACPI_FAN_NS), /* L13 Yoga Gen 2 */8807 TPACPI_Q_LNV3('N', '2', 'U', TPACPI_FAN_NS), /* X13 Yoga Gen 2*/8808 TPACPI_Q_LNV3('R', '0', 'R', TPACPI_FAN_NS), /* L380 */8809 TPACPI_Q_LNV3('R', '1', '5', TPACPI_FAN_NS), /* L13 Yoga Gen 1 */8810 TPACPI_Q_LNV3('R', '1', '0', TPACPI_FAN_NS), /* L390 */8811 TPACPI_Q_LNV3('N', '2', 'L', TPACPI_FAN_NS), /* X13 Yoga Gen 1 */8812 TPACPI_Q_LNV3('R', '0', 'T', TPACPI_FAN_NS), /* 11e Gen5 GL */8813 TPACPI_Q_LNV3('R', '1', 'D', TPACPI_FAN_NS), /* 11e Gen5 GL-R */8814 TPACPI_Q_LNV3('R', '0', 'V', TPACPI_FAN_NS), /* 11e Gen5 KL-Y */8815 TPACPI_Q_LNV3('N', '1', 'O', TPACPI_FAN_NOFAN), /* X1 Tablet (2nd gen) */8816 TPACPI_Q_LNV3('R', '0', 'Q', TPACPI_FAN_DECRPM),/* L480 */8817};8818 8819static int __init fan_init(struct ibm_init_struct *iibm)8820{8821 unsigned long quirks;8822 8823 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,8824 "initializing fan subdriver\n");8825 8826 mutex_init(&fan_mutex);8827 fan_status_access_mode = TPACPI_FAN_NONE;8828 fan_control_access_mode = TPACPI_FAN_WR_NONE;8829 fan_control_commands = 0;8830 fan_watchdog_maxinterval = 0;8831 tp_features.fan_ctrl_status_undef = 0;8832 tp_features.second_fan = 0;8833 tp_features.second_fan_ctl = 0;8834 fan_control_desired_level = 7;8835 8836 if (tpacpi_is_ibm()) {8837 TPACPI_ACPIHANDLE_INIT(fans);8838 TPACPI_ACPIHANDLE_INIT(gfan);8839 TPACPI_ACPIHANDLE_INIT(sfan);8840 }8841 if (tpacpi_is_lenovo()) {8842 TPACPI_ACPIHANDLE_INIT(fang);8843 TPACPI_ACPIHANDLE_INIT(fanw);8844 }8845 8846 quirks = tpacpi_check_quirks(fan_quirk_table,8847 ARRAY_SIZE(fan_quirk_table));8848 8849 if (quirks & TPACPI_FAN_NOFAN) {8850 pr_info("No integrated ThinkPad fan available\n");8851 return -ENODEV;8852 }8853 8854 if (quirks & TPACPI_FAN_NS) {8855 pr_info("ECFW with non-standard fan reg control found\n");8856 fan_with_ns_addr = 1;8857 /* Fan ctrl support from host is undefined for now */8858 tp_features.fan_ctrl_status_undef = 1;8859 }8860 8861 /* Check for the EC/BIOS with RPM reported in decimal*/8862 if (quirks & TPACPI_FAN_DECRPM) {8863 pr_info("ECFW with fan RPM as decimal in EC register\n");8864 ecfw_with_fan_dec_rpm = 1;8865 tp_features.fan_ctrl_status_undef = 1;8866 }8867 8868 if (gfan_handle) {8869 /* 570, 600e/x, 770e, 770x */8870 fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN;8871 } else if (fang_handle) {8872 /* E531 */8873 fan_status_access_mode = TPACPI_FAN_RD_ACPI_FANG;8874 } else {8875 /* all other ThinkPads: note that even old-style8876 * ThinkPad ECs supports the fan control register */8877 if (fan_with_ns_addr ||8878 likely(acpi_ec_read(fan_status_offset, &fan_control_initial_status))) {8879 int res;8880 unsigned int speed;8881 8882 fan_status_access_mode = fan_with_ns_addr ?8883 TPACPI_FAN_RD_TPEC_NS : TPACPI_FAN_RD_TPEC;8884 8885 if (quirks & TPACPI_FAN_Q1)8886 fan_quirk1_setup();8887 /* Try and probe the 2nd fan */8888 tp_features.second_fan = 1; /* needed for get_speed to work */8889 res = fan2_get_speed(&speed);8890 if (res >= 0 && speed != FAN_NOT_PRESENT) {8891 /* It responded - so let's assume it's there */8892 tp_features.second_fan = 1;8893 /* fan control not currently available for ns ECFW */8894 tp_features.second_fan_ctl = !fan_with_ns_addr;8895 pr_info("secondary fan control detected & enabled\n");8896 } else {8897 /* Fan not auto-detected */8898 tp_features.second_fan = 0;8899 if (quirks & TPACPI_FAN_2FAN) {8900 tp_features.second_fan = 1;8901 pr_info("secondary fan support enabled\n");8902 }8903 if (quirks & TPACPI_FAN_2CTL) {8904 tp_features.second_fan = 1;8905 tp_features.second_fan_ctl = 1;8906 pr_info("secondary fan control enabled\n");8907 }8908 }8909 } else {8910 pr_err("ThinkPad ACPI EC access misbehaving, fan status and control unavailable\n");8911 return -ENODEV;8912 }8913 }8914 8915 if (sfan_handle) {8916 /* 570, 770x-JL */8917 fan_control_access_mode = TPACPI_FAN_WR_ACPI_SFAN;8918 fan_control_commands |=8919 TPACPI_FAN_CMD_LEVEL | TPACPI_FAN_CMD_ENABLE;8920 } else if (fanw_handle) {8921 /* E531 */8922 fan_control_access_mode = TPACPI_FAN_WR_ACPI_FANW;8923 fan_control_commands |=8924 TPACPI_FAN_CMD_LEVEL | TPACPI_FAN_CMD_SPEED | TPACPI_FAN_CMD_ENABLE;8925 } else {8926 if (!gfan_handle) {8927 /* gfan without sfan means no fan control */8928 /* all other models implement TP EC 0x2f control */8929 8930 if (fans_handle) {8931 /* X31, X40, X41 */8932 fan_control_access_mode =8933 TPACPI_FAN_WR_ACPI_FANS;8934 fan_control_commands |=8935 TPACPI_FAN_CMD_SPEED |8936 TPACPI_FAN_CMD_LEVEL |8937 TPACPI_FAN_CMD_ENABLE;8938 } else {8939 fan_control_access_mode = TPACPI_FAN_WR_TPEC;8940 fan_control_commands |=8941 TPACPI_FAN_CMD_LEVEL |8942 TPACPI_FAN_CMD_ENABLE;8943 }8944 }8945 }8946 8947 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,8948 "fan is %s, modes %d, %d\n",8949 str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||8950 fan_control_access_mode != TPACPI_FAN_WR_NONE),8951 fan_status_access_mode, fan_control_access_mode);8952 8953 /* fan control master switch */8954 if (!fan_control_allowed) {8955 fan_control_access_mode = TPACPI_FAN_WR_NONE;8956 fan_control_commands = 0;8957 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,8958 "fan control features disabled by parameter\n");8959 }8960 8961 /* update fan_control_desired_level */8962 if (fan_status_access_mode != TPACPI_FAN_NONE)8963 fan_get_status_safe(NULL);8964 8965 if (fan_status_access_mode == TPACPI_FAN_NONE &&8966 fan_control_access_mode == TPACPI_FAN_WR_NONE)8967 return -ENODEV;8968 8969 return 0;8970}8971 8972static void fan_exit(void)8973{8974 vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_FAN,8975 "cancelling any pending fan watchdog tasks\n");8976 8977 cancel_delayed_work(&fan_watchdog_task);8978 flush_workqueue(tpacpi_wq);8979}8980 8981static void fan_suspend(void)8982{8983 int rc;8984 8985 if (!fan_control_allowed)8986 return;8987 8988 /* Store fan status in cache */8989 fan_control_resume_level = 0;8990 rc = fan_get_status_safe(&fan_control_resume_level);8991 if (rc)8992 pr_notice("failed to read fan level for later restore during resume: %d\n",8993 rc);8994 8995 /* if it is undefined, don't attempt to restore it.8996 * KEEP THIS LAST */8997 if (tp_features.fan_ctrl_status_undef)8998 fan_control_resume_level = 0;8999}9000 9001static void fan_resume(void)9002{9003 u8 current_level = 7;9004 bool do_set = false;9005 int rc;9006 9007 /* DSDT *always* updates status on resume */9008 tp_features.fan_ctrl_status_undef = 0;9009 9010 if (!fan_control_allowed ||9011 !fan_control_resume_level ||9012 fan_get_status_safe(¤t_level))9013 return;9014 9015 switch (fan_control_access_mode) {9016 case TPACPI_FAN_WR_ACPI_SFAN:9017 /* never decrease fan level */9018 do_set = (fan_control_resume_level > current_level);9019 break;9020 case TPACPI_FAN_WR_ACPI_FANS:9021 case TPACPI_FAN_WR_TPEC:9022 /* never decrease fan level, scale is:9023 * TP_EC_FAN_FULLSPEED > 7 >= TP_EC_FAN_AUTO9024 *9025 * We expect the firmware to set either 7 or AUTO, but we9026 * handle FULLSPEED out of paranoia.9027 *9028 * So, we can safely only restore FULLSPEED or 7, anything9029 * else could slow the fan. Restoring AUTO is useless, at9030 * best that's exactly what the DSDT already set (it is the9031 * slower it uses).9032 *9033 * Always keep in mind that the DSDT *will* have set the9034 * fans to what the vendor supposes is the best level. We9035 * muck with it only to speed the fan up.9036 */9037 if (fan_control_resume_level != 7 &&9038 !(fan_control_resume_level & TP_EC_FAN_FULLSPEED))9039 return;9040 else9041 do_set = !(current_level & TP_EC_FAN_FULLSPEED) &&9042 (current_level != fan_control_resume_level);9043 break;9044 default:9045 return;9046 }9047 if (do_set) {9048 pr_notice("restoring fan level to 0x%02x\n",9049 fan_control_resume_level);9050 rc = fan_set_level_safe(fan_control_resume_level);9051 if (rc < 0)9052 pr_notice("failed to restore fan level: %d\n", rc);9053 }9054}9055 9056static int fan_read(struct seq_file *m)9057{9058 int rc;9059 u8 status;9060 unsigned int speed = 0;9061 9062 switch (fan_status_access_mode) {9063 case TPACPI_FAN_RD_ACPI_GFAN:9064 /* 570, 600e/x, 770e, 770x */9065 rc = fan_get_status_safe(&status);9066 if (rc)9067 return rc;9068 9069 seq_printf(m, "status:\t\t%s\n"9070 "level:\t\t%d\n",9071 str_enabled_disabled(status), status);9072 break;9073 9074 case TPACPI_FAN_RD_TPEC_NS:9075 case TPACPI_FAN_RD_TPEC:9076 case TPACPI_FAN_RD_ACPI_FANG:9077 /* all except 570, 600e/x, 770e, 770x */9078 rc = fan_get_status_safe(&status);9079 if (rc)9080 return rc;9081 9082 seq_printf(m, "status:\t\t%s\n", str_enabled_disabled(status));9083 9084 rc = fan_get_speed(&speed);9085 if (rc < 0)9086 return rc;9087 9088 /* Check for fan speeds displayed in hexadecimal */9089 if (!ecfw_with_fan_dec_rpm)9090 seq_printf(m, "speed:\t\t%d\n", speed);9091 else9092 seq_printf(m, "speed:\t\t%x\n", speed);9093 9094 if (fan_status_access_mode == TPACPI_FAN_RD_TPEC_NS) {9095 /*9096 * No full speed bit in NS EC9097 * EC Auto mode is set by default.9098 * No other levels settings available9099 */9100 seq_printf(m, "level:\t\t%s\n", status & FAN_NS_CTRL ? "unknown" : "auto");9101 } else if (fan_status_access_mode == TPACPI_FAN_RD_TPEC) {9102 if (status & TP_EC_FAN_FULLSPEED)9103 /* Disengaged mode takes precedence */9104 seq_printf(m, "level:\t\tdisengaged\n");9105 else if (status & TP_EC_FAN_AUTO)9106 seq_printf(m, "level:\t\tauto\n");9107 else9108 seq_printf(m, "level:\t\t%d\n", status);9109 }9110 break;9111 9112 case TPACPI_FAN_NONE:9113 default:9114 seq_printf(m, "status:\t\tnot supported\n");9115 }9116 9117 if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) {9118 seq_printf(m, "commands:\tlevel <level>");9119 9120 switch (fan_control_access_mode) {9121 case TPACPI_FAN_WR_ACPI_SFAN:9122 seq_printf(m, " (<level> is 0-7)\n");9123 break;9124 9125 default:9126 seq_printf(m, " (<level> is 0-7, auto, disengaged, full-speed)\n");9127 break;9128 }9129 }9130 9131 if (fan_control_commands & TPACPI_FAN_CMD_ENABLE)9132 seq_printf(m, "commands:\tenable, disable\n"9133 "commands:\twatchdog <timeout> (<timeout> is 0 (off), 1-120 (seconds))\n");9134 9135 if (fan_control_commands & TPACPI_FAN_CMD_SPEED)9136 seq_printf(m, "commands:\tspeed <speed> (<speed> is 0-65535)\n");9137 9138 return 0;9139}9140 9141static int fan_write_cmd_level(const char *cmd, int *rc)9142{9143 int level;9144 9145 if (strstarts(cmd, "level auto"))9146 level = TP_EC_FAN_AUTO;9147 else if (strstarts(cmd, "level disengaged") || strstarts(cmd, "level full-speed"))9148 level = TP_EC_FAN_FULLSPEED;9149 else if (sscanf(cmd, "level %d", &level) != 1)9150 return 0;9151 9152 *rc = fan_set_level_safe(level);9153 if (*rc == -ENXIO)9154 pr_err("level command accepted for unsupported access mode %d\n",9155 fan_control_access_mode);9156 else if (!*rc)9157 tpacpi_disclose_usertask("procfs fan",9158 "set level to %d\n", level);9159 9160 return 1;9161}9162 9163static int fan_write_cmd_enable(const char *cmd, int *rc)9164{9165 if (!strstarts(cmd, "enable"))9166 return 0;9167 9168 *rc = fan_set_enable();9169 if (*rc == -ENXIO)9170 pr_err("enable command accepted for unsupported access mode %d\n",9171 fan_control_access_mode);9172 else if (!*rc)9173 tpacpi_disclose_usertask("procfs fan", "enable\n");9174 9175 return 1;9176}9177 9178static int fan_write_cmd_disable(const char *cmd, int *rc)9179{9180 if (!strstarts(cmd, "disable"))9181 return 0;9182 9183 *rc = fan_set_disable();9184 if (*rc == -ENXIO)9185 pr_err("disable command accepted for unsupported access mode %d\n",9186 fan_control_access_mode);9187 else if (!*rc)9188 tpacpi_disclose_usertask("procfs fan", "disable\n");9189 9190 return 1;9191}9192 9193static int fan_write_cmd_speed(const char *cmd, int *rc)9194{9195 int speed;9196 9197 /* TODO:9198 * Support speed <low> <medium> <high> ? */9199 9200 if (sscanf(cmd, "speed %d", &speed) != 1)9201 return 0;9202 9203 *rc = fan_set_speed(speed);9204 if (*rc == -ENXIO)9205 pr_err("speed command accepted for unsupported access mode %d\n",9206 fan_control_access_mode);9207 else if (!*rc)9208 tpacpi_disclose_usertask("procfs fan",9209 "set speed to %d\n", speed);9210 9211 return 1;9212}9213 9214static int fan_write_cmd_watchdog(const char *cmd, int *rc)9215{9216 int interval;9217 9218 if (sscanf(cmd, "watchdog %d", &interval) != 1)9219 return 0;9220 9221 if (interval < 0 || interval > 120)9222 *rc = -EINVAL;9223 else {9224 fan_watchdog_maxinterval = interval;9225 tpacpi_disclose_usertask("procfs fan",9226 "set watchdog timer to %d\n",9227 interval);9228 }9229 9230 return 1;9231}9232 9233static int fan_write(char *buf)9234{9235 char *cmd;9236 int rc = 0;9237 9238 while (!rc && (cmd = strsep(&buf, ","))) {9239 if (!((fan_control_commands & TPACPI_FAN_CMD_LEVEL) &&9240 fan_write_cmd_level(cmd, &rc)) &&9241 !((fan_control_commands & TPACPI_FAN_CMD_ENABLE) &&9242 (fan_write_cmd_enable(cmd, &rc) ||9243 fan_write_cmd_disable(cmd, &rc) ||9244 fan_write_cmd_watchdog(cmd, &rc))) &&9245 !((fan_control_commands & TPACPI_FAN_CMD_SPEED) &&9246 fan_write_cmd_speed(cmd, &rc))9247 )9248 rc = -EINVAL;9249 else if (!rc)9250 fan_watchdog_reset();9251 }9252 9253 return rc;9254}9255 9256static struct ibm_struct fan_driver_data = {9257 .name = "fan",9258 .read = fan_read,9259 .write = fan_write,9260 .exit = fan_exit,9261 .suspend = fan_suspend,9262 .resume = fan_resume,9263};9264 9265/*************************************************************************9266 * Mute LED subdriver9267 */9268 9269#define TPACPI_LED_MAX 29270 9271struct tp_led_table {9272 acpi_string name;9273 int on_value;9274 int off_value;9275 int state;9276};9277 9278static struct tp_led_table led_tables[TPACPI_LED_MAX] = {9279 [LED_AUDIO_MUTE] = {9280 .name = "SSMS",9281 .on_value = 1,9282 .off_value = 0,9283 },9284 [LED_AUDIO_MICMUTE] = {9285 .name = "MMTS",9286 .on_value = 2,9287 .off_value = 0,9288 },9289};9290 9291static int mute_led_on_off(struct tp_led_table *t, bool state)9292{9293 acpi_handle temp;9294 int output;9295 9296 if (ACPI_FAILURE(acpi_get_handle(hkey_handle, t->name, &temp))) {9297 pr_warn("Thinkpad ACPI has no %s interface.\n", t->name);9298 return -EIO;9299 }9300 9301 if (!acpi_evalf(hkey_handle, &output, t->name, "dd",9302 state ? t->on_value : t->off_value))9303 return -EIO;9304 9305 t->state = state;9306 return state;9307}9308 9309static int tpacpi_led_set(int whichled, bool on)9310{9311 struct tp_led_table *t;9312 9313 t = &led_tables[whichled];9314 if (t->state < 0 || t->state == on)9315 return t->state;9316 return mute_led_on_off(t, on);9317}9318 9319static int tpacpi_led_mute_set(struct led_classdev *led_cdev,9320 enum led_brightness brightness)9321{9322 return tpacpi_led_set(LED_AUDIO_MUTE, brightness != LED_OFF);9323}9324 9325static int tpacpi_led_micmute_set(struct led_classdev *led_cdev,9326 enum led_brightness brightness)9327{9328 return tpacpi_led_set(LED_AUDIO_MICMUTE, brightness != LED_OFF);9329}9330 9331static struct led_classdev mute_led_cdev[TPACPI_LED_MAX] = {9332 [LED_AUDIO_MUTE] = {9333 .name = "platform::mute",9334 .max_brightness = 1,9335 .brightness_set_blocking = tpacpi_led_mute_set,9336 .default_trigger = "audio-mute",9337 },9338 [LED_AUDIO_MICMUTE] = {9339 .name = "platform::micmute",9340 .max_brightness = 1,9341 .brightness_set_blocking = tpacpi_led_micmute_set,9342 .default_trigger = "audio-micmute",9343 },9344};9345 9346static int mute_led_init(struct ibm_init_struct *iibm)9347{9348 acpi_handle temp;9349 int i, err;9350 9351 for (i = 0; i < TPACPI_LED_MAX; i++) {9352 struct tp_led_table *t = &led_tables[i];9353 if (ACPI_FAILURE(acpi_get_handle(hkey_handle, t->name, &temp))) {9354 t->state = -ENODEV;9355 continue;9356 }9357 9358 err = led_classdev_register(&tpacpi_pdev->dev, &mute_led_cdev[i]);9359 if (err < 0) {9360 while (i--)9361 led_classdev_unregister(&mute_led_cdev[i]);9362 return err;9363 }9364 }9365 return 0;9366}9367 9368static void mute_led_exit(void)9369{9370 int i;9371 9372 for (i = 0; i < TPACPI_LED_MAX; i++) {9373 led_classdev_unregister(&mute_led_cdev[i]);9374 tpacpi_led_set(i, false);9375 }9376}9377 9378static void mute_led_resume(void)9379{9380 int i;9381 9382 for (i = 0; i < TPACPI_LED_MAX; i++) {9383 struct tp_led_table *t = &led_tables[i];9384 if (t->state >= 0)9385 mute_led_on_off(t, t->state);9386 }9387}9388 9389static struct ibm_struct mute_led_driver_data = {9390 .name = "mute_led",9391 .exit = mute_led_exit,9392 .resume = mute_led_resume,9393};9394 9395/*9396 * Battery Wear Control Driver9397 * Contact: Ognjen Galic <smclt30p@gmail.com>9398 */9399 9400/* Metadata */9401 9402#define GET_START "BCTG"9403#define SET_START "BCCS"9404#define GET_STOP "BCSG"9405#define SET_STOP "BCSS"9406#define GET_DISCHARGE "BDSG"9407#define SET_DISCHARGE "BDSS"9408#define GET_INHIBIT "BICG"9409#define SET_INHIBIT "BICS"9410 9411enum {9412 BAT_ANY = 0,9413 BAT_PRIMARY = 1,9414 BAT_SECONDARY = 29415};9416 9417enum {9418 /* Error condition bit */9419 METHOD_ERR = BIT(31),9420};9421 9422enum {9423 /* This is used in the get/set helpers */9424 THRESHOLD_START,9425 THRESHOLD_STOP,9426 FORCE_DISCHARGE,9427 INHIBIT_CHARGE,9428};9429 9430struct tpacpi_battery_data {9431 int charge_start;9432 int start_support;9433 int charge_stop;9434 int stop_support;9435 unsigned int charge_behaviours;9436};9437 9438struct tpacpi_battery_driver_data {9439 struct tpacpi_battery_data batteries[3];9440 int individual_addressing;9441};9442 9443static struct tpacpi_battery_driver_data battery_info;9444 9445/* ACPI helpers/functions/probes */9446 9447/*9448 * This evaluates a ACPI method call specific to the battery9449 * ACPI extension. The specifics are that an error is marked9450 * in the 32rd bit of the response, so we just check that here.9451 */9452static acpi_status tpacpi_battery_acpi_eval(char *method, int *ret, int param)9453{9454 int response;9455 9456 if (!acpi_evalf(hkey_handle, &response, method, "dd", param)) {9457 acpi_handle_err(hkey_handle, "%s: evaluate failed", method);9458 return AE_ERROR;9459 }9460 if (response & METHOD_ERR) {9461 acpi_handle_err(hkey_handle,9462 "%s evaluated but flagged as error", method);9463 return AE_ERROR;9464 }9465 *ret = response;9466 return AE_OK;9467}9468 9469static int tpacpi_battery_get(int what, int battery, int *ret)9470{9471 switch (what) {9472 case THRESHOLD_START:9473 if ACPI_FAILURE(tpacpi_battery_acpi_eval(GET_START, ret, battery))9474 return -ENODEV;9475 9476 /* The value is in the low 8 bits of the response */9477 *ret = *ret & 0xFF;9478 return 0;9479 case THRESHOLD_STOP:9480 if ACPI_FAILURE(tpacpi_battery_acpi_eval(GET_STOP, ret, battery))9481 return -ENODEV;9482 /* Value is in lower 8 bits */9483 *ret = *ret & 0xFF;9484 /*9485 * On the stop value, if we return 0 that9486 * does not make any sense. 0 means Default, which9487 * means that charging stops at 100%, so we return9488 * that.9489 */9490 if (*ret == 0)9491 *ret = 100;9492 return 0;9493 case FORCE_DISCHARGE:9494 if ACPI_FAILURE(tpacpi_battery_acpi_eval(GET_DISCHARGE, ret, battery))9495 return -ENODEV;9496 /* The force discharge status is in bit 0 */9497 *ret = *ret & 0x01;9498 return 0;9499 case INHIBIT_CHARGE:9500 if ACPI_FAILURE(tpacpi_battery_acpi_eval(GET_INHIBIT, ret, battery))9501 return -ENODEV;9502 /* The inhibit charge status is in bit 0 */9503 *ret = *ret & 0x01;9504 return 0;9505 default:9506 pr_crit("wrong parameter: %d", what);9507 return -EINVAL;9508 }9509}9510 9511static int tpacpi_battery_set(int what, int battery, int value)9512{9513 int param, ret;9514 /* The first 8 bits are the value of the threshold */9515 param = value;9516 /* The battery ID is in bits 8-9, 2 bits */9517 param |= battery << 8;9518 9519 switch (what) {9520 case THRESHOLD_START:9521 if ACPI_FAILURE(tpacpi_battery_acpi_eval(SET_START, &ret, param)) {9522 pr_err("failed to set charge threshold on battery %d",9523 battery);9524 return -ENODEV;9525 }9526 return 0;9527 case THRESHOLD_STOP:9528 if ACPI_FAILURE(tpacpi_battery_acpi_eval(SET_STOP, &ret, param)) {9529 pr_err("failed to set stop threshold: %d", battery);9530 return -ENODEV;9531 }9532 return 0;9533 case FORCE_DISCHARGE:9534 /* Force discharge is in bit 0,9535 * break on AC attach is in bit 1 (won't work on some ThinkPads),9536 * battery ID is in bits 8-9, 2 bits.9537 */9538 if (ACPI_FAILURE(tpacpi_battery_acpi_eval(SET_DISCHARGE, &ret, param))) {9539 pr_err("failed to set force discharge on %d", battery);9540 return -ENODEV;9541 }9542 return 0;9543 case INHIBIT_CHARGE:9544 /* When setting inhibit charge, we set a default value of9545 * always breaking on AC detach and the effective time is set to9546 * be permanent.9547 * The battery ID is in bits 4-5, 2 bits,9548 * the effective time is in bits 8-23, 2 bytes.9549 * A time of FFFF indicates forever.9550 */9551 param = value;9552 param |= battery << 4;9553 param |= 0xFFFF << 8;9554 if (ACPI_FAILURE(tpacpi_battery_acpi_eval(SET_INHIBIT, &ret, param))) {9555 pr_err("failed to set inhibit charge on %d", battery);9556 return -ENODEV;9557 }9558 return 0;9559 default:9560 pr_crit("wrong parameter: %d", what);9561 return -EINVAL;9562 }9563}9564 9565static int tpacpi_battery_set_validate(int what, int battery, int value)9566{9567 int ret, v;9568 9569 ret = tpacpi_battery_set(what, battery, value);9570 if (ret < 0)9571 return ret;9572 9573 ret = tpacpi_battery_get(what, battery, &v);9574 if (ret < 0)9575 return ret;9576 9577 if (v == value)9578 return 0;9579 9580 msleep(500);9581 9582 ret = tpacpi_battery_get(what, battery, &v);9583 if (ret < 0)9584 return ret;9585 9586 if (v == value)9587 return 0;9588 9589 return -EIO;9590}9591 9592static int tpacpi_battery_probe(int battery)9593{9594 int ret = 0;9595 9596 memset(&battery_info.batteries[battery], 0,9597 sizeof(battery_info.batteries[battery]));9598 9599 /*9600 * 1) Get the current start threshold9601 * 2) Check for support9602 * 3) Get the current stop threshold9603 * 4) Check for support9604 * 5) Get the current force discharge status9605 * 6) Check for support9606 * 7) Get the current inhibit charge status9607 * 8) Check for support9608 */9609 if (acpi_has_method(hkey_handle, GET_START)) {9610 if ACPI_FAILURE(tpacpi_battery_acpi_eval(GET_START, &ret, battery)) {9611 pr_err("Error probing battery %d\n", battery);9612 return -ENODEV;9613 }9614 /* Individual addressing is in bit 9 */9615 if (ret & BIT(9))9616 battery_info.individual_addressing = true;9617 /* Support is marked in bit 8 */9618 if (ret & BIT(8))9619 battery_info.batteries[battery].start_support = 1;9620 else9621 return -ENODEV;9622 if (tpacpi_battery_get(THRESHOLD_START, battery,9623 &battery_info.batteries[battery].charge_start)) {9624 pr_err("Error probing battery %d\n", battery);9625 return -ENODEV;9626 }9627 }9628 if (acpi_has_method(hkey_handle, GET_STOP)) {9629 if ACPI_FAILURE(tpacpi_battery_acpi_eval(GET_STOP, &ret, battery)) {9630 pr_err("Error probing battery stop; %d\n", battery);9631 return -ENODEV;9632 }9633 /* Support is marked in bit 8 */9634 if (ret & BIT(8))9635 battery_info.batteries[battery].stop_support = 1;9636 else9637 return -ENODEV;9638 if (tpacpi_battery_get(THRESHOLD_STOP, battery,9639 &battery_info.batteries[battery].charge_stop)) {9640 pr_err("Error probing battery stop: %d\n", battery);9641 return -ENODEV;9642 }9643 }9644 if (acpi_has_method(hkey_handle, GET_DISCHARGE)) {9645 if (ACPI_FAILURE(tpacpi_battery_acpi_eval(GET_DISCHARGE, &ret, battery))) {9646 pr_err("Error probing battery discharge; %d\n", battery);9647 return -ENODEV;9648 }9649 /* Support is marked in bit 8 */9650 if (ret & BIT(8))9651 battery_info.batteries[battery].charge_behaviours |=9652 BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE);9653 }9654 if (acpi_has_method(hkey_handle, GET_INHIBIT)) {9655 if (ACPI_FAILURE(tpacpi_battery_acpi_eval(GET_INHIBIT, &ret, battery))) {9656 pr_err("Error probing battery inhibit charge; %d\n", battery);9657 return -ENODEV;9658 }9659 /* Support is marked in bit 5 */9660 if (ret & BIT(5))9661 battery_info.batteries[battery].charge_behaviours |=9662 BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE);9663 }9664 9665 battery_info.batteries[battery].charge_behaviours |=9666 BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO);9667 9668 pr_info("battery %d registered (start %d, stop %d, behaviours: 0x%x)\n",9669 battery,9670 battery_info.batteries[battery].charge_start,9671 battery_info.batteries[battery].charge_stop,9672 battery_info.batteries[battery].charge_behaviours);9673 9674 return 0;9675}9676 9677/* General helper functions */9678 9679static int tpacpi_battery_get_id(const char *battery_name)9680{9681 9682 if (strcmp(battery_name, "BAT0") == 0 ||9683 tp_features.battery_force_primary)9684 return BAT_PRIMARY;9685 if (strcmp(battery_name, "BAT1") == 0)9686 return BAT_SECONDARY;9687 /*9688 * If for some reason the battery is not BAT0 nor is it9689 * BAT1, we will assume it's the default, first battery,9690 * AKA primary.9691 */9692 pr_warn("unknown battery %s, assuming primary", battery_name);9693 return BAT_PRIMARY;9694}9695 9696/* sysfs interface */9697 9698static ssize_t tpacpi_battery_store(int what,9699 struct device *dev,9700 const char *buf, size_t count)9701{9702 struct power_supply *supply = to_power_supply(dev);9703 unsigned long value;9704 int battery, rval;9705 /*9706 * Some systems have support for more than9707 * one battery. If that is the case,9708 * tpacpi_battery_probe marked that addressing9709 * them individually is supported, so we do that9710 * based on the device struct.9711 *9712 * On systems that are not supported, we assume9713 * the primary as most of the ACPI calls fail9714 * with "Any Battery" as the parameter.9715 */9716 if (battery_info.individual_addressing)9717 /* BAT_PRIMARY or BAT_SECONDARY */9718 battery = tpacpi_battery_get_id(supply->desc->name);9719 else9720 battery = BAT_PRIMARY;9721 9722 rval = kstrtoul(buf, 10, &value);9723 if (rval)9724 return rval;9725 9726 switch (what) {9727 case THRESHOLD_START:9728 if (!battery_info.batteries[battery].start_support)9729 return -ENODEV;9730 /* valid values are [0, 99] */9731 if (value > 99)9732 return -EINVAL;9733 if (value > battery_info.batteries[battery].charge_stop)9734 return -EINVAL;9735 if (tpacpi_battery_set(THRESHOLD_START, battery, value))9736 return -ENODEV;9737 battery_info.batteries[battery].charge_start = value;9738 return count;9739 9740 case THRESHOLD_STOP:9741 if (!battery_info.batteries[battery].stop_support)9742 return -ENODEV;9743 /* valid values are [1, 100] */9744 if (value < 1 || value > 100)9745 return -EINVAL;9746 if (value < battery_info.batteries[battery].charge_start)9747 return -EINVAL;9748 battery_info.batteries[battery].charge_stop = value;9749 /*9750 * When 100 is passed to stop, we need to flip9751 * it to 0 as that the EC understands that as9752 * "Default", which will charge to 100%9753 */9754 if (value == 100)9755 value = 0;9756 if (tpacpi_battery_set(THRESHOLD_STOP, battery, value))9757 return -EINVAL;9758 return count;9759 default:9760 pr_crit("Wrong parameter: %d", what);9761 return -EINVAL;9762 }9763 return count;9764}9765 9766static ssize_t tpacpi_battery_show(int what,9767 struct device *dev,9768 char *buf)9769{9770 struct power_supply *supply = to_power_supply(dev);9771 int ret, battery;9772 /*9773 * Some systems have support for more than9774 * one battery. If that is the case,9775 * tpacpi_battery_probe marked that addressing9776 * them individually is supported, so we;9777 * based on the device struct.9778 *9779 * On systems that are not supported, we assume9780 * the primary as most of the ACPI calls fail9781 * with "Any Battery" as the parameter.9782 */9783 if (battery_info.individual_addressing)9784 /* BAT_PRIMARY or BAT_SECONDARY */9785 battery = tpacpi_battery_get_id(supply->desc->name);9786 else9787 battery = BAT_PRIMARY;9788 if (tpacpi_battery_get(what, battery, &ret))9789 return -ENODEV;9790 return sysfs_emit(buf, "%d\n", ret);9791}9792 9793static ssize_t charge_control_start_threshold_show(struct device *device,9794 struct device_attribute *attr,9795 char *buf)9796{9797 return tpacpi_battery_show(THRESHOLD_START, device, buf);9798}9799 9800static ssize_t charge_control_end_threshold_show(struct device *device,9801 struct device_attribute *attr,9802 char *buf)9803{9804 return tpacpi_battery_show(THRESHOLD_STOP, device, buf);9805}9806 9807static ssize_t charge_behaviour_show(struct device *dev,9808 struct device_attribute *attr,9809 char *buf)9810{9811 enum power_supply_charge_behaviour active = POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO;9812 struct power_supply *supply = to_power_supply(dev);9813 unsigned int available;9814 int ret, battery;9815 9816 battery = tpacpi_battery_get_id(supply->desc->name);9817 available = battery_info.batteries[battery].charge_behaviours;9818 9819 if (available & BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE)) {9820 if (tpacpi_battery_get(FORCE_DISCHARGE, battery, &ret))9821 return -ENODEV;9822 if (ret) {9823 active = POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE;9824 goto out;9825 }9826 }9827 9828 if (available & BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE)) {9829 if (tpacpi_battery_get(INHIBIT_CHARGE, battery, &ret))9830 return -ENODEV;9831 if (ret) {9832 active = POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE;9833 goto out;9834 }9835 }9836 9837out:9838 return power_supply_charge_behaviour_show(dev, available, active, buf);9839}9840 9841static ssize_t charge_control_start_threshold_store(struct device *dev,9842 struct device_attribute *attr,9843 const char *buf, size_t count)9844{9845 return tpacpi_battery_store(THRESHOLD_START, dev, buf, count);9846}9847 9848static ssize_t charge_control_end_threshold_store(struct device *dev,9849 struct device_attribute *attr,9850 const char *buf, size_t count)9851{9852 return tpacpi_battery_store(THRESHOLD_STOP, dev, buf, count);9853}9854 9855static ssize_t charge_behaviour_store(struct device *dev,9856 struct device_attribute *attr,9857 const char *buf, size_t count)9858{9859 struct power_supply *supply = to_power_supply(dev);9860 int selected, battery, ret = 0;9861 unsigned int available;9862 9863 battery = tpacpi_battery_get_id(supply->desc->name);9864 available = battery_info.batteries[battery].charge_behaviours;9865 selected = power_supply_charge_behaviour_parse(available, buf);9866 9867 if (selected < 0)9868 return selected;9869 9870 switch (selected) {9871 case POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO:9872 if (available & BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE))9873 ret = tpacpi_battery_set_validate(FORCE_DISCHARGE, battery, 0);9874 if (available & BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE))9875 ret = min(ret, tpacpi_battery_set_validate(INHIBIT_CHARGE, battery, 0));9876 if (ret < 0)9877 return ret;9878 break;9879 case POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE:9880 if (available & BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE))9881 ret = tpacpi_battery_set_validate(INHIBIT_CHARGE, battery, 0);9882 ret = min(ret, tpacpi_battery_set_validate(FORCE_DISCHARGE, battery, 1));9883 if (ret < 0)9884 return ret;9885 break;9886 case POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE:9887 if (available & BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE))9888 ret = tpacpi_battery_set_validate(FORCE_DISCHARGE, battery, 0);9889 ret = min(ret, tpacpi_battery_set_validate(INHIBIT_CHARGE, battery, 1));9890 if (ret < 0)9891 return ret;9892 break;9893 default:9894 dev_err(dev, "Unexpected charge behaviour: %d\n", selected);9895 return -EINVAL;9896 }9897 9898 return count;9899}9900 9901static DEVICE_ATTR_RW(charge_control_start_threshold);9902static DEVICE_ATTR_RW(charge_control_end_threshold);9903static DEVICE_ATTR_RW(charge_behaviour);9904static struct device_attribute dev_attr_charge_start_threshold = __ATTR(9905 charge_start_threshold,9906 0644,9907 charge_control_start_threshold_show,9908 charge_control_start_threshold_store9909);9910static struct device_attribute dev_attr_charge_stop_threshold = __ATTR(9911 charge_stop_threshold,9912 0644,9913 charge_control_end_threshold_show,9914 charge_control_end_threshold_store9915);9916 9917static struct attribute *tpacpi_battery_attrs[] = {9918 &dev_attr_charge_control_start_threshold.attr,9919 &dev_attr_charge_control_end_threshold.attr,9920 &dev_attr_charge_start_threshold.attr,9921 &dev_attr_charge_stop_threshold.attr,9922 &dev_attr_charge_behaviour.attr,9923 NULL,9924};9925 9926ATTRIBUTE_GROUPS(tpacpi_battery);9927 9928/* ACPI battery hooking */9929 9930static int tpacpi_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook)9931{9932 int batteryid = tpacpi_battery_get_id(battery->desc->name);9933 9934 if (tpacpi_battery_probe(batteryid))9935 return -ENODEV;9936 if (device_add_groups(&battery->dev, tpacpi_battery_groups))9937 return -ENODEV;9938 return 0;9939}9940 9941static int tpacpi_battery_remove(struct power_supply *battery, struct acpi_battery_hook *hook)9942{9943 device_remove_groups(&battery->dev, tpacpi_battery_groups);9944 return 0;9945}9946 9947static struct acpi_battery_hook battery_hook = {9948 .add_battery = tpacpi_battery_add,9949 .remove_battery = tpacpi_battery_remove,9950 .name = "ThinkPad Battery Extension",9951};9952 9953/* Subdriver init/exit */9954 9955static const struct tpacpi_quirk battery_quirk_table[] __initconst = {9956 /*9957 * Individual addressing is broken on models that expose the9958 * primary battery as BAT1.9959 */9960 TPACPI_Q_LNV('8', 'F', true), /* Thinkpad X120e */9961 TPACPI_Q_LNV('J', '7', true), /* B5400 */9962 TPACPI_Q_LNV('J', 'I', true), /* Thinkpad 11e */9963 TPACPI_Q_LNV3('R', '0', 'B', true), /* Thinkpad 11e gen 3 */9964 TPACPI_Q_LNV3('R', '0', 'C', true), /* Thinkpad 13 */9965 TPACPI_Q_LNV3('R', '0', 'J', true), /* Thinkpad 13 gen 2 */9966 TPACPI_Q_LNV3('R', '0', 'K', true), /* Thinkpad 11e gen 4 celeron BIOS */9967};9968 9969static int __init tpacpi_battery_init(struct ibm_init_struct *ibm)9970{9971 memset(&battery_info, 0, sizeof(battery_info));9972 9973 tp_features.battery_force_primary = tpacpi_check_quirks(9974 battery_quirk_table,9975 ARRAY_SIZE(battery_quirk_table));9976 9977 battery_hook_register(&battery_hook);9978 return 0;9979}9980 9981static void tpacpi_battery_exit(void)9982{9983 battery_hook_unregister(&battery_hook);9984}9985 9986static struct ibm_struct battery_driver_data = {9987 .name = "battery",9988 .exit = tpacpi_battery_exit,9989};9990 9991/*************************************************************************9992 * LCD Shadow subdriver, for the Lenovo PrivacyGuard feature9993 */9994 9995static struct drm_privacy_screen *lcdshadow_dev;9996static acpi_handle lcdshadow_get_handle;9997static acpi_handle lcdshadow_set_handle;9998 9999static int lcdshadow_set_sw_state(struct drm_privacy_screen *priv,10000 enum drm_privacy_screen_status state)10001{10002 int output;10003 10004 if (WARN_ON(!mutex_is_locked(&priv->lock)))10005 return -EIO;10006 10007 if (!acpi_evalf(lcdshadow_set_handle, &output, NULL, "dd", (int)state))10008 return -EIO;10009 10010 priv->hw_state = priv->sw_state = state;10011 return 0;10012}10013 10014static void lcdshadow_get_hw_state(struct drm_privacy_screen *priv)10015{10016 int output;10017 10018 if (!acpi_evalf(lcdshadow_get_handle, &output, NULL, "dd", 0))10019 return;10020 10021 priv->hw_state = priv->sw_state = output & 0x1;10022}10023 10024static const struct drm_privacy_screen_ops lcdshadow_ops = {10025 .set_sw_state = lcdshadow_set_sw_state,10026 .get_hw_state = lcdshadow_get_hw_state,10027};10028 10029static int tpacpi_lcdshadow_init(struct ibm_init_struct *iibm)10030{10031 acpi_status status1, status2;10032 int output;10033 10034 status1 = acpi_get_handle(hkey_handle, "GSSS", &lcdshadow_get_handle);10035 status2 = acpi_get_handle(hkey_handle, "SSSS", &lcdshadow_set_handle);10036 if (ACPI_FAILURE(status1) || ACPI_FAILURE(status2))10037 return 0;10038 10039 if (!acpi_evalf(lcdshadow_get_handle, &output, NULL, "dd", 0))10040 return -EIO;10041 10042 if (!(output & 0x10000))10043 return 0;10044 10045 lcdshadow_dev = drm_privacy_screen_register(&tpacpi_pdev->dev,10046 &lcdshadow_ops, NULL);10047 if (IS_ERR(lcdshadow_dev))10048 return PTR_ERR(lcdshadow_dev);10049 10050 return 0;10051}10052 10053static void lcdshadow_exit(void)10054{10055 drm_privacy_screen_unregister(lcdshadow_dev);10056}10057 10058static void lcdshadow_resume(void)10059{10060 if (!lcdshadow_dev)10061 return;10062 10063 mutex_lock(&lcdshadow_dev->lock);10064 lcdshadow_set_sw_state(lcdshadow_dev, lcdshadow_dev->sw_state);10065 mutex_unlock(&lcdshadow_dev->lock);10066}10067 10068static int lcdshadow_read(struct seq_file *m)10069{10070 if (!lcdshadow_dev) {10071 seq_puts(m, "status:\t\tnot supported\n");10072 } else {10073 seq_printf(m, "status:\t\t%d\n", lcdshadow_dev->hw_state);10074 seq_puts(m, "commands:\t0, 1\n");10075 }10076 10077 return 0;10078}10079 10080static int lcdshadow_write(char *buf)10081{10082 char *cmd;10083 int res, state = -EINVAL;10084 10085 if (!lcdshadow_dev)10086 return -ENODEV;10087 10088 while ((cmd = strsep(&buf, ","))) {10089 res = kstrtoint(cmd, 10, &state);10090 if (res < 0)10091 return res;10092 }10093 10094 if (state >= 2 || state < 0)10095 return -EINVAL;10096 10097 mutex_lock(&lcdshadow_dev->lock);10098 res = lcdshadow_set_sw_state(lcdshadow_dev, state);10099 mutex_unlock(&lcdshadow_dev->lock);10100 10101 drm_privacy_screen_call_notifier_chain(lcdshadow_dev);10102 10103 return res;10104}10105 10106static struct ibm_struct lcdshadow_driver_data = {10107 .name = "lcdshadow",10108 .exit = lcdshadow_exit,10109 .resume = lcdshadow_resume,10110 .read = lcdshadow_read,10111 .write = lcdshadow_write,10112};10113 10114/*************************************************************************10115 * Thinkpad sensor interfaces10116 */10117 10118#define DYTC_CMD_QUERY 0 /* To get DYTC status - enable/revision */10119#define DYTC_QUERY_ENABLE_BIT 8 /* Bit 8 - 0 = disabled, 1 = enabled */10120#define DYTC_QUERY_SUBREV_BIT 16 /* Bits 16 - 27 - sub revision */10121#define DYTC_QUERY_REV_BIT 28 /* Bits 28 - 31 - revision */10122 10123#define DYTC_CMD_GET 2 /* To get current IC function and mode */10124#define DYTC_GET_LAPMODE_BIT 17 /* Set when in lapmode */10125 10126#define PALMSENSOR_PRESENT_BIT 0 /* Determine if psensor present */10127#define PALMSENSOR_ON_BIT 1 /* psensor status */10128 10129static bool has_palmsensor;10130static bool has_lapsensor;10131static bool palm_state;10132static bool lap_state;10133static int dytc_version;10134 10135static int dytc_command(int command, int *output)10136{10137 acpi_handle dytc_handle;10138 10139 if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "DYTC", &dytc_handle))) {10140 /* Platform doesn't support DYTC */10141 return -ENODEV;10142 }10143 if (!acpi_evalf(dytc_handle, output, NULL, "dd", command))10144 return -EIO;10145 return 0;10146}10147 10148static int lapsensor_get(bool *present, bool *state)10149{10150 int output, err;10151 10152 *present = false;10153 err = dytc_command(DYTC_CMD_GET, &output);10154 if (err)10155 return err;10156 10157 *present = true; /*If we get his far, we have lapmode support*/10158 *state = output & BIT(DYTC_GET_LAPMODE_BIT) ? true : false;10159 return 0;10160}10161 10162static int palmsensor_get(bool *present, bool *state)10163{10164 acpi_handle psensor_handle;10165 int output;10166 10167 *present = false;10168 if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "GPSS", &psensor_handle)))10169 return -ENODEV;10170 if (!acpi_evalf(psensor_handle, &output, NULL, "d"))10171 return -EIO;10172 10173 *present = output & BIT(PALMSENSOR_PRESENT_BIT) ? true : false;10174 *state = output & BIT(PALMSENSOR_ON_BIT) ? true : false;10175 return 0;10176}10177 10178static void lapsensor_refresh(void)10179{10180 bool state;10181 int err;10182 10183 if (has_lapsensor) {10184 err = lapsensor_get(&has_lapsensor, &state);10185 if (err)10186 return;10187 if (lap_state != state) {10188 lap_state = state;10189 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, "dytc_lapmode");10190 }10191 }10192}10193 10194static void palmsensor_refresh(void)10195{10196 bool state;10197 int err;10198 10199 if (has_palmsensor) {10200 err = palmsensor_get(&has_palmsensor, &state);10201 if (err)10202 return;10203 if (palm_state != state) {10204 palm_state = state;10205 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, "palmsensor");10206 }10207 }10208}10209 10210static ssize_t dytc_lapmode_show(struct device *dev,10211 struct device_attribute *attr,10212 char *buf)10213{10214 if (has_lapsensor)10215 return sysfs_emit(buf, "%d\n", lap_state);10216 return sysfs_emit(buf, "\n");10217}10218static DEVICE_ATTR_RO(dytc_lapmode);10219 10220static ssize_t palmsensor_show(struct device *dev,10221 struct device_attribute *attr,10222 char *buf)10223{10224 if (has_palmsensor)10225 return sysfs_emit(buf, "%d\n", palm_state);10226 return sysfs_emit(buf, "\n");10227}10228static DEVICE_ATTR_RO(palmsensor);10229 10230static struct attribute *proxsensor_attributes[] = {10231 &dev_attr_dytc_lapmode.attr,10232 &dev_attr_palmsensor.attr,10233 NULL10234};10235 10236static umode_t proxsensor_attr_is_visible(struct kobject *kobj,10237 struct attribute *attr, int n)10238{10239 if (attr == &dev_attr_dytc_lapmode.attr) {10240 /*10241 * Platforms before DYTC version 5 claim to have a lap sensor,10242 * but it doesn't work, so we ignore them.10243 */10244 if (!has_lapsensor || dytc_version < 5)10245 return 0;10246 } else if (attr == &dev_attr_palmsensor.attr) {10247 if (!has_palmsensor)10248 return 0;10249 }10250 10251 return attr->mode;10252}10253 10254static const struct attribute_group proxsensor_attr_group = {10255 .is_visible = proxsensor_attr_is_visible,10256 .attrs = proxsensor_attributes,10257};10258 10259static int tpacpi_proxsensor_init(struct ibm_init_struct *iibm)10260{10261 int palm_err, lap_err;10262 10263 palm_err = palmsensor_get(&has_palmsensor, &palm_state);10264 lap_err = lapsensor_get(&has_lapsensor, &lap_state);10265 /* If support isn't available for both devices return -ENODEV */10266 if ((palm_err == -ENODEV) && (lap_err == -ENODEV))10267 return -ENODEV;10268 /* Otherwise, if there was an error return it */10269 if (palm_err && (palm_err != -ENODEV))10270 return palm_err;10271 if (lap_err && (lap_err != -ENODEV))10272 return lap_err;10273 10274 return 0;10275}10276 10277static struct ibm_struct proxsensor_driver_data = {10278 .name = "proximity-sensor",10279};10280 10281/*************************************************************************10282 * DYTC Platform Profile interface10283 */10284 10285#define DYTC_CMD_SET 1 /* To enable/disable IC function mode */10286#define DYTC_CMD_MMC_GET 8 /* To get current MMC function and mode */10287#define DYTC_CMD_RESET 0x1ff /* To reset back to default */10288 10289#define DYTC_CMD_FUNC_CAP 3 /* To get DYTC capabilities */10290#define DYTC_FC_MMC 27 /* MMC Mode supported */10291#define DYTC_FC_PSC 29 /* PSC Mode supported */10292#define DYTC_FC_AMT 31 /* AMT mode supported */10293 10294#define DYTC_GET_FUNCTION_BIT 8 /* Bits 8-11 - function setting */10295#define DYTC_GET_MODE_BIT 12 /* Bits 12-15 - mode setting */10296 10297#define DYTC_SET_FUNCTION_BIT 12 /* Bits 12-15 - function setting */10298#define DYTC_SET_MODE_BIT 16 /* Bits 16-19 - mode setting */10299#define DYTC_SET_VALID_BIT 20 /* Bit 20 - 1 = on, 0 = off */10300 10301#define DYTC_FUNCTION_STD 0 /* Function = 0, standard mode */10302#define DYTC_FUNCTION_CQL 1 /* Function = 1, lap mode */10303#define DYTC_FUNCTION_MMC 11 /* Function = 11, MMC mode */10304#define DYTC_FUNCTION_PSC 13 /* Function = 13, PSC mode */10305#define DYTC_FUNCTION_AMT 15 /* Function = 15, AMT mode */10306 10307#define DYTC_MODE_AMT_ENABLE 0x1 /* Enable AMT (in balanced mode) */10308#define DYTC_MODE_AMT_DISABLE 0xF /* Disable AMT (in other modes) */10309 10310#define DYTC_MODE_MMC_PERFORM 2 /* High power mode aka performance */10311#define DYTC_MODE_MMC_LOWPOWER 3 /* Low power mode */10312#define DYTC_MODE_MMC_BALANCE 0xF /* Default mode aka balanced */10313#define DYTC_MODE_MMC_DEFAULT 0 /* Default mode from MMC_GET, aka balanced */10314 10315#define DYTC_MODE_PSC_LOWPOWER 3 /* Low power mode */10316#define DYTC_MODE_PSC_BALANCE 5 /* Default mode aka balanced */10317#define DYTC_MODE_PSC_PERFORM 7 /* High power mode aka performance */10318 10319#define DYTC_ERR_MASK 0xF /* Bits 0-3 in cmd result are the error result */10320#define DYTC_ERR_SUCCESS 1 /* CMD completed successful */10321 10322#define DYTC_SET_COMMAND(function, mode, on) \10323 (DYTC_CMD_SET | (function) << DYTC_SET_FUNCTION_BIT | \10324 (mode) << DYTC_SET_MODE_BIT | \10325 (on) << DYTC_SET_VALID_BIT)10326 10327#define DYTC_DISABLE_CQL DYTC_SET_COMMAND(DYTC_FUNCTION_CQL, DYTC_MODE_MMC_BALANCE, 0)10328#define DYTC_ENABLE_CQL DYTC_SET_COMMAND(DYTC_FUNCTION_CQL, DYTC_MODE_MMC_BALANCE, 1)10329static int dytc_control_amt(bool enable);10330static bool dytc_amt_active;10331 10332static enum platform_profile_option dytc_current_profile;10333static atomic_t dytc_ignore_event = ATOMIC_INIT(0);10334static DEFINE_MUTEX(dytc_mutex);10335static int dytc_capabilities;10336static bool dytc_mmc_get_available;10337static int profile_force;10338 10339static int convert_dytc_to_profile(int funcmode, int dytcmode,10340 enum platform_profile_option *profile)10341{10342 switch (funcmode) {10343 case DYTC_FUNCTION_MMC:10344 switch (dytcmode) {10345 case DYTC_MODE_MMC_LOWPOWER:10346 *profile = PLATFORM_PROFILE_LOW_POWER;10347 break;10348 case DYTC_MODE_MMC_DEFAULT:10349 case DYTC_MODE_MMC_BALANCE:10350 *profile = PLATFORM_PROFILE_BALANCED;10351 break;10352 case DYTC_MODE_MMC_PERFORM:10353 *profile = PLATFORM_PROFILE_PERFORMANCE;10354 break;10355 default: /* Unknown mode */10356 return -EINVAL;10357 }10358 return 0;10359 case DYTC_FUNCTION_PSC:10360 switch (dytcmode) {10361 case DYTC_MODE_PSC_LOWPOWER:10362 *profile = PLATFORM_PROFILE_LOW_POWER;10363 break;10364 case DYTC_MODE_PSC_BALANCE:10365 *profile = PLATFORM_PROFILE_BALANCED;10366 break;10367 case DYTC_MODE_PSC_PERFORM:10368 *profile = PLATFORM_PROFILE_PERFORMANCE;10369 break;10370 default: /* Unknown mode */10371 return -EINVAL;10372 }10373 return 0;10374 case DYTC_FUNCTION_AMT:10375 /* For now return balanced. It's the closest we have to 'auto' */10376 *profile = PLATFORM_PROFILE_BALANCED;10377 return 0;10378 default:10379 /* Unknown function */10380 pr_debug("unknown function 0x%x\n", funcmode);10381 return -EOPNOTSUPP;10382 }10383 return 0;10384}10385 10386static int convert_profile_to_dytc(enum platform_profile_option profile, int *perfmode)10387{10388 switch (profile) {10389 case PLATFORM_PROFILE_LOW_POWER:10390 if (dytc_capabilities & BIT(DYTC_FC_MMC))10391 *perfmode = DYTC_MODE_MMC_LOWPOWER;10392 else if (dytc_capabilities & BIT(DYTC_FC_PSC))10393 *perfmode = DYTC_MODE_PSC_LOWPOWER;10394 break;10395 case PLATFORM_PROFILE_BALANCED:10396 if (dytc_capabilities & BIT(DYTC_FC_MMC))10397 *perfmode = DYTC_MODE_MMC_BALANCE;10398 else if (dytc_capabilities & BIT(DYTC_FC_PSC))10399 *perfmode = DYTC_MODE_PSC_BALANCE;10400 break;10401 case PLATFORM_PROFILE_PERFORMANCE:10402 if (dytc_capabilities & BIT(DYTC_FC_MMC))10403 *perfmode = DYTC_MODE_MMC_PERFORM;10404 else if (dytc_capabilities & BIT(DYTC_FC_PSC))10405 *perfmode = DYTC_MODE_PSC_PERFORM;10406 break;10407 default: /* Unknown profile */10408 return -EOPNOTSUPP;10409 }10410 return 0;10411}10412 10413/*10414 * dytc_profile_get: Function to register with platform_profile10415 * handler. Returns current platform profile.10416 */10417static int dytc_profile_get(struct platform_profile_handler *pprof,10418 enum platform_profile_option *profile)10419{10420 *profile = dytc_current_profile;10421 return 0;10422}10423 10424static int dytc_control_amt(bool enable)10425{10426 int dummy;10427 int err;10428 int cmd;10429 10430 if (!(dytc_capabilities & BIT(DYTC_FC_AMT))) {10431 pr_warn("Attempting to toggle AMT on a system that doesn't advertise support\n");10432 return -ENODEV;10433 }10434 10435 if (enable)10436 cmd = DYTC_SET_COMMAND(DYTC_FUNCTION_AMT, DYTC_MODE_AMT_ENABLE, enable);10437 else10438 cmd = DYTC_SET_COMMAND(DYTC_FUNCTION_AMT, DYTC_MODE_AMT_DISABLE, enable);10439 10440 pr_debug("%sabling AMT (cmd 0x%x)", enable ? "en":"dis", cmd);10441 err = dytc_command(cmd, &dummy);10442 if (err)10443 return err;10444 dytc_amt_active = enable;10445 return 0;10446}10447 10448/*10449 * Helper function - check if we are in CQL mode and if we are10450 * - disable CQL,10451 * - run the command10452 * - enable CQL10453 * If not in CQL mode, just run the command10454 */10455static int dytc_cql_command(int command, int *output)10456{10457 int err, cmd_err, dummy;10458 int cur_funcmode;10459 10460 /* Determine if we are in CQL mode. This alters the commands we do */10461 err = dytc_command(DYTC_CMD_GET, output);10462 if (err)10463 return err;10464 10465 cur_funcmode = (*output >> DYTC_GET_FUNCTION_BIT) & 0xF;10466 /* Check if we're OK to return immediately */10467 if ((command == DYTC_CMD_GET) && (cur_funcmode != DYTC_FUNCTION_CQL))10468 return 0;10469 10470 if (cur_funcmode == DYTC_FUNCTION_CQL) {10471 atomic_inc(&dytc_ignore_event);10472 err = dytc_command(DYTC_DISABLE_CQL, &dummy);10473 if (err)10474 return err;10475 }10476 10477 cmd_err = dytc_command(command, output);10478 /* Check return condition after we've restored CQL state */10479 10480 if (cur_funcmode == DYTC_FUNCTION_CQL) {10481 err = dytc_command(DYTC_ENABLE_CQL, &dummy);10482 if (err)10483 return err;10484 }10485 return cmd_err;10486}10487 10488/*10489 * dytc_profile_set: Function to register with platform_profile10490 * handler. Sets current platform profile.10491 */10492static int dytc_profile_set(struct platform_profile_handler *pprof,10493 enum platform_profile_option profile)10494{10495 int perfmode;10496 int output;10497 int err;10498 10499 err = mutex_lock_interruptible(&dytc_mutex);10500 if (err)10501 return err;10502 10503 err = convert_profile_to_dytc(profile, &perfmode);10504 if (err)10505 goto unlock;10506 10507 if (dytc_capabilities & BIT(DYTC_FC_MMC)) {10508 if (profile == PLATFORM_PROFILE_BALANCED) {10509 /*10510 * To get back to balanced mode we need to issue a reset command.10511 * Note we still need to disable CQL mode before hand and re-enable10512 * it afterwards, otherwise dytc_lapmode gets reset to 0 and stays10513 * stuck at 0 for aprox. 30 minutes.10514 */10515 err = dytc_cql_command(DYTC_CMD_RESET, &output);10516 if (err)10517 goto unlock;10518 } else {10519 /* Determine if we are in CQL mode. This alters the commands we do */10520 err = dytc_cql_command(DYTC_SET_COMMAND(DYTC_FUNCTION_MMC, perfmode, 1),10521 &output);10522 if (err)10523 goto unlock;10524 }10525 } else if (dytc_capabilities & BIT(DYTC_FC_PSC)) {10526 err = dytc_command(DYTC_SET_COMMAND(DYTC_FUNCTION_PSC, perfmode, 1), &output);10527 if (err)10528 goto unlock;10529 10530 /* system supports AMT, activate it when on balanced */10531 if (dytc_capabilities & BIT(DYTC_FC_AMT))10532 dytc_control_amt(profile == PLATFORM_PROFILE_BALANCED);10533 }10534 /* Success - update current profile */10535 dytc_current_profile = profile;10536unlock:10537 mutex_unlock(&dytc_mutex);10538 return err;10539}10540 10541static void dytc_profile_refresh(void)10542{10543 enum platform_profile_option profile;10544 int output = 0, err = 0;10545 int perfmode, funcmode = 0;10546 10547 mutex_lock(&dytc_mutex);10548 if (dytc_capabilities & BIT(DYTC_FC_MMC)) {10549 if (dytc_mmc_get_available)10550 err = dytc_command(DYTC_CMD_MMC_GET, &output);10551 else10552 err = dytc_cql_command(DYTC_CMD_GET, &output);10553 funcmode = DYTC_FUNCTION_MMC;10554 } else if (dytc_capabilities & BIT(DYTC_FC_PSC)) {10555 err = dytc_command(DYTC_CMD_GET, &output);10556 /* Check if we are PSC mode, or have AMT enabled */10557 funcmode = (output >> DYTC_GET_FUNCTION_BIT) & 0xF;10558 } else { /* Unknown profile mode */10559 err = -ENODEV;10560 }10561 mutex_unlock(&dytc_mutex);10562 if (err)10563 return;10564 10565 perfmode = (output >> DYTC_GET_MODE_BIT) & 0xF;10566 err = convert_dytc_to_profile(funcmode, perfmode, &profile);10567 if (!err && profile != dytc_current_profile) {10568 dytc_current_profile = profile;10569 platform_profile_notify();10570 }10571}10572 10573static struct platform_profile_handler dytc_profile = {10574 .profile_get = dytc_profile_get,10575 .profile_set = dytc_profile_set,10576};10577 10578static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)10579{10580 int err, output;10581 10582 /* Setup supported modes */10583 set_bit(PLATFORM_PROFILE_LOW_POWER, dytc_profile.choices);10584 set_bit(PLATFORM_PROFILE_BALANCED, dytc_profile.choices);10585 set_bit(PLATFORM_PROFILE_PERFORMANCE, dytc_profile.choices);10586 10587 err = dytc_command(DYTC_CMD_QUERY, &output);10588 if (err)10589 return err;10590 10591 if (output & BIT(DYTC_QUERY_ENABLE_BIT))10592 dytc_version = (output >> DYTC_QUERY_REV_BIT) & 0xF;10593 10594 /* Check DYTC is enabled and supports mode setting */10595 if (dytc_version < 5)10596 return -ENODEV;10597 10598 /* Check what capabilities are supported */10599 err = dytc_command(DYTC_CMD_FUNC_CAP, &dytc_capabilities);10600 if (err)10601 return err;10602 10603 /* Check if user wants to override the profile selection */10604 if (profile_force) {10605 switch (profile_force) {10606 case -1:10607 dytc_capabilities = 0;10608 break;10609 case 1:10610 dytc_capabilities = BIT(DYTC_FC_MMC);10611 break;10612 case 2:10613 dytc_capabilities = BIT(DYTC_FC_PSC);10614 break;10615 }10616 pr_debug("Profile selection forced: 0x%x\n", dytc_capabilities);10617 }10618 if (dytc_capabilities & BIT(DYTC_FC_MMC)) { /* MMC MODE */10619 pr_debug("MMC is supported\n");10620 /*10621 * Check if MMC_GET functionality available10622 * Version > 6 and return success from MMC_GET command10623 */10624 dytc_mmc_get_available = false;10625 if (dytc_version >= 6) {10626 err = dytc_command(DYTC_CMD_MMC_GET, &output);10627 if (!err && ((output & DYTC_ERR_MASK) == DYTC_ERR_SUCCESS))10628 dytc_mmc_get_available = true;10629 }10630 } else if (dytc_capabilities & BIT(DYTC_FC_PSC)) { /* PSC MODE */10631 pr_debug("PSC is supported\n");10632 } else {10633 dbg_printk(TPACPI_DBG_INIT, "No DYTC support available\n");10634 return -ENODEV;10635 }10636 10637 dbg_printk(TPACPI_DBG_INIT,10638 "DYTC version %d: thermal mode available\n", dytc_version);10639 10640 /* Create platform_profile structure and register */10641 err = platform_profile_register(&dytc_profile);10642 /*10643 * If for some reason platform_profiles aren't enabled10644 * don't quit terminally.10645 */10646 if (err)10647 return -ENODEV;10648 10649 /* Ensure initial values are correct */10650 dytc_profile_refresh();10651 10652 /* Workaround for https://bugzilla.kernel.org/show_bug.cgi?id=216347 */10653 if (dytc_capabilities & BIT(DYTC_FC_PSC))10654 dytc_profile_set(NULL, PLATFORM_PROFILE_BALANCED);10655 10656 return 0;10657}10658 10659static void dytc_profile_exit(void)10660{10661 platform_profile_remove();10662}10663 10664static struct ibm_struct dytc_profile_driver_data = {10665 .name = "dytc-profile",10666 .exit = dytc_profile_exit,10667};10668 10669/*************************************************************************10670 * Keyboard language interface10671 */10672 10673struct keyboard_lang_data {10674 const char *lang_str;10675 int lang_code;10676};10677 10678static const struct keyboard_lang_data keyboard_lang_data[] = {10679 {"be", 0x080c},10680 {"cz", 0x0405},10681 {"da", 0x0406},10682 {"de", 0x0c07},10683 {"en", 0x0000},10684 {"es", 0x2c0a},10685 {"et", 0x0425},10686 {"fr", 0x040c},10687 {"fr-ch", 0x100c},10688 {"hu", 0x040e},10689 {"it", 0x0410},10690 {"jp", 0x0411},10691 {"nl", 0x0413},10692 {"nn", 0x0414},10693 {"pl", 0x0415},10694 {"pt", 0x0816},10695 {"sl", 0x041b},10696 {"sv", 0x081d},10697 {"tr", 0x041f},10698};10699 10700static int set_keyboard_lang_command(int command)10701{10702 acpi_handle sskl_handle;10703 int output;10704 10705 if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "SSKL", &sskl_handle))) {10706 /* Platform doesn't support SSKL */10707 return -ENODEV;10708 }10709 10710 if (!acpi_evalf(sskl_handle, &output, NULL, "dd", command))10711 return -EIO;10712 10713 return 0;10714}10715 10716static int get_keyboard_lang(int *output)10717{10718 acpi_handle gskl_handle;10719 int kbd_lang;10720 10721 if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "GSKL", &gskl_handle))) {10722 /* Platform doesn't support GSKL */10723 return -ENODEV;10724 }10725 10726 if (!acpi_evalf(gskl_handle, &kbd_lang, NULL, "dd", 0x02000000))10727 return -EIO;10728 10729 /*10730 * METHOD_ERR gets returned on devices where there are no special (e.g. '=',10731 * '(' and ')') keys which use layout dependent key-press emulation.10732 */10733 if (kbd_lang & METHOD_ERR)10734 return -ENODEV;10735 10736 *output = kbd_lang;10737 10738 return 0;10739}10740 10741/* sysfs keyboard language entry */10742static ssize_t keyboard_lang_show(struct device *dev,10743 struct device_attribute *attr,10744 char *buf)10745{10746 int output, err, i, len = 0;10747 10748 err = get_keyboard_lang(&output);10749 if (err)10750 return err;10751 10752 for (i = 0; i < ARRAY_SIZE(keyboard_lang_data); i++) {10753 if (i)10754 len += sysfs_emit_at(buf, len, "%s", " ");10755 10756 if (output == keyboard_lang_data[i].lang_code) {10757 len += sysfs_emit_at(buf, len, "[%s]", keyboard_lang_data[i].lang_str);10758 } else {10759 len += sysfs_emit_at(buf, len, "%s", keyboard_lang_data[i].lang_str);10760 }10761 }10762 len += sysfs_emit_at(buf, len, "\n");10763 10764 return len;10765}10766 10767static ssize_t keyboard_lang_store(struct device *dev,10768 struct device_attribute *attr,10769 const char *buf, size_t count)10770{10771 int err, i;10772 bool lang_found = false;10773 int lang_code = 0;10774 10775 for (i = 0; i < ARRAY_SIZE(keyboard_lang_data); i++) {10776 if (sysfs_streq(buf, keyboard_lang_data[i].lang_str)) {10777 lang_code = keyboard_lang_data[i].lang_code;10778 lang_found = true;10779 break;10780 }10781 }10782 10783 if (lang_found) {10784 lang_code = lang_code | 1 << 24;10785 10786 /* Set language code */10787 err = set_keyboard_lang_command(lang_code);10788 if (err)10789 return err;10790 } else {10791 dev_err(&tpacpi_pdev->dev, "Unknown Keyboard language. Ignoring\n");10792 return -EINVAL;10793 }10794 10795 tpacpi_disclose_usertask(attr->attr.name,10796 "keyboard language is set to %s\n", buf);10797 10798 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, "keyboard_lang");10799 10800 return count;10801}10802static DEVICE_ATTR_RW(keyboard_lang);10803 10804static struct attribute *kbdlang_attributes[] = {10805 &dev_attr_keyboard_lang.attr,10806 NULL10807};10808 10809static umode_t kbdlang_attr_is_visible(struct kobject *kobj,10810 struct attribute *attr, int n)10811{10812 return tp_features.kbd_lang ? attr->mode : 0;10813}10814 10815static const struct attribute_group kbdlang_attr_group = {10816 .is_visible = kbdlang_attr_is_visible,10817 .attrs = kbdlang_attributes,10818};10819 10820static int tpacpi_kbdlang_init(struct ibm_init_struct *iibm)10821{10822 int err, output;10823 10824 err = get_keyboard_lang(&output);10825 tp_features.kbd_lang = !err;10826 return err;10827}10828 10829static struct ibm_struct kbdlang_driver_data = {10830 .name = "kbdlang",10831};10832 10833/*************************************************************************10834 * DPRC(Dynamic Power Reduction Control) subdriver, for the Lenovo WWAN10835 * and WLAN feature.10836 */10837#define DPRC_GET_WWAN_ANTENNA_TYPE 0x4000010838#define DPRC_WWAN_ANTENNA_TYPE_A_BIT BIT(4)10839#define DPRC_WWAN_ANTENNA_TYPE_B_BIT BIT(8)10840static bool has_antennatype;10841static int wwan_antennatype;10842 10843static int dprc_command(int command, int *output)10844{10845 acpi_handle dprc_handle;10846 10847 if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "DPRC", &dprc_handle))) {10848 /* Platform doesn't support DPRC */10849 return -ENODEV;10850 }10851 10852 if (!acpi_evalf(dprc_handle, output, NULL, "dd", command))10853 return -EIO;10854 10855 /*10856 * METHOD_ERR gets returned on devices where few commands are not supported10857 * for example command to get WWAN Antenna type command is not supported on10858 * some devices.10859 */10860 if (*output & METHOD_ERR)10861 return -ENODEV;10862 10863 return 0;10864}10865 10866static int get_wwan_antenna(int *wwan_antennatype)10867{10868 int output, err;10869 10870 /* Get current Antenna type */10871 err = dprc_command(DPRC_GET_WWAN_ANTENNA_TYPE, &output);10872 if (err)10873 return err;10874 10875 if (output & DPRC_WWAN_ANTENNA_TYPE_A_BIT)10876 *wwan_antennatype = 1;10877 else if (output & DPRC_WWAN_ANTENNA_TYPE_B_BIT)10878 *wwan_antennatype = 2;10879 else10880 return -ENODEV;10881 10882 return 0;10883}10884 10885/* sysfs wwan antenna type entry */10886static ssize_t wwan_antenna_type_show(struct device *dev,10887 struct device_attribute *attr,10888 char *buf)10889{10890 switch (wwan_antennatype) {10891 case 1:10892 return sysfs_emit(buf, "type a\n");10893 case 2:10894 return sysfs_emit(buf, "type b\n");10895 default:10896 return -ENODATA;10897 }10898}10899static DEVICE_ATTR_RO(wwan_antenna_type);10900 10901static struct attribute *dprc_attributes[] = {10902 &dev_attr_wwan_antenna_type.attr,10903 NULL10904};10905 10906static umode_t dprc_attr_is_visible(struct kobject *kobj,10907 struct attribute *attr, int n)10908{10909 return has_antennatype ? attr->mode : 0;10910}10911 10912static const struct attribute_group dprc_attr_group = {10913 .is_visible = dprc_attr_is_visible,10914 .attrs = dprc_attributes,10915};10916 10917static int tpacpi_dprc_init(struct ibm_init_struct *iibm)10918{10919 int err;10920 10921 err = get_wwan_antenna(&wwan_antennatype);10922 if (err)10923 return err;10924 10925 has_antennatype = true;10926 return 0;10927}10928 10929static struct ibm_struct dprc_driver_data = {10930 .name = "dprc",10931};10932 10933/*10934 * Auxmac10935 *10936 * This auxiliary mac address is enabled in the bios through the10937 * MAC Address Pass-through feature. In most cases, there are three10938 * possibilities: Internal Mac, Second Mac, and disabled.10939 *10940 */10941 10942#define AUXMAC_LEN 1210943#define AUXMAC_START 910944#define AUXMAC_STRLEN 2210945#define AUXMAC_BEGIN_MARKER 810946#define AUXMAC_END_MARKER 2110947 10948static char auxmac[AUXMAC_LEN + 1];10949 10950static int auxmac_init(struct ibm_init_struct *iibm)10951{10952 acpi_status status;10953 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };10954 union acpi_object *obj;10955 10956 status = acpi_evaluate_object(NULL, "\\MACA", NULL, &buffer);10957 10958 if (ACPI_FAILURE(status))10959 return -ENODEV;10960 10961 obj = buffer.pointer;10962 10963 if (obj->type != ACPI_TYPE_STRING || obj->string.length != AUXMAC_STRLEN) {10964 pr_info("Invalid buffer for MAC address pass-through.\n");10965 goto auxmacinvalid;10966 }10967 10968 if (obj->string.pointer[AUXMAC_BEGIN_MARKER] != '#' ||10969 obj->string.pointer[AUXMAC_END_MARKER] != '#') {10970 pr_info("Invalid header for MAC address pass-through.\n");10971 goto auxmacinvalid;10972 }10973 10974 if (strncmp(obj->string.pointer + AUXMAC_START, "XXXXXXXXXXXX", AUXMAC_LEN) != 0)10975 strscpy(auxmac, obj->string.pointer + AUXMAC_START, sizeof(auxmac));10976 else10977 strscpy(auxmac, "disabled", sizeof(auxmac));10978 10979free:10980 kfree(obj);10981 return 0;10982 10983auxmacinvalid:10984 strscpy(auxmac, "unavailable", sizeof(auxmac));10985 goto free;10986}10987 10988static struct ibm_struct auxmac_data = {10989 .name = "auxmac",10990};10991 10992static DEVICE_STRING_ATTR_RO(auxmac, 0444, auxmac);10993 10994static umode_t auxmac_attr_is_visible(struct kobject *kobj,10995 struct attribute *attr, int n)10996{10997 return auxmac[0] == 0 ? 0 : attr->mode;10998}10999 11000static struct attribute *auxmac_attributes[] = {11001 &dev_attr_auxmac.attr.attr,11002 NULL11003};11004 11005static const struct attribute_group auxmac_attr_group = {11006 .is_visible = auxmac_attr_is_visible,11007 .attrs = auxmac_attributes,11008};11009 11010/* --------------------------------------------------------------------- */11011 11012static struct attribute *tpacpi_driver_attributes[] = {11013 &driver_attr_debug_level.attr,11014 &driver_attr_version.attr,11015 &driver_attr_interface_version.attr,11016#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES11017 &driver_attr_wlsw_emulstate.attr,11018 &driver_attr_bluetooth_emulstate.attr,11019 &driver_attr_wwan_emulstate.attr,11020 &driver_attr_uwb_emulstate.attr,11021#endif11022 NULL11023};11024 11025#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES11026static umode_t tpacpi_attr_is_visible(struct kobject *kobj,11027 struct attribute *attr, int n)11028{11029 if (attr == &driver_attr_wlsw_emulstate.attr) {11030 if (!dbg_wlswemul)11031 return 0;11032 } else if (attr == &driver_attr_bluetooth_emulstate.attr) {11033 if (!dbg_bluetoothemul)11034 return 0;11035 } else if (attr == &driver_attr_wwan_emulstate.attr) {11036 if (!dbg_wwanemul)11037 return 0;11038 } else if (attr == &driver_attr_uwb_emulstate.attr) {11039 if (!dbg_uwbemul)11040 return 0;11041 }11042 11043 return attr->mode;11044}11045#endif11046 11047static const struct attribute_group tpacpi_driver_attr_group = {11048#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES11049 .is_visible = tpacpi_attr_is_visible,11050#endif11051 .attrs = tpacpi_driver_attributes,11052};11053 11054static const struct attribute_group *tpacpi_driver_groups[] = {11055 &tpacpi_driver_attr_group,11056 NULL,11057};11058 11059static const struct attribute_group *tpacpi_groups[] = {11060 &adaptive_kbd_attr_group,11061 &hotkey_attr_group,11062 &bluetooth_attr_group,11063 &wan_attr_group,11064 &cmos_attr_group,11065 &proxsensor_attr_group,11066 &kbdlang_attr_group,11067 &dprc_attr_group,11068 &auxmac_attr_group,11069 NULL,11070};11071 11072static const struct attribute_group *tpacpi_hwmon_groups[] = {11073 &thermal_attr_group,11074 &temp_label_attr_group,11075 &fan_attr_group,11076 NULL,11077};11078 11079static const struct attribute_group *tpacpi_hwmon_driver_groups[] = {11080 &fan_driver_attr_group,11081 NULL,11082};11083 11084/****************************************************************************11085 ****************************************************************************11086 *11087 * Platform drivers11088 *11089 ****************************************************************************11090 ****************************************************************************/11091 11092static struct platform_driver tpacpi_pdriver = {11093 .driver = {11094 .name = TPACPI_DRVR_NAME,11095 .pm = &tpacpi_pm,11096 .groups = tpacpi_driver_groups,11097 .dev_groups = tpacpi_groups,11098 },11099 .shutdown = tpacpi_shutdown_handler,11100};11101 11102static struct platform_driver tpacpi_hwmon_pdriver = {11103 .driver = {11104 .name = TPACPI_HWMON_DRVR_NAME,11105 .groups = tpacpi_hwmon_driver_groups,11106 },11107};11108 11109/****************************************************************************11110 ****************************************************************************11111 *11112 * Infrastructure11113 *11114 ****************************************************************************11115 ****************************************************************************/11116 11117/*11118 * HKEY event callout for other subdrivers go here11119 * (yes, it is ugly, but it is quick, safe, and gets the job done11120 */11121static bool tpacpi_driver_event(const unsigned int hkey_event)11122{11123 switch (hkey_event) {11124 case TP_HKEY_EV_BRGHT_UP:11125 case TP_HKEY_EV_BRGHT_DOWN:11126 if (ibm_backlight_device)11127 tpacpi_brightness_notify_change();11128 /*11129 * Key press events are suppressed by default hotkey_user_mask11130 * and should still be reported if explicitly requested.11131 */11132 return false;11133 case TP_HKEY_EV_VOL_UP:11134 case TP_HKEY_EV_VOL_DOWN:11135 case TP_HKEY_EV_VOL_MUTE:11136 if (alsa_card)11137 volume_alsa_notify_change();11138 11139 /* Key events are suppressed by default hotkey_user_mask */11140 return false;11141 case TP_HKEY_EV_KBD_LIGHT:11142 if (tp_features.kbdlight) {11143 enum led_brightness brightness;11144 11145 mutex_lock(&kbdlight_mutex);11146 11147 /*11148 * Check the brightness actually changed, setting the brightness11149 * through kbdlight_set_level() also triggers this event.11150 */11151 brightness = kbdlight_sysfs_get(NULL);11152 if (kbdlight_brightness != brightness) {11153 kbdlight_brightness = brightness;11154 led_classdev_notify_brightness_hw_changed(11155 &tpacpi_led_kbdlight.led_classdev, brightness);11156 }11157 11158 mutex_unlock(&kbdlight_mutex);11159 }11160 /* Key events are suppressed by default hotkey_user_mask */11161 return false;11162 case TP_HKEY_EV_DFR_CHANGE_ROW:11163 adaptive_keyboard_change_row();11164 return true;11165 case TP_HKEY_EV_DFR_S_QUICKVIEW_ROW:11166 adaptive_keyboard_s_quickview_row();11167 return true;11168 case TP_HKEY_EV_THM_CSM_COMPLETED:11169 lapsensor_refresh();11170 /* If we are already accessing DYTC then skip dytc update */11171 if (!atomic_add_unless(&dytc_ignore_event, -1, 0))11172 dytc_profile_refresh();11173 11174 return true;11175 case TP_HKEY_EV_PRIVACYGUARD_TOGGLE:11176 if (lcdshadow_dev) {11177 enum drm_privacy_screen_status old_hw_state;11178 bool changed;11179 11180 mutex_lock(&lcdshadow_dev->lock);11181 old_hw_state = lcdshadow_dev->hw_state;11182 lcdshadow_get_hw_state(lcdshadow_dev);11183 changed = lcdshadow_dev->hw_state != old_hw_state;11184 mutex_unlock(&lcdshadow_dev->lock);11185 11186 if (changed)11187 drm_privacy_screen_call_notifier_chain(lcdshadow_dev);11188 }11189 return true;11190 case TP_HKEY_EV_AMT_TOGGLE:11191 /* If we're enabling AMT we need to force balanced mode */11192 if (!dytc_amt_active)11193 /* This will also set AMT mode enabled */11194 dytc_profile_set(NULL, PLATFORM_PROFILE_BALANCED);11195 else11196 dytc_control_amt(!dytc_amt_active);11197 11198 return true;11199 case TP_HKEY_EV_DOUBLETAP_TOGGLE:11200 tp_features.trackpoint_doubletap = !tp_features.trackpoint_doubletap;11201 return true;11202 case TP_HKEY_EV_PROFILE_TOGGLE:11203 platform_profile_cycle();11204 return true;11205 }11206 11207 return false;11208}11209 11210/* --------------------------------------------------------------------- */11211 11212/* /proc support */11213static struct proc_dir_entry *proc_dir;11214 11215/*11216 * Module and infrastructure proble, init and exit handling11217 */11218 11219static bool force_load;11220 11221#ifdef CONFIG_THINKPAD_ACPI_DEBUG11222static const char * __init str_supported(int is_supported)11223{11224 static char text_unsupported[] __initdata = "not supported";11225 11226 return (is_supported) ? &text_unsupported[4] : &text_unsupported[0];11227}11228#endif /* CONFIG_THINKPAD_ACPI_DEBUG */11229 11230static void ibm_exit(struct ibm_struct *ibm)11231{11232 dbg_printk(TPACPI_DBG_EXIT, "removing %s\n", ibm->name);11233 11234 list_del_init(&ibm->all_drivers);11235 11236 if (ibm->flags.acpi_notify_installed) {11237 dbg_printk(TPACPI_DBG_EXIT,11238 "%s: acpi_remove_notify_handler\n", ibm->name);11239 BUG_ON(!ibm->acpi);11240 acpi_remove_notify_handler(*ibm->acpi->handle,11241 ibm->acpi->type,11242 dispatch_acpi_notify);11243 ibm->flags.acpi_notify_installed = 0;11244 }11245 11246 if (ibm->flags.proc_created) {11247 dbg_printk(TPACPI_DBG_EXIT,11248 "%s: remove_proc_entry\n", ibm->name);11249 remove_proc_entry(ibm->name, proc_dir);11250 ibm->flags.proc_created = 0;11251 }11252 11253 if (ibm->flags.acpi_driver_registered) {11254 dbg_printk(TPACPI_DBG_EXIT,11255 "%s: acpi_bus_unregister_driver\n", ibm->name);11256 BUG_ON(!ibm->acpi);11257 acpi_bus_unregister_driver(ibm->acpi->driver);11258 kfree(ibm->acpi->driver);11259 ibm->acpi->driver = NULL;11260 ibm->flags.acpi_driver_registered = 0;11261 }11262 11263 if (ibm->flags.init_called && ibm->exit) {11264 ibm->exit();11265 ibm->flags.init_called = 0;11266 }11267 11268 dbg_printk(TPACPI_DBG_INIT, "finished removing %s\n", ibm->name);11269}11270 11271static int __init ibm_init(struct ibm_init_struct *iibm)11272{11273 int ret;11274 struct ibm_struct *ibm = iibm->data;11275 struct proc_dir_entry *entry;11276 11277 BUG_ON(ibm == NULL);11278 11279 INIT_LIST_HEAD(&ibm->all_drivers);11280 11281 if (ibm->flags.experimental && !experimental)11282 return 0;11283 11284 dbg_printk(TPACPI_DBG_INIT,11285 "probing for %s\n", ibm->name);11286 11287 if (iibm->init) {11288 ret = iibm->init(iibm);11289 if (ret > 0 || ret == -ENODEV)11290 return 0; /* subdriver functionality not available */11291 if (ret)11292 return ret;11293 11294 ibm->flags.init_called = 1;11295 }11296 11297 if (ibm->acpi) {11298 if (ibm->acpi->hid) {11299 ret = register_tpacpi_subdriver(ibm);11300 if (ret)11301 goto err_out;11302 }11303 11304 if (ibm->acpi->notify) {11305 ret = setup_acpi_notify(ibm);11306 if (ret == -ENODEV) {11307 pr_notice("disabling subdriver %s\n",11308 ibm->name);11309 ret = 0;11310 goto err_out;11311 }11312 if (ret < 0)11313 goto err_out;11314 }11315 }11316 11317 dbg_printk(TPACPI_DBG_INIT,11318 "%s installed\n", ibm->name);11319 11320 if (ibm->read) {11321 umode_t mode = iibm->base_procfs_mode;11322 11323 if (!mode)11324 mode = S_IRUGO;11325 if (ibm->write)11326 mode |= S_IWUSR;11327 entry = proc_create_data(ibm->name, mode, proc_dir,11328 &dispatch_proc_ops, ibm);11329 if (!entry) {11330 pr_err("unable to create proc entry %s\n", ibm->name);11331 ret = -ENODEV;11332 goto err_out;11333 }11334 ibm->flags.proc_created = 1;11335 }11336 11337 list_add_tail(&ibm->all_drivers, &tpacpi_all_drivers);11338 11339 return 0;11340 11341err_out:11342 dbg_printk(TPACPI_DBG_INIT,11343 "%s: at error exit path with result %d\n",11344 ibm->name, ret);11345 11346 ibm_exit(ibm);11347 return (ret < 0) ? ret : 0;11348}11349 11350/* Probing */11351 11352static char __init tpacpi_parse_fw_id(const char * const s,11353 u32 *model, u16 *release)11354{11355 int i;11356 11357 if (!s || strlen(s) < 8)11358 goto invalid;11359 11360 for (i = 0; i < 8; i++)11361 if (!((s[i] >= '0' && s[i] <= '9') ||11362 (s[i] >= 'A' && s[i] <= 'Z')))11363 goto invalid;11364 11365 /*11366 * Most models: xxyTkkWW (#.##c)11367 * Ancient 570/600 and -SL lacks (#.##c)11368 */11369 if (s[3] == 'T' || s[3] == 'N') {11370 *model = TPID(s[0], s[1]);11371 *release = TPVER(s[4], s[5]);11372 return s[2];11373 11374 /* New models: xxxyTkkW (#.##c); T550 and some others */11375 } else if (s[4] == 'T' || s[4] == 'N') {11376 *model = TPID3(s[0], s[1], s[2]);11377 *release = TPVER(s[5], s[6]);11378 return s[3];11379 }11380 11381invalid:11382 return '\0';11383}11384 11385#define EC_FW_STRING_LEN 1811386 11387static void find_new_ec_fwstr(const struct dmi_header *dm, void *private)11388{11389 char *ec_fw_string = (char *) private;11390 const char *dmi_data = (const char *)dm;11391 /*11392 * ThinkPad Embedded Controller Program Table on newer models11393 *11394 * Offset | Name | Width | Description11395 * ----------------------------------------------------11396 * 0x00 | Type | BYTE | 0x8C11397 * 0x01 | Length | BYTE |11398 * 0x02 | Handle | WORD | Varies11399 * 0x04 | Signature | BYTEx6 | ASCII for "LENOVO"11400 * 0x0A | OEM struct offset | BYTE | 0x0B11401 * 0x0B | OEM struct number | BYTE | 0x07, for this structure11402 * 0x0C | OEM struct revision | BYTE | 0x01, for this format11403 * 0x0D | ECP version ID | STR ID |11404 * 0x0E | ECP release date | STR ID |11405 */11406 11407 /* Return if data structure not match */11408 if (dm->type != 140 || dm->length < 0x0F ||11409 memcmp(dmi_data + 4, "LENOVO", 6) != 0 ||11410 dmi_data[0x0A] != 0x0B || dmi_data[0x0B] != 0x07 ||11411 dmi_data[0x0C] != 0x01)11412 return;11413 11414 /* fwstr is the first 8byte string */11415 BUILD_BUG_ON(EC_FW_STRING_LEN <= 8);11416 memcpy(ec_fw_string, dmi_data + 0x0F, 8);11417}11418 11419/* returns 0 - probe ok, or < 0 - probe error.11420 * Probe ok doesn't mean thinkpad found.11421 * On error, kfree() cleanup on tp->* is not performed, caller must do it */11422static int __must_check __init get_thinkpad_model_data(11423 struct thinkpad_id_data *tp)11424{11425 const struct dmi_device *dev = NULL;11426 char ec_fw_string[EC_FW_STRING_LEN] = {0};11427 char const *s;11428 char t;11429 11430 if (!tp)11431 return -EINVAL;11432 11433 memset(tp, 0, sizeof(*tp));11434 11435 if (dmi_name_in_vendors("IBM"))11436 tp->vendor = PCI_VENDOR_ID_IBM;11437 else if (dmi_name_in_vendors("LENOVO"))11438 tp->vendor = PCI_VENDOR_ID_LENOVO;11439 else11440 return 0;11441 11442 s = dmi_get_system_info(DMI_BIOS_VERSION);11443 tp->bios_version_str = kstrdup(s, GFP_KERNEL);11444 if (s && !tp->bios_version_str)11445 return -ENOMEM;11446 11447 /* Really ancient ThinkPad 240X will fail this, which is fine */11448 t = tpacpi_parse_fw_id(tp->bios_version_str,11449 &tp->bios_model, &tp->bios_release);11450 if (t != 'E' && t != 'C')11451 return 0;11452 11453 /*11454 * ThinkPad T23 or newer, A31 or newer, R50e or newer,11455 * X32 or newer, all Z series; Some models must have an11456 * up-to-date BIOS or they will not be detected.11457 *11458 * See https://thinkwiki.org/wiki/List_of_DMI_IDs11459 */11460 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {11461 if (sscanf(dev->name,11462 "IBM ThinkPad Embedded Controller -[%17c",11463 ec_fw_string) == 1) {11464 ec_fw_string[sizeof(ec_fw_string) - 1] = 0;11465 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;11466 break;11467 }11468 }11469 11470 /* Newer ThinkPads have different EC program info table */11471 if (!ec_fw_string[0])11472 dmi_walk(find_new_ec_fwstr, &ec_fw_string);11473 11474 if (ec_fw_string[0]) {11475 tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL);11476 if (!tp->ec_version_str)11477 return -ENOMEM;11478 11479 t = tpacpi_parse_fw_id(ec_fw_string,11480 &tp->ec_model, &tp->ec_release);11481 if (t != 'H') {11482 pr_notice("ThinkPad firmware release %s doesn't match the known patterns\n",11483 ec_fw_string);11484 pr_notice("please report this to %s\n", TPACPI_MAIL);11485 }11486 }11487 11488 s = dmi_get_system_info(DMI_PRODUCT_VERSION);11489 if (s && !(strncasecmp(s, "ThinkPad", 8) && strncasecmp(s, "Lenovo", 6))) {11490 tp->model_str = kstrdup(s, GFP_KERNEL);11491 if (!tp->model_str)11492 return -ENOMEM;11493 } else {11494 s = dmi_get_system_info(DMI_BIOS_VENDOR);11495 if (s && !(strncasecmp(s, "Lenovo", 6))) {11496 tp->model_str = kstrdup(s, GFP_KERNEL);11497 if (!tp->model_str)11498 return -ENOMEM;11499 }11500 }11501 11502 s = dmi_get_system_info(DMI_PRODUCT_NAME);11503 tp->nummodel_str = kstrdup(s, GFP_KERNEL);11504 if (s && !tp->nummodel_str)11505 return -ENOMEM;11506 11507 return 0;11508}11509 11510static int __init probe_for_thinkpad(void)11511{11512 int is_thinkpad;11513 11514 if (acpi_disabled)11515 return -ENODEV;11516 11517 /* It would be dangerous to run the driver in this case */11518 if (!tpacpi_is_ibm() && !tpacpi_is_lenovo())11519 return -ENODEV;11520 11521 /*11522 * Non-ancient models have better DMI tagging, but very old models11523 * don't. tpacpi_is_fw_known() is a cheat to help in that case.11524 */11525 is_thinkpad = (thinkpad_id.model_str != NULL) ||11526 (thinkpad_id.ec_model != 0) ||11527 tpacpi_is_fw_known();11528 11529 /* The EC handler is required */11530 tpacpi_acpi_handle_locate("ec", TPACPI_ACPI_EC_HID, &ec_handle);11531 if (!ec_handle) {11532 if (is_thinkpad)11533 pr_err("Not yet supported ThinkPad detected!\n");11534 return -ENODEV;11535 }11536 11537 if (!is_thinkpad && !force_load)11538 return -ENODEV;11539 11540 return 0;11541}11542 11543static void __init thinkpad_acpi_init_banner(void)11544{11545 pr_info("%s v%s\n", TPACPI_DESC, TPACPI_VERSION);11546 pr_info("%s\n", TPACPI_URL);11547 11548 pr_info("ThinkPad BIOS %s, EC %s\n",11549 (thinkpad_id.bios_version_str) ?11550 thinkpad_id.bios_version_str : "unknown",11551 (thinkpad_id.ec_version_str) ?11552 thinkpad_id.ec_version_str : "unknown");11553 11554 BUG_ON(!thinkpad_id.vendor);11555 11556 if (thinkpad_id.model_str)11557 pr_info("%s %s, model %s\n",11558 (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?11559 "IBM" : ((thinkpad_id.vendor ==11560 PCI_VENDOR_ID_LENOVO) ?11561 "Lenovo" : "Unknown vendor"),11562 thinkpad_id.model_str,11563 (thinkpad_id.nummodel_str) ?11564 thinkpad_id.nummodel_str : "unknown");11565}11566 11567/* Module init, exit, parameters */11568 11569static struct ibm_init_struct ibms_init[] __initdata = {11570 {11571 .data = &thinkpad_acpi_driver_data,11572 },11573 {11574 .init = hotkey_init,11575 .data = &hotkey_driver_data,11576 },11577 {11578 .init = bluetooth_init,11579 .data = &bluetooth_driver_data,11580 },11581 {11582 .init = wan_init,11583 .data = &wan_driver_data,11584 },11585 {11586 .init = uwb_init,11587 .data = &uwb_driver_data,11588 },11589#ifdef CONFIG_THINKPAD_ACPI_VIDEO11590 {11591 .init = video_init,11592 .base_procfs_mode = S_IRUSR,11593 .data = &video_driver_data,11594 },11595#endif11596 {11597 .init = kbdlight_init,11598 .data = &kbdlight_driver_data,11599 },11600 {11601 .init = light_init,11602 .data = &light_driver_data,11603 },11604 {11605 .init = cmos_init,11606 .data = &cmos_driver_data,11607 },11608 {11609 .init = led_init,11610 .data = &led_driver_data,11611 },11612 {11613 .init = beep_init,11614 .data = &beep_driver_data,11615 },11616 {11617 .init = thermal_init,11618 .data = &thermal_driver_data,11619 },11620 {11621 .init = brightness_init,11622 .data = &brightness_driver_data,11623 },11624 {11625 .init = volume_init,11626 .data = &volume_driver_data,11627 },11628 {11629 .init = fan_init,11630 .data = &fan_driver_data,11631 },11632 {11633 .init = mute_led_init,11634 .data = &mute_led_driver_data,11635 },11636 {11637 .init = tpacpi_battery_init,11638 .data = &battery_driver_data,11639 },11640 {11641 .init = tpacpi_lcdshadow_init,11642 .data = &lcdshadow_driver_data,11643 },11644 {11645 .init = tpacpi_proxsensor_init,11646 .data = &proxsensor_driver_data,11647 },11648 {11649 .init = tpacpi_dytc_profile_init,11650 .data = &dytc_profile_driver_data,11651 },11652 {11653 .init = tpacpi_kbdlang_init,11654 .data = &kbdlang_driver_data,11655 },11656 {11657 .init = tpacpi_dprc_init,11658 .data = &dprc_driver_data,11659 },11660 {11661 .init = auxmac_init,11662 .data = &auxmac_data,11663 },11664};11665 11666static int __init set_ibm_param(const char *val, const struct kernel_param *kp)11667{11668 unsigned int i;11669 struct ibm_struct *ibm;11670 11671 if (!kp || !kp->name || !val)11672 return -EINVAL;11673 11674 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {11675 ibm = ibms_init[i].data;11676 if (!ibm || !ibm->name)11677 continue;11678 11679 if (strcmp(ibm->name, kp->name) == 0 && ibm->write) {11680 if (strlen(val) > sizeof(ibms_init[i].param) - 1)11681 return -ENOSPC;11682 strcpy(ibms_init[i].param, val);11683 return 0;11684 }11685 }11686 11687 return -EINVAL;11688}11689 11690module_param(experimental, int, 0444);11691MODULE_PARM_DESC(experimental,11692 "Enables experimental features when non-zero");11693 11694module_param_named(debug, dbg_level, uint, 0);11695MODULE_PARM_DESC(debug, "Sets debug level bit-mask");11696 11697module_param(force_load, bool, 0444);11698MODULE_PARM_DESC(force_load,11699 "Attempts to load the driver even on a mis-identified ThinkPad when true");11700 11701module_param_named(fan_control, fan_control_allowed, bool, 0444);11702MODULE_PARM_DESC(fan_control,11703 "Enables setting fan parameters features when true");11704 11705module_param_named(brightness_mode, brightness_mode, uint, 0444);11706MODULE_PARM_DESC(brightness_mode,11707 "Selects brightness control strategy: 0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM");11708 11709module_param(brightness_enable, uint, 0444);11710MODULE_PARM_DESC(brightness_enable,11711 "Enables backlight control when 1, disables when 0");11712 11713#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT11714module_param_named(volume_mode, volume_mode, uint, 0444);11715MODULE_PARM_DESC(volume_mode,11716 "Selects volume control strategy: 0=auto, 1=EC, 2=N/A, 3=EC+NVRAM");11717 11718module_param_named(volume_capabilities, volume_capabilities, uint, 0444);11719MODULE_PARM_DESC(volume_capabilities,11720 "Selects the mixer capabilities: 0=auto, 1=volume and mute, 2=mute only");11721 11722module_param_named(volume_control, volume_control_allowed, bool, 0444);11723MODULE_PARM_DESC(volume_control,11724 "Enables software override for the console audio control when true");11725 11726module_param_named(software_mute, software_mute_requested, bool, 0444);11727MODULE_PARM_DESC(software_mute,11728 "Request full software mute control");11729 11730/* ALSA module API parameters */11731module_param_named(index, alsa_index, int, 0444);11732MODULE_PARM_DESC(index, "ALSA index for the ACPI EC Mixer");11733module_param_named(id, alsa_id, charp, 0444);11734MODULE_PARM_DESC(id, "ALSA id for the ACPI EC Mixer");11735module_param_named(enable, alsa_enable, bool, 0444);11736MODULE_PARM_DESC(enable, "Enable the ALSA interface for the ACPI EC Mixer");11737#endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */11738 11739/* The module parameter can't be read back, that's why 0 is used here */11740#define TPACPI_PARAM(feature) \11741 module_param_call(feature, set_ibm_param, NULL, NULL, 0); \11742 MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command at module load, see documentation")11743 11744TPACPI_PARAM(hotkey);11745TPACPI_PARAM(bluetooth);11746TPACPI_PARAM(video);11747TPACPI_PARAM(light);11748TPACPI_PARAM(cmos);11749TPACPI_PARAM(led);11750TPACPI_PARAM(beep);11751TPACPI_PARAM(brightness);11752TPACPI_PARAM(volume);11753TPACPI_PARAM(fan);11754 11755#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES11756module_param(dbg_wlswemul, uint, 0444);11757MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation");11758module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0);11759MODULE_PARM_DESC(wlsw_state,11760 "Initial state of the emulated WLSW switch");11761 11762module_param(dbg_bluetoothemul, uint, 0444);11763MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation");11764module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0);11765MODULE_PARM_DESC(bluetooth_state,11766 "Initial state of the emulated bluetooth switch");11767 11768module_param(dbg_wwanemul, uint, 0444);11769MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation");11770module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0);11771MODULE_PARM_DESC(wwan_state,11772 "Initial state of the emulated WWAN switch");11773 11774module_param(dbg_uwbemul, uint, 0444);11775MODULE_PARM_DESC(dbg_uwbemul, "Enables UWB switch emulation");11776module_param_named(uwb_state, tpacpi_uwb_emulstate, bool, 0);11777MODULE_PARM_DESC(uwb_state,11778 "Initial state of the emulated UWB switch");11779#endif11780 11781module_param(profile_force, int, 0444);11782MODULE_PARM_DESC(profile_force, "Force profile mode. -1=off, 1=MMC, 2=PSC");11783 11784static void thinkpad_acpi_module_exit(void)11785{11786 struct ibm_struct *ibm, *itmp;11787 11788 tpacpi_lifecycle = TPACPI_LIFE_EXITING;11789 11790 if (tpacpi_hwmon)11791 hwmon_device_unregister(tpacpi_hwmon);11792 if (tp_features.sensors_pdrv_registered)11793 platform_driver_unregister(&tpacpi_hwmon_pdriver);11794 if (tp_features.platform_drv_registered)11795 platform_driver_unregister(&tpacpi_pdriver);11796 11797 list_for_each_entry_safe_reverse(ibm, itmp,11798 &tpacpi_all_drivers,11799 all_drivers) {11800 ibm_exit(ibm);11801 }11802 11803 dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");11804 11805 if (tpacpi_inputdev) {11806 if (tp_features.input_device_registered)11807 input_unregister_device(tpacpi_inputdev);11808 else11809 input_free_device(tpacpi_inputdev);11810 }11811 11812 if (tpacpi_sensors_pdev)11813 platform_device_unregister(tpacpi_sensors_pdev);11814 if (tpacpi_pdev)11815 platform_device_unregister(tpacpi_pdev);11816 if (proc_dir)11817 remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir);11818 if (tpacpi_wq)11819 destroy_workqueue(tpacpi_wq);11820 11821 kfree(thinkpad_id.bios_version_str);11822 kfree(thinkpad_id.ec_version_str);11823 kfree(thinkpad_id.model_str);11824 kfree(thinkpad_id.nummodel_str);11825}11826 11827 11828static int __init thinkpad_acpi_module_init(void)11829{11830 const struct dmi_system_id *dmi_id;11831 int ret, i;11832 acpi_object_type obj_type;11833 11834 tpacpi_lifecycle = TPACPI_LIFE_INIT;11835 11836 /* Driver-level probe */11837 11838 ret = get_thinkpad_model_data(&thinkpad_id);11839 if (ret) {11840 pr_err("unable to get DMI data: %d\n", ret);11841 thinkpad_acpi_module_exit();11842 return ret;11843 }11844 ret = probe_for_thinkpad();11845 if (ret) {11846 thinkpad_acpi_module_exit();11847 return ret;11848 }11849 11850 /* Driver initialization */11851 11852 thinkpad_acpi_init_banner();11853 tpacpi_check_outdated_fw();11854 11855 TPACPI_ACPIHANDLE_INIT(ecrd);11856 TPACPI_ACPIHANDLE_INIT(ecwr);11857 11858 /*11859 * Quirk: in some models (e.g. X380 Yoga), an object named ECRD11860 * exists, but it is a register, not a method.11861 */11862 if (ecrd_handle) {11863 acpi_get_type(ecrd_handle, &obj_type);11864 if (obj_type != ACPI_TYPE_METHOD)11865 ecrd_handle = NULL;11866 }11867 if (ecwr_handle) {11868 acpi_get_type(ecwr_handle, &obj_type);11869 if (obj_type != ACPI_TYPE_METHOD)11870 ecwr_handle = NULL;11871 }11872 11873 tpacpi_wq = create_singlethread_workqueue(TPACPI_WORKQUEUE_NAME);11874 if (!tpacpi_wq) {11875 thinkpad_acpi_module_exit();11876 return -ENOMEM;11877 }11878 11879 proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir);11880 if (!proc_dir) {11881 pr_err("unable to create proc dir " TPACPI_PROC_DIR "\n");11882 thinkpad_acpi_module_exit();11883 return -ENODEV;11884 }11885 11886 dmi_id = dmi_first_match(fwbug_list);11887 if (dmi_id)11888 tp_features.quirks = dmi_id->driver_data;11889 11890 /* Device initialization */11891 tpacpi_pdev = platform_device_register_simple(TPACPI_DRVR_NAME, PLATFORM_DEVID_NONE,11892 NULL, 0);11893 if (IS_ERR(tpacpi_pdev)) {11894 ret = PTR_ERR(tpacpi_pdev);11895 tpacpi_pdev = NULL;11896 pr_err("unable to register platform device\n");11897 thinkpad_acpi_module_exit();11898 return ret;11899 }11900 tpacpi_sensors_pdev = platform_device_register_simple(11901 TPACPI_HWMON_DRVR_NAME,11902 PLATFORM_DEVID_NONE, NULL, 0);11903 if (IS_ERR(tpacpi_sensors_pdev)) {11904 ret = PTR_ERR(tpacpi_sensors_pdev);11905 tpacpi_sensors_pdev = NULL;11906 pr_err("unable to register hwmon platform device\n");11907 thinkpad_acpi_module_exit();11908 return ret;11909 }11910 11911 mutex_init(&tpacpi_inputdev_send_mutex);11912 tpacpi_inputdev = input_allocate_device();11913 if (!tpacpi_inputdev) {11914 thinkpad_acpi_module_exit();11915 return -ENOMEM;11916 } else {11917 /* Prepare input device, but don't register */11918 tpacpi_inputdev->name = "ThinkPad Extra Buttons";11919 tpacpi_inputdev->phys = TPACPI_DRVR_NAME "/input0";11920 tpacpi_inputdev->id.bustype = BUS_HOST;11921 tpacpi_inputdev->id.vendor = thinkpad_id.vendor;11922 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;11923 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;11924 tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev;11925 }11926 11927 /* Init subdriver dependencies */11928 tpacpi_detect_brightness_capabilities();11929 11930 /* Init subdrivers */11931 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {11932 ret = ibm_init(&ibms_init[i]);11933 if (ret >= 0 && *ibms_init[i].param)11934 ret = ibms_init[i].data->write(ibms_init[i].param);11935 if (ret < 0) {11936 thinkpad_acpi_module_exit();11937 return ret;11938 }11939 }11940 11941 tpacpi_lifecycle = TPACPI_LIFE_RUNNING;11942 11943 ret = platform_driver_register(&tpacpi_pdriver);11944 if (ret) {11945 pr_err("unable to register main platform driver\n");11946 thinkpad_acpi_module_exit();11947 return ret;11948 }11949 tp_features.platform_drv_registered = 1;11950 11951 ret = platform_driver_register(&tpacpi_hwmon_pdriver);11952 if (ret) {11953 pr_err("unable to register hwmon platform driver\n");11954 thinkpad_acpi_module_exit();11955 return ret;11956 }11957 tp_features.sensors_pdrv_registered = 1;11958 11959 tpacpi_hwmon = hwmon_device_register_with_groups(11960 &tpacpi_sensors_pdev->dev, TPACPI_NAME, NULL, tpacpi_hwmon_groups);11961 if (IS_ERR(tpacpi_hwmon)) {11962 ret = PTR_ERR(tpacpi_hwmon);11963 tpacpi_hwmon = NULL;11964 pr_err("unable to register hwmon device\n");11965 thinkpad_acpi_module_exit();11966 return ret;11967 }11968 11969 ret = input_register_device(tpacpi_inputdev);11970 if (ret < 0) {11971 pr_err("unable to register input device\n");11972 thinkpad_acpi_module_exit();11973 return ret;11974 } else {11975 tp_features.input_device_registered = 1;11976 }11977 11978 return 0;11979}11980 11981MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);11982 11983/*11984 * This will autoload the driver in almost every ThinkPad11985 * in widespread use.11986 *11987 * Only _VERY_ old models, like the 240, 240x and 570 lack11988 * the HKEY event interface.11989 */11990MODULE_DEVICE_TABLE(acpi, ibm_htk_device_ids);11991 11992/*11993 * DMI matching for module autoloading11994 *11995 * See https://thinkwiki.org/wiki/List_of_DMI_IDs11996 * See https://thinkwiki.org/wiki/BIOS_Upgrade_Downloads11997 *11998 * Only models listed in thinkwiki will be supported, so add yours11999 * if it is not there yet.12000 */12001#define IBM_BIOS_MODULE_ALIAS(__type) \12002 MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW*")12003 12004/* Ancient thinkpad BIOSes have to be identified by12005 * BIOS type or model number, and there are far less12006 * BIOS types than model numbers... */12007IBM_BIOS_MODULE_ALIAS("I[MU]"); /* 570, 570e */12008 12009MODULE_AUTHOR("Borislav Deianov <borislav@users.sf.net>");12010MODULE_AUTHOR("Henrique de Moraes Holschuh <hmh@hmh.eng.br>");12011MODULE_DESCRIPTION(TPACPI_DESC);12012MODULE_VERSION(TPACPI_VERSION);12013MODULE_LICENSE("GPL");12014 12015module_init(thinkpad_acpi_module_init);12016module_exit(thinkpad_acpi_module_exit);12017