thinkpad_acpi.c revision 877d03105d04b2c13e241130277fa69c8d2564f0
1/* 2 * thinkpad_acpi.c - ThinkPad ACPI Extras 3 * 4 * 5 * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net> 6 * Copyright (C) 2006-2008 Henrique de Moraes Holschuh <hmh@hmh.eng.br> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 21 * 02110-1301, USA. 22 */ 23 24#define TPACPI_VERSION "0.22" 25#define TPACPI_SYSFS_VERSION 0x020200 26 27/* 28 * Changelog: 29 * 2007-10-20 changelog trimmed down 30 * 31 * 2007-03-27 0.14 renamed to thinkpad_acpi and moved to 32 * drivers/misc. 33 * 34 * 2006-11-22 0.13 new maintainer 35 * changelog now lives in git commit history, and will 36 * not be updated further in-file. 37 * 38 * 2005-03-17 0.11 support for 600e, 770x 39 * thanks to Jamie Lentin <lentinj@dial.pipex.com> 40 * 41 * 2005-01-16 0.9 use MODULE_VERSION 42 * thanks to Henrik Brix Andersen <brix@gentoo.org> 43 * fix parameter passing on module loading 44 * thanks to Rusty Russell <rusty@rustcorp.com.au> 45 * thanks to Jim Radford <radford@blackbean.org> 46 * 2004-11-08 0.8 fix init error case, don't return from a macro 47 * thanks to Chris Wright <chrisw@osdl.org> 48 */ 49 50#include <linux/kernel.h> 51#include <linux/module.h> 52#include <linux/init.h> 53#include <linux/types.h> 54#include <linux/string.h> 55#include <linux/list.h> 56#include <linux/mutex.h> 57#include <linux/kthread.h> 58#include <linux/freezer.h> 59#include <linux/delay.h> 60 61#include <linux/nvram.h> 62#include <linux/proc_fs.h> 63#include <linux/sysfs.h> 64#include <linux/backlight.h> 65#include <linux/fb.h> 66#include <linux/platform_device.h> 67#include <linux/hwmon.h> 68#include <linux/hwmon-sysfs.h> 69#include <linux/input.h> 70#include <linux/leds.h> 71#include <linux/rfkill.h> 72#include <asm/uaccess.h> 73 74#include <linux/dmi.h> 75#include <linux/jiffies.h> 76#include <linux/workqueue.h> 77 78#include <acpi/acpi_drivers.h> 79 80#include <linux/pci_ids.h> 81 82 83/* ThinkPad CMOS commands */ 84#define TP_CMOS_VOLUME_DOWN 0 85#define TP_CMOS_VOLUME_UP 1 86#define TP_CMOS_VOLUME_MUTE 2 87#define TP_CMOS_BRIGHTNESS_UP 4 88#define TP_CMOS_BRIGHTNESS_DOWN 5 89#define TP_CMOS_THINKLIGHT_ON 12 90#define TP_CMOS_THINKLIGHT_OFF 13 91 92/* NVRAM Addresses */ 93enum tp_nvram_addr { 94 TP_NVRAM_ADDR_HK2 = 0x57, 95 TP_NVRAM_ADDR_THINKLIGHT = 0x58, 96 TP_NVRAM_ADDR_VIDEO = 0x59, 97 TP_NVRAM_ADDR_BRIGHTNESS = 0x5e, 98 TP_NVRAM_ADDR_MIXER = 0x60, 99}; 100 101/* NVRAM bit masks */ 102enum { 103 TP_NVRAM_MASK_HKT_THINKPAD = 0x08, 104 TP_NVRAM_MASK_HKT_ZOOM = 0x20, 105 TP_NVRAM_MASK_HKT_DISPLAY = 0x40, 106 TP_NVRAM_MASK_HKT_HIBERNATE = 0x80, 107 TP_NVRAM_MASK_THINKLIGHT = 0x10, 108 TP_NVRAM_MASK_HKT_DISPEXPND = 0x30, 109 TP_NVRAM_MASK_HKT_BRIGHTNESS = 0x20, 110 TP_NVRAM_MASK_LEVEL_BRIGHTNESS = 0x0f, 111 TP_NVRAM_POS_LEVEL_BRIGHTNESS = 0, 112 TP_NVRAM_MASK_MUTE = 0x40, 113 TP_NVRAM_MASK_HKT_VOLUME = 0x80, 114 TP_NVRAM_MASK_LEVEL_VOLUME = 0x0f, 115 TP_NVRAM_POS_LEVEL_VOLUME = 0, 116}; 117 118/* ACPI HIDs */ 119#define TPACPI_ACPI_HKEY_HID "IBM0068" 120 121/* Input IDs */ 122#define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */ 123#define TPACPI_HKEY_INPUT_VERSION 0x4101 124 125/* ACPI \WGSV commands */ 126enum { 127 TP_ACPI_WGSV_GET_STATE = 0x01, /* Get state information */ 128 TP_ACPI_WGSV_PWR_ON_ON_RESUME = 0x02, /* Resume WWAN powered on */ 129 TP_ACPI_WGSV_PWR_OFF_ON_RESUME = 0x03, /* Resume WWAN powered off */ 130 TP_ACPI_WGSV_SAVE_STATE = 0x04, /* Save state for S4/S5 */ 131}; 132 133/* TP_ACPI_WGSV_GET_STATE bits */ 134enum { 135 TP_ACPI_WGSV_STATE_WWANEXIST = 0x0001, /* WWAN hw available */ 136 TP_ACPI_WGSV_STATE_WWANPWR = 0x0002, /* WWAN radio enabled */ 137 TP_ACPI_WGSV_STATE_WWANPWRRES = 0x0004, /* WWAN state at resume */ 138 TP_ACPI_WGSV_STATE_WWANBIOSOFF = 0x0008, /* WWAN disabled in BIOS */ 139 TP_ACPI_WGSV_STATE_BLTHEXIST = 0x0001, /* BLTH hw available */ 140 TP_ACPI_WGSV_STATE_BLTHPWR = 0x0002, /* BLTH radio enabled */ 141 TP_ACPI_WGSV_STATE_BLTHPWRRES = 0x0004, /* BLTH state at resume */ 142 TP_ACPI_WGSV_STATE_BLTHBIOSOFF = 0x0008, /* BLTH disabled in BIOS */ 143 TP_ACPI_WGSV_STATE_UWBEXIST = 0x0010, /* UWB hw available */ 144 TP_ACPI_WGSV_STATE_UWBPWR = 0x0020, /* UWB radio enabled */ 145}; 146 147/**************************************************************************** 148 * Main driver 149 */ 150 151#define TPACPI_NAME "thinkpad" 152#define TPACPI_DESC "ThinkPad ACPI Extras" 153#define TPACPI_FILE TPACPI_NAME "_acpi" 154#define TPACPI_URL "http://ibm-acpi.sf.net/" 155#define TPACPI_MAIL "ibm-acpi-devel@lists.sourceforge.net" 156 157#define TPACPI_PROC_DIR "ibm" 158#define TPACPI_ACPI_EVENT_PREFIX "ibm" 159#define TPACPI_DRVR_NAME TPACPI_FILE 160#define TPACPI_DRVR_SHORTNAME "tpacpi" 161#define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon" 162 163#define TPACPI_NVRAM_KTHREAD_NAME "ktpacpi_nvramd" 164#define TPACPI_WORKQUEUE_NAME "ktpacpid" 165 166#define TPACPI_MAX_ACPI_ARGS 3 167 168/* rfkill switches */ 169enum { 170 TPACPI_RFK_BLUETOOTH_SW_ID = 0, 171 TPACPI_RFK_WWAN_SW_ID, 172 TPACPI_RFK_UWB_SW_ID, 173}; 174 175/* Debugging */ 176#define TPACPI_LOG TPACPI_FILE ": " 177#define TPACPI_ALERT KERN_ALERT TPACPI_LOG 178#define TPACPI_CRIT KERN_CRIT TPACPI_LOG 179#define TPACPI_ERR KERN_ERR TPACPI_LOG 180#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG 181#define TPACPI_INFO KERN_INFO TPACPI_LOG 182#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG 183 184#define TPACPI_DBG_ALL 0xffff 185#define TPACPI_DBG_INIT 0x0001 186#define TPACPI_DBG_EXIT 0x0002 187#define dbg_printk(a_dbg_level, format, arg...) \ 188 do { if (dbg_level & a_dbg_level) \ 189 printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \ 190 } while (0) 191#ifdef CONFIG_THINKPAD_ACPI_DEBUG 192#define vdbg_printk(a_dbg_level, format, arg...) \ 193 dbg_printk(a_dbg_level, format, ## arg) 194static const char *str_supported(int is_supported); 195#else 196#define vdbg_printk(a_dbg_level, format, arg...) 197#endif 198 199#define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off") 200#define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") 201#define strlencmp(a, b) (strncmp((a), (b), strlen(b))) 202 203 204/**************************************************************************** 205 * Driver-wide structs and misc. variables 206 */ 207 208struct ibm_struct; 209 210struct tp_acpi_drv_struct { 211 const struct acpi_device_id *hid; 212 struct acpi_driver *driver; 213 214 void (*notify) (struct ibm_struct *, u32); 215 acpi_handle *handle; 216 u32 type; 217 struct acpi_device *device; 218}; 219 220struct ibm_struct { 221 char *name; 222 223 int (*read) (char *); 224 int (*write) (char *); 225 void (*exit) (void); 226 void (*resume) (void); 227 void (*suspend) (pm_message_t state); 228 void (*shutdown) (void); 229 230 struct list_head all_drivers; 231 232 struct tp_acpi_drv_struct *acpi; 233 234 struct { 235 u8 acpi_driver_registered:1; 236 u8 acpi_notify_installed:1; 237 u8 proc_created:1; 238 u8 init_called:1; 239 u8 experimental:1; 240 } flags; 241}; 242 243struct ibm_init_struct { 244 char param[32]; 245 246 int (*init) (struct ibm_init_struct *); 247 struct ibm_struct *data; 248}; 249 250static struct { 251#ifdef CONFIG_THINKPAD_ACPI_BAY 252 u32 bay_status:1; 253 u32 bay_eject:1; 254 u32 bay_status2:1; 255 u32 bay_eject2:1; 256#endif 257 u32 bluetooth:1; 258 u32 hotkey:1; 259 u32 hotkey_mask:1; 260 u32 hotkey_wlsw:1; 261 u32 hotkey_tablet:1; 262 u32 light:1; 263 u32 light_status:1; 264 u32 bright_16levels:1; 265 u32 bright_acpimode:1; 266 u32 wan:1; 267 u32 uwb:1; 268 u32 fan_ctrl_status_undef:1; 269 u32 input_device_registered:1; 270 u32 platform_drv_registered:1; 271 u32 platform_drv_attrs_registered:1; 272 u32 sensors_pdrv_registered:1; 273 u32 sensors_pdrv_attrs_registered:1; 274 u32 sensors_pdev_attrs_registered:1; 275 u32 hotkey_poll_active:1; 276} tp_features; 277 278static struct { 279 u16 hotkey_mask_ff:1; 280 u16 bright_cmos_ec_unsync:1; 281} tp_warned; 282 283struct thinkpad_id_data { 284 unsigned int vendor; /* ThinkPad vendor: 285 * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */ 286 287 char *bios_version_str; /* Something like 1ZET51WW (1.03z) */ 288 char *ec_version_str; /* Something like 1ZHT51WW-1.04a */ 289 290 u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */ 291 u16 ec_model; 292 293 char *model_str; /* ThinkPad T43 */ 294 char *nummodel_str; /* 9384A9C for a 9384-A9C model */ 295}; 296static struct thinkpad_id_data thinkpad_id; 297 298static enum { 299 TPACPI_LIFE_INIT = 0, 300 TPACPI_LIFE_RUNNING, 301 TPACPI_LIFE_EXITING, 302} tpacpi_lifecycle; 303 304static int experimental; 305static u32 dbg_level; 306 307static struct workqueue_struct *tpacpi_wq; 308 309/* Special LED class that can defer work */ 310struct tpacpi_led_classdev { 311 struct led_classdev led_classdev; 312 struct work_struct work; 313 enum led_brightness new_brightness; 314 unsigned int led; 315}; 316 317#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 318static int dbg_wlswemul; 319static int tpacpi_wlsw_emulstate; 320static int dbg_bluetoothemul; 321static int tpacpi_bluetooth_emulstate; 322static int dbg_wwanemul; 323static int tpacpi_wwan_emulstate; 324static int dbg_uwbemul; 325static int tpacpi_uwb_emulstate; 326#endif 327 328 329/**************************************************************************** 330 **************************************************************************** 331 * 332 * ACPI Helpers and device model 333 * 334 **************************************************************************** 335 ****************************************************************************/ 336 337/************************************************************************* 338 * ACPI basic handles 339 */ 340 341static acpi_handle root_handle; 342 343#define TPACPI_HANDLE(object, parent, paths...) \ 344 static acpi_handle object##_handle; \ 345 static acpi_handle *object##_parent = &parent##_handle; \ 346 static char *object##_path; \ 347 static char *object##_paths[] = { paths } 348 349TPACPI_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0", /* 240, 240x */ 350 "\\_SB.PCI.ISA.EC", /* 570 */ 351 "\\_SB.PCI0.ISA0.EC0", /* 600e/x, 770e, 770x */ 352 "\\_SB.PCI0.ISA.EC", /* A21e, A2xm/p, T20-22, X20-21 */ 353 "\\_SB.PCI0.AD4S.EC0", /* i1400, R30 */ 354 "\\_SB.PCI0.ICH3.EC0", /* R31 */ 355 "\\_SB.PCI0.LPC.EC", /* all others */ 356 ); 357 358TPACPI_HANDLE(ecrd, ec, "ECRD"); /* 570 */ 359TPACPI_HANDLE(ecwr, ec, "ECWR"); /* 570 */ 360 361TPACPI_HANDLE(cmos, root, "\\UCMS", /* R50, R50e, R50p, R51, */ 362 /* T4x, X31, X40 */ 363 "\\CMOS", /* A3x, G4x, R32, T23, T30, X22-24, X30 */ 364 "\\CMS", /* R40, R40e */ 365 ); /* all others */ 366 367TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */ 368 "^HKEY", /* R30, R31 */ 369 "HKEY", /* all others */ 370 ); /* 570 */ 371 372TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */ 373 "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */ 374 "\\_SB.PCI0.VID0", /* 770e */ 375 "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */ 376 "\\_SB.PCI0.AGP.VID", /* all others */ 377 ); /* R30, R31 */ 378 379 380/************************************************************************* 381 * ACPI helpers 382 */ 383 384static int acpi_evalf(acpi_handle handle, 385 void *res, char *method, char *fmt, ...) 386{ 387 char *fmt0 = fmt; 388 struct acpi_object_list params; 389 union acpi_object in_objs[TPACPI_MAX_ACPI_ARGS]; 390 struct acpi_buffer result, *resultp; 391 union acpi_object out_obj; 392 acpi_status status; 393 va_list ap; 394 char res_type; 395 int success; 396 int quiet; 397 398 if (!*fmt) { 399 printk(TPACPI_ERR "acpi_evalf() called with empty format\n"); 400 return 0; 401 } 402 403 if (*fmt == 'q') { 404 quiet = 1; 405 fmt++; 406 } else 407 quiet = 0; 408 409 res_type = *(fmt++); 410 411 params.count = 0; 412 params.pointer = &in_objs[0]; 413 414 va_start(ap, fmt); 415 while (*fmt) { 416 char c = *(fmt++); 417 switch (c) { 418 case 'd': /* int */ 419 in_objs[params.count].integer.value = va_arg(ap, int); 420 in_objs[params.count++].type = ACPI_TYPE_INTEGER; 421 break; 422 /* add more types as needed */ 423 default: 424 printk(TPACPI_ERR "acpi_evalf() called " 425 "with invalid format character '%c'\n", c); 426 return 0; 427 } 428 } 429 va_end(ap); 430 431 if (res_type != 'v') { 432 result.length = sizeof(out_obj); 433 result.pointer = &out_obj; 434 resultp = &result; 435 } else 436 resultp = NULL; 437 438 status = acpi_evaluate_object(handle, method, ¶ms, resultp); 439 440 switch (res_type) { 441 case 'd': /* int */ 442 if (res) 443 *(int *)res = out_obj.integer.value; 444 success = status == AE_OK && out_obj.type == ACPI_TYPE_INTEGER; 445 break; 446 case 'v': /* void */ 447 success = status == AE_OK; 448 break; 449 /* add more types as needed */ 450 default: 451 printk(TPACPI_ERR "acpi_evalf() called " 452 "with invalid format character '%c'\n", res_type); 453 return 0; 454 } 455 456 if (!success && !quiet) 457 printk(TPACPI_ERR "acpi_evalf(%s, %s, ...) failed: %d\n", 458 method, fmt0, status); 459 460 return success; 461} 462 463static int acpi_ec_read(int i, u8 *p) 464{ 465 int v; 466 467 if (ecrd_handle) { 468 if (!acpi_evalf(ecrd_handle, &v, NULL, "dd", i)) 469 return 0; 470 *p = v; 471 } else { 472 if (ec_read(i, p) < 0) 473 return 0; 474 } 475 476 return 1; 477} 478 479static int acpi_ec_write(int i, u8 v) 480{ 481 if (ecwr_handle) { 482 if (!acpi_evalf(ecwr_handle, NULL, NULL, "vdd", i, v)) 483 return 0; 484 } else { 485 if (ec_write(i, v) < 0) 486 return 0; 487 } 488 489 return 1; 490} 491 492#if defined(CONFIG_THINKPAD_ACPI_DOCK) || defined(CONFIG_THINKPAD_ACPI_BAY) 493static int _sta(acpi_handle handle) 494{ 495 int status; 496 497 if (!handle || !acpi_evalf(handle, &status, "_STA", "d")) 498 status = 0; 499 500 return status; 501} 502#endif 503 504static int issue_thinkpad_cmos_command(int cmos_cmd) 505{ 506 if (!cmos_handle) 507 return -ENXIO; 508 509 if (!acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd)) 510 return -EIO; 511 512 return 0; 513} 514 515/************************************************************************* 516 * ACPI device model 517 */ 518 519#define TPACPI_ACPIHANDLE_INIT(object) \ 520 drv_acpi_handle_init(#object, &object##_handle, *object##_parent, \ 521 object##_paths, ARRAY_SIZE(object##_paths), &object##_path) 522 523static void drv_acpi_handle_init(char *name, 524 acpi_handle *handle, acpi_handle parent, 525 char **paths, int num_paths, char **path) 526{ 527 int i; 528 acpi_status status; 529 530 vdbg_printk(TPACPI_DBG_INIT, "trying to locate ACPI handle for %s\n", 531 name); 532 533 for (i = 0; i < num_paths; i++) { 534 status = acpi_get_handle(parent, paths[i], handle); 535 if (ACPI_SUCCESS(status)) { 536 *path = paths[i]; 537 dbg_printk(TPACPI_DBG_INIT, 538 "Found ACPI handle %s for %s\n", 539 *path, name); 540 return; 541 } 542 } 543 544 vdbg_printk(TPACPI_DBG_INIT, "ACPI handle for %s not found\n", 545 name); 546 *handle = NULL; 547} 548 549static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data) 550{ 551 struct ibm_struct *ibm = data; 552 553 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING) 554 return; 555 556 if (!ibm || !ibm->acpi || !ibm->acpi->notify) 557 return; 558 559 ibm->acpi->notify(ibm, event); 560} 561 562static int __init setup_acpi_notify(struct ibm_struct *ibm) 563{ 564 acpi_status status; 565 int rc; 566 567 BUG_ON(!ibm->acpi); 568 569 if (!*ibm->acpi->handle) 570 return 0; 571 572 vdbg_printk(TPACPI_DBG_INIT, 573 "setting up ACPI notify for %s\n", ibm->name); 574 575 rc = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device); 576 if (rc < 0) { 577 printk(TPACPI_ERR "acpi_bus_get_device(%s) failed: %d\n", 578 ibm->name, rc); 579 return -ENODEV; 580 } 581 582 ibm->acpi->device->driver_data = ibm; 583 sprintf(acpi_device_class(ibm->acpi->device), "%s/%s", 584 TPACPI_ACPI_EVENT_PREFIX, 585 ibm->name); 586 587 status = acpi_install_notify_handler(*ibm->acpi->handle, 588 ibm->acpi->type, dispatch_acpi_notify, ibm); 589 if (ACPI_FAILURE(status)) { 590 if (status == AE_ALREADY_EXISTS) { 591 printk(TPACPI_NOTICE 592 "another device driver is already " 593 "handling %s events\n", ibm->name); 594 } else { 595 printk(TPACPI_ERR 596 "acpi_install_notify_handler(%s) failed: %d\n", 597 ibm->name, status); 598 } 599 return -ENODEV; 600 } 601 ibm->flags.acpi_notify_installed = 1; 602 return 0; 603} 604 605static int __init tpacpi_device_add(struct acpi_device *device) 606{ 607 return 0; 608} 609 610static int __init register_tpacpi_subdriver(struct ibm_struct *ibm) 611{ 612 int rc; 613 614 dbg_printk(TPACPI_DBG_INIT, 615 "registering %s as an ACPI driver\n", ibm->name); 616 617 BUG_ON(!ibm->acpi); 618 619 ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL); 620 if (!ibm->acpi->driver) { 621 printk(TPACPI_ERR 622 "failed to allocate memory for ibm->acpi->driver\n"); 623 return -ENOMEM; 624 } 625 626 sprintf(ibm->acpi->driver->name, "%s_%s", TPACPI_NAME, ibm->name); 627 ibm->acpi->driver->ids = ibm->acpi->hid; 628 629 ibm->acpi->driver->ops.add = &tpacpi_device_add; 630 631 rc = acpi_bus_register_driver(ibm->acpi->driver); 632 if (rc < 0) { 633 printk(TPACPI_ERR "acpi_bus_register_driver(%s) failed: %d\n", 634 ibm->name, rc); 635 kfree(ibm->acpi->driver); 636 ibm->acpi->driver = NULL; 637 } else if (!rc) 638 ibm->flags.acpi_driver_registered = 1; 639 640 return rc; 641} 642 643 644/**************************************************************************** 645 **************************************************************************** 646 * 647 * Procfs Helpers 648 * 649 **************************************************************************** 650 ****************************************************************************/ 651 652static int dispatch_procfs_read(char *page, char **start, off_t off, 653 int count, int *eof, void *data) 654{ 655 struct ibm_struct *ibm = data; 656 int len; 657 658 if (!ibm || !ibm->read) 659 return -EINVAL; 660 661 len = ibm->read(page); 662 if (len < 0) 663 return len; 664 665 if (len <= off + count) 666 *eof = 1; 667 *start = page + off; 668 len -= off; 669 if (len > count) 670 len = count; 671 if (len < 0) 672 len = 0; 673 674 return len; 675} 676 677static int dispatch_procfs_write(struct file *file, 678 const char __user *userbuf, 679 unsigned long count, void *data) 680{ 681 struct ibm_struct *ibm = data; 682 char *kernbuf; 683 int ret; 684 685 if (!ibm || !ibm->write) 686 return -EINVAL; 687 688 kernbuf = kmalloc(count + 2, GFP_KERNEL); 689 if (!kernbuf) 690 return -ENOMEM; 691 692 if (copy_from_user(kernbuf, userbuf, count)) { 693 kfree(kernbuf); 694 return -EFAULT; 695 } 696 697 kernbuf[count] = 0; 698 strcat(kernbuf, ","); 699 ret = ibm->write(kernbuf); 700 if (ret == 0) 701 ret = count; 702 703 kfree(kernbuf); 704 705 return ret; 706} 707 708static char *next_cmd(char **cmds) 709{ 710 char *start = *cmds; 711 char *end; 712 713 while ((end = strchr(start, ',')) && end == start) 714 start = end + 1; 715 716 if (!end) 717 return NULL; 718 719 *end = 0; 720 *cmds = end + 1; 721 return start; 722} 723 724 725/**************************************************************************** 726 **************************************************************************** 727 * 728 * Device model: input, hwmon and platform 729 * 730 **************************************************************************** 731 ****************************************************************************/ 732 733static struct platform_device *tpacpi_pdev; 734static struct platform_device *tpacpi_sensors_pdev; 735static struct device *tpacpi_hwmon; 736static struct input_dev *tpacpi_inputdev; 737static struct mutex tpacpi_inputdev_send_mutex; 738static LIST_HEAD(tpacpi_all_drivers); 739 740static int tpacpi_suspend_handler(struct platform_device *pdev, 741 pm_message_t state) 742{ 743 struct ibm_struct *ibm, *itmp; 744 745 list_for_each_entry_safe(ibm, itmp, 746 &tpacpi_all_drivers, 747 all_drivers) { 748 if (ibm->suspend) 749 (ibm->suspend)(state); 750 } 751 752 return 0; 753} 754 755static int tpacpi_resume_handler(struct platform_device *pdev) 756{ 757 struct ibm_struct *ibm, *itmp; 758 759 list_for_each_entry_safe(ibm, itmp, 760 &tpacpi_all_drivers, 761 all_drivers) { 762 if (ibm->resume) 763 (ibm->resume)(); 764 } 765 766 return 0; 767} 768 769static void tpacpi_shutdown_handler(struct platform_device *pdev) 770{ 771 struct ibm_struct *ibm, *itmp; 772 773 list_for_each_entry_safe(ibm, itmp, 774 &tpacpi_all_drivers, 775 all_drivers) { 776 if (ibm->shutdown) 777 (ibm->shutdown)(); 778 } 779} 780 781static struct platform_driver tpacpi_pdriver = { 782 .driver = { 783 .name = TPACPI_DRVR_NAME, 784 .owner = THIS_MODULE, 785 }, 786 .suspend = tpacpi_suspend_handler, 787 .resume = tpacpi_resume_handler, 788 .shutdown = tpacpi_shutdown_handler, 789}; 790 791static struct platform_driver tpacpi_hwmon_pdriver = { 792 .driver = { 793 .name = TPACPI_HWMON_DRVR_NAME, 794 .owner = THIS_MODULE, 795 }, 796}; 797 798/************************************************************************* 799 * sysfs support helpers 800 */ 801 802struct attribute_set { 803 unsigned int members, max_members; 804 struct attribute_group group; 805}; 806 807struct attribute_set_obj { 808 struct attribute_set s; 809 struct attribute *a; 810} __attribute__((packed)); 811 812static struct attribute_set *create_attr_set(unsigned int max_members, 813 const char *name) 814{ 815 struct attribute_set_obj *sobj; 816 817 if (max_members == 0) 818 return NULL; 819 820 /* Allocates space for implicit NULL at the end too */ 821 sobj = kzalloc(sizeof(struct attribute_set_obj) + 822 max_members * sizeof(struct attribute *), 823 GFP_KERNEL); 824 if (!sobj) 825 return NULL; 826 sobj->s.max_members = max_members; 827 sobj->s.group.attrs = &sobj->a; 828 sobj->s.group.name = name; 829 830 return &sobj->s; 831} 832 833#define destroy_attr_set(_set) \ 834 kfree(_set); 835 836/* not multi-threaded safe, use it in a single thread per set */ 837static int add_to_attr_set(struct attribute_set *s, struct attribute *attr) 838{ 839 if (!s || !attr) 840 return -EINVAL; 841 842 if (s->members >= s->max_members) 843 return -ENOMEM; 844 845 s->group.attrs[s->members] = attr; 846 s->members++; 847 848 return 0; 849} 850 851static int add_many_to_attr_set(struct attribute_set *s, 852 struct attribute **attr, 853 unsigned int count) 854{ 855 int i, res; 856 857 for (i = 0; i < count; i++) { 858 res = add_to_attr_set(s, attr[i]); 859 if (res) 860 return res; 861 } 862 863 return 0; 864} 865 866static void delete_attr_set(struct attribute_set *s, struct kobject *kobj) 867{ 868 sysfs_remove_group(kobj, &s->group); 869 destroy_attr_set(s); 870} 871 872#define register_attr_set_with_sysfs(_attr_set, _kobj) \ 873 sysfs_create_group(_kobj, &_attr_set->group) 874 875static int parse_strtoul(const char *buf, 876 unsigned long max, unsigned long *value) 877{ 878 char *endp; 879 880 while (*buf && isspace(*buf)) 881 buf++; 882 *value = simple_strtoul(buf, &endp, 0); 883 while (*endp && isspace(*endp)) 884 endp++; 885 if (*endp || *value > max) 886 return -EINVAL; 887 888 return 0; 889} 890 891static void tpacpi_disable_brightness_delay(void) 892{ 893 if (acpi_evalf(hkey_handle, NULL, "PWMS", "qvd", 0)) 894 printk(TPACPI_NOTICE 895 "ACPI backlight control delay disabled\n"); 896} 897 898static int __init tpacpi_query_bcl_levels(acpi_handle handle) 899{ 900 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 901 union acpi_object *obj; 902 int rc; 903 904 if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) { 905 obj = (union acpi_object *)buffer.pointer; 906 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { 907 printk(TPACPI_ERR "Unknown _BCL data, " 908 "please report this to %s\n", TPACPI_MAIL); 909 rc = 0; 910 } else { 911 rc = obj->package.count; 912 } 913 } else { 914 return 0; 915 } 916 917 kfree(buffer.pointer); 918 return rc; 919} 920 921static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle, 922 u32 lvl, void *context, void **rv) 923{ 924 char name[ACPI_PATH_SEGMENT_LENGTH]; 925 struct acpi_buffer buffer = { sizeof(name), &name }; 926 927 if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && 928 !strncmp("_BCL", name, sizeof(name) - 1)) { 929 BUG_ON(!rv || !*rv); 930 **(int **)rv = tpacpi_query_bcl_levels(handle); 931 return AE_CTRL_TERMINATE; 932 } else { 933 return AE_OK; 934 } 935} 936 937/* 938 * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map 939 */ 940static int __init tpacpi_check_std_acpi_brightness_support(void) 941{ 942 int status; 943 int bcl_levels = 0; 944 void *bcl_ptr = &bcl_levels; 945 946 if (!vid_handle) { 947 TPACPI_ACPIHANDLE_INIT(vid); 948 } 949 if (!vid_handle) 950 return 0; 951 952 /* 953 * Search for a _BCL method, and execute it. This is safe on all 954 * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista 955 * BIOS in ACPI backlight control mode. We do NOT have to care 956 * about calling the _BCL method in an enabled video device, any 957 * will do for our purposes. 958 */ 959 960 status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, 961 tpacpi_acpi_walk_find_bcl, NULL, 962 &bcl_ptr); 963 964 if (ACPI_SUCCESS(status) && bcl_levels > 2) { 965 tp_features.bright_acpimode = 1; 966 return (bcl_levels - 2); 967 } 968 969 return 0; 970} 971 972static int __init tpacpi_new_rfkill(const unsigned int id, 973 struct rfkill **rfk, 974 const enum rfkill_type rfktype, 975 const char *name, 976 const bool set_default, 977 int (*toggle_radio)(void *, enum rfkill_state), 978 int (*get_state)(void *, enum rfkill_state *)) 979{ 980 int res; 981 enum rfkill_state initial_state = RFKILL_STATE_SOFT_BLOCKED; 982 983 res = get_state(NULL, &initial_state); 984 if (res < 0) { 985 printk(TPACPI_ERR 986 "failed to read initial state for %s, error %d; " 987 "will turn radio off\n", name, res); 988 } else if (set_default) { 989 /* try to set the initial state as the default for the rfkill 990 * type, since we ask the firmware to preserve it across S5 in 991 * NVRAM */ 992 rfkill_set_default(rfktype, 993 (initial_state == RFKILL_STATE_UNBLOCKED) ? 994 RFKILL_STATE_UNBLOCKED : 995 RFKILL_STATE_SOFT_BLOCKED); 996 } 997 998 *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype); 999 if (!*rfk) { 1000 printk(TPACPI_ERR 1001 "failed to allocate memory for rfkill class\n"); 1002 return -ENOMEM; 1003 } 1004 1005 (*rfk)->name = name; 1006 (*rfk)->get_state = get_state; 1007 (*rfk)->toggle_radio = toggle_radio; 1008 (*rfk)->state = initial_state; 1009 1010 res = rfkill_register(*rfk); 1011 if (res < 0) { 1012 printk(TPACPI_ERR 1013 "failed to register %s rfkill switch: %d\n", 1014 name, res); 1015 rfkill_free(*rfk); 1016 *rfk = NULL; 1017 return res; 1018 } 1019 1020 return 0; 1021} 1022 1023/************************************************************************* 1024 * thinkpad-acpi driver attributes 1025 */ 1026 1027/* interface_version --------------------------------------------------- */ 1028static ssize_t tpacpi_driver_interface_version_show( 1029 struct device_driver *drv, 1030 char *buf) 1031{ 1032 return snprintf(buf, PAGE_SIZE, "0x%08x\n", TPACPI_SYSFS_VERSION); 1033} 1034 1035static DRIVER_ATTR(interface_version, S_IRUGO, 1036 tpacpi_driver_interface_version_show, NULL); 1037 1038/* debug_level --------------------------------------------------------- */ 1039static ssize_t tpacpi_driver_debug_show(struct device_driver *drv, 1040 char *buf) 1041{ 1042 return snprintf(buf, PAGE_SIZE, "0x%04x\n", dbg_level); 1043} 1044 1045static ssize_t tpacpi_driver_debug_store(struct device_driver *drv, 1046 const char *buf, size_t count) 1047{ 1048 unsigned long t; 1049 1050 if (parse_strtoul(buf, 0xffff, &t)) 1051 return -EINVAL; 1052 1053 dbg_level = t; 1054 1055 return count; 1056} 1057 1058static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, 1059 tpacpi_driver_debug_show, tpacpi_driver_debug_store); 1060 1061/* version ------------------------------------------------------------- */ 1062static ssize_t tpacpi_driver_version_show(struct device_driver *drv, 1063 char *buf) 1064{ 1065 return snprintf(buf, PAGE_SIZE, "%s v%s\n", 1066 TPACPI_DESC, TPACPI_VERSION); 1067} 1068 1069static DRIVER_ATTR(version, S_IRUGO, 1070 tpacpi_driver_version_show, NULL); 1071 1072/* --------------------------------------------------------------------- */ 1073 1074#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 1075 1076static void tpacpi_send_radiosw_update(void); 1077 1078/* wlsw_emulstate ------------------------------------------------------ */ 1079static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv, 1080 char *buf) 1081{ 1082 return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_wlsw_emulstate); 1083} 1084 1085static ssize_t tpacpi_driver_wlsw_emulstate_store(struct device_driver *drv, 1086 const char *buf, size_t count) 1087{ 1088 unsigned long t; 1089 1090 if (parse_strtoul(buf, 1, &t)) 1091 return -EINVAL; 1092 1093 if (tpacpi_wlsw_emulstate != t) { 1094 tpacpi_wlsw_emulstate = !!t; 1095 tpacpi_send_radiosw_update(); 1096 } else 1097 tpacpi_wlsw_emulstate = !!t; 1098 1099 return count; 1100} 1101 1102static DRIVER_ATTR(wlsw_emulstate, S_IWUSR | S_IRUGO, 1103 tpacpi_driver_wlsw_emulstate_show, 1104 tpacpi_driver_wlsw_emulstate_store); 1105 1106/* bluetooth_emulstate ------------------------------------------------- */ 1107static ssize_t tpacpi_driver_bluetooth_emulstate_show( 1108 struct device_driver *drv, 1109 char *buf) 1110{ 1111 return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_bluetooth_emulstate); 1112} 1113 1114static ssize_t tpacpi_driver_bluetooth_emulstate_store( 1115 struct device_driver *drv, 1116 const char *buf, size_t count) 1117{ 1118 unsigned long t; 1119 1120 if (parse_strtoul(buf, 1, &t)) 1121 return -EINVAL; 1122 1123 tpacpi_bluetooth_emulstate = !!t; 1124 1125 return count; 1126} 1127 1128static DRIVER_ATTR(bluetooth_emulstate, S_IWUSR | S_IRUGO, 1129 tpacpi_driver_bluetooth_emulstate_show, 1130 tpacpi_driver_bluetooth_emulstate_store); 1131 1132/* wwan_emulstate ------------------------------------------------- */ 1133static ssize_t tpacpi_driver_wwan_emulstate_show( 1134 struct device_driver *drv, 1135 char *buf) 1136{ 1137 return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_wwan_emulstate); 1138} 1139 1140static ssize_t tpacpi_driver_wwan_emulstate_store( 1141 struct device_driver *drv, 1142 const char *buf, size_t count) 1143{ 1144 unsigned long t; 1145 1146 if (parse_strtoul(buf, 1, &t)) 1147 return -EINVAL; 1148 1149 tpacpi_wwan_emulstate = !!t; 1150 1151 return count; 1152} 1153 1154static DRIVER_ATTR(wwan_emulstate, S_IWUSR | S_IRUGO, 1155 tpacpi_driver_wwan_emulstate_show, 1156 tpacpi_driver_wwan_emulstate_store); 1157 1158/* uwb_emulstate ------------------------------------------------- */ 1159static ssize_t tpacpi_driver_uwb_emulstate_show( 1160 struct device_driver *drv, 1161 char *buf) 1162{ 1163 return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_uwb_emulstate); 1164} 1165 1166static ssize_t tpacpi_driver_uwb_emulstate_store( 1167 struct device_driver *drv, 1168 const char *buf, size_t count) 1169{ 1170 unsigned long t; 1171 1172 if (parse_strtoul(buf, 1, &t)) 1173 return -EINVAL; 1174 1175 tpacpi_uwb_emulstate = !!t; 1176 1177 return count; 1178} 1179 1180static DRIVER_ATTR(uwb_emulstate, S_IWUSR | S_IRUGO, 1181 tpacpi_driver_uwb_emulstate_show, 1182 tpacpi_driver_uwb_emulstate_store); 1183#endif 1184 1185/* --------------------------------------------------------------------- */ 1186 1187static struct driver_attribute *tpacpi_driver_attributes[] = { 1188 &driver_attr_debug_level, &driver_attr_version, 1189 &driver_attr_interface_version, 1190}; 1191 1192static int __init tpacpi_create_driver_attributes(struct device_driver *drv) 1193{ 1194 int i, res; 1195 1196 i = 0; 1197 res = 0; 1198 while (!res && i < ARRAY_SIZE(tpacpi_driver_attributes)) { 1199 res = driver_create_file(drv, tpacpi_driver_attributes[i]); 1200 i++; 1201 } 1202 1203#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 1204 if (!res && dbg_wlswemul) 1205 res = driver_create_file(drv, &driver_attr_wlsw_emulstate); 1206 if (!res && dbg_bluetoothemul) 1207 res = driver_create_file(drv, &driver_attr_bluetooth_emulstate); 1208 if (!res && dbg_wwanemul) 1209 res = driver_create_file(drv, &driver_attr_wwan_emulstate); 1210 if (!res && dbg_uwbemul) 1211 res = driver_create_file(drv, &driver_attr_uwb_emulstate); 1212#endif 1213 1214 return res; 1215} 1216 1217static void tpacpi_remove_driver_attributes(struct device_driver *drv) 1218{ 1219 int i; 1220 1221 for (i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++) 1222 driver_remove_file(drv, tpacpi_driver_attributes[i]); 1223 1224#ifdef THINKPAD_ACPI_DEBUGFACILITIES 1225 driver_remove_file(drv, &driver_attr_wlsw_emulstate); 1226 driver_remove_file(drv, &driver_attr_bluetooth_emulstate); 1227 driver_remove_file(drv, &driver_attr_wwan_emulstate); 1228 driver_remove_file(drv, &driver_attr_uwb_emulstate); 1229#endif 1230} 1231 1232/**************************************************************************** 1233 **************************************************************************** 1234 * 1235 * Subdrivers 1236 * 1237 **************************************************************************** 1238 ****************************************************************************/ 1239 1240/************************************************************************* 1241 * thinkpad-acpi init subdriver 1242 */ 1243 1244static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm) 1245{ 1246 printk(TPACPI_INFO "%s v%s\n", TPACPI_DESC, TPACPI_VERSION); 1247 printk(TPACPI_INFO "%s\n", TPACPI_URL); 1248 1249 printk(TPACPI_INFO "ThinkPad BIOS %s, EC %s\n", 1250 (thinkpad_id.bios_version_str) ? 1251 thinkpad_id.bios_version_str : "unknown", 1252 (thinkpad_id.ec_version_str) ? 1253 thinkpad_id.ec_version_str : "unknown"); 1254 1255 if (thinkpad_id.vendor && thinkpad_id.model_str) 1256 printk(TPACPI_INFO "%s %s, model %s\n", 1257 (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? 1258 "IBM" : ((thinkpad_id.vendor == 1259 PCI_VENDOR_ID_LENOVO) ? 1260 "Lenovo" : "Unknown vendor"), 1261 thinkpad_id.model_str, 1262 (thinkpad_id.nummodel_str) ? 1263 thinkpad_id.nummodel_str : "unknown"); 1264 1265 return 0; 1266} 1267 1268static int thinkpad_acpi_driver_read(char *p) 1269{ 1270 int len = 0; 1271 1272 len += sprintf(p + len, "driver:\t\t%s\n", TPACPI_DESC); 1273 len += sprintf(p + len, "version:\t%s\n", TPACPI_VERSION); 1274 1275 return len; 1276} 1277 1278static struct ibm_struct thinkpad_acpi_driver_data = { 1279 .name = "driver", 1280 .read = thinkpad_acpi_driver_read, 1281}; 1282 1283/************************************************************************* 1284 * Hotkey subdriver 1285 */ 1286 1287enum { /* hot key scan codes (derived from ACPI DSDT) */ 1288 TP_ACPI_HOTKEYSCAN_FNF1 = 0, 1289 TP_ACPI_HOTKEYSCAN_FNF2, 1290 TP_ACPI_HOTKEYSCAN_FNF3, 1291 TP_ACPI_HOTKEYSCAN_FNF4, 1292 TP_ACPI_HOTKEYSCAN_FNF5, 1293 TP_ACPI_HOTKEYSCAN_FNF6, 1294 TP_ACPI_HOTKEYSCAN_FNF7, 1295 TP_ACPI_HOTKEYSCAN_FNF8, 1296 TP_ACPI_HOTKEYSCAN_FNF9, 1297 TP_ACPI_HOTKEYSCAN_FNF10, 1298 TP_ACPI_HOTKEYSCAN_FNF11, 1299 TP_ACPI_HOTKEYSCAN_FNF12, 1300 TP_ACPI_HOTKEYSCAN_FNBACKSPACE, 1301 TP_ACPI_HOTKEYSCAN_FNINSERT, 1302 TP_ACPI_HOTKEYSCAN_FNDELETE, 1303 TP_ACPI_HOTKEYSCAN_FNHOME, 1304 TP_ACPI_HOTKEYSCAN_FNEND, 1305 TP_ACPI_HOTKEYSCAN_FNPAGEUP, 1306 TP_ACPI_HOTKEYSCAN_FNPAGEDOWN, 1307 TP_ACPI_HOTKEYSCAN_FNSPACE, 1308 TP_ACPI_HOTKEYSCAN_VOLUMEUP, 1309 TP_ACPI_HOTKEYSCAN_VOLUMEDOWN, 1310 TP_ACPI_HOTKEYSCAN_MUTE, 1311 TP_ACPI_HOTKEYSCAN_THINKPAD, 1312}; 1313 1314enum { /* Keys available through NVRAM polling */ 1315 TPACPI_HKEY_NVRAM_KNOWN_MASK = 0x00fb88c0U, 1316 TPACPI_HKEY_NVRAM_GOOD_MASK = 0x00fb8000U, 1317}; 1318 1319enum { /* Positions of some of the keys in hotkey masks */ 1320 TP_ACPI_HKEY_DISPSWTCH_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF7, 1321 TP_ACPI_HKEY_DISPXPAND_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF8, 1322 TP_ACPI_HKEY_HIBERNATE_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF12, 1323 TP_ACPI_HKEY_BRGHTUP_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNHOME, 1324 TP_ACPI_HKEY_BRGHTDWN_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNEND, 1325 TP_ACPI_HKEY_THNKLGHT_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNPAGEUP, 1326 TP_ACPI_HKEY_ZOOM_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNSPACE, 1327 TP_ACPI_HKEY_VOLUP_MASK = 1 << TP_ACPI_HOTKEYSCAN_VOLUMEUP, 1328 TP_ACPI_HKEY_VOLDWN_MASK = 1 << TP_ACPI_HOTKEYSCAN_VOLUMEDOWN, 1329 TP_ACPI_HKEY_MUTE_MASK = 1 << TP_ACPI_HOTKEYSCAN_MUTE, 1330 TP_ACPI_HKEY_THINKPAD_MASK = 1 << TP_ACPI_HOTKEYSCAN_THINKPAD, 1331}; 1332 1333enum { /* NVRAM to ACPI HKEY group map */ 1334 TP_NVRAM_HKEY_GROUP_HK2 = TP_ACPI_HKEY_THINKPAD_MASK | 1335 TP_ACPI_HKEY_ZOOM_MASK | 1336 TP_ACPI_HKEY_DISPSWTCH_MASK | 1337 TP_ACPI_HKEY_HIBERNATE_MASK, 1338 TP_NVRAM_HKEY_GROUP_BRIGHTNESS = TP_ACPI_HKEY_BRGHTUP_MASK | 1339 TP_ACPI_HKEY_BRGHTDWN_MASK, 1340 TP_NVRAM_HKEY_GROUP_VOLUME = TP_ACPI_HKEY_VOLUP_MASK | 1341 TP_ACPI_HKEY_VOLDWN_MASK | 1342 TP_ACPI_HKEY_MUTE_MASK, 1343}; 1344 1345#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1346struct tp_nvram_state { 1347 u16 thinkpad_toggle:1; 1348 u16 zoom_toggle:1; 1349 u16 display_toggle:1; 1350 u16 thinklight_toggle:1; 1351 u16 hibernate_toggle:1; 1352 u16 displayexp_toggle:1; 1353 u16 display_state:1; 1354 u16 brightness_toggle:1; 1355 u16 volume_toggle:1; 1356 u16 mute:1; 1357 1358 u8 brightness_level; 1359 u8 volume_level; 1360}; 1361 1362static struct task_struct *tpacpi_hotkey_task; 1363static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */ 1364static int hotkey_poll_freq = 10; /* Hz */ 1365static struct mutex hotkey_thread_mutex; 1366static struct mutex hotkey_thread_data_mutex; 1367static unsigned int hotkey_config_change; 1368 1369#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1370 1371#define hotkey_source_mask 0U 1372 1373#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1374 1375static struct mutex hotkey_mutex; 1376 1377static enum { /* Reasons for waking up */ 1378 TP_ACPI_WAKEUP_NONE = 0, /* None or unknown */ 1379 TP_ACPI_WAKEUP_BAYEJ, /* Bay ejection request */ 1380 TP_ACPI_WAKEUP_UNDOCK, /* Undock request */ 1381} hotkey_wakeup_reason; 1382 1383static int hotkey_autosleep_ack; 1384 1385static int hotkey_orig_status; 1386static u32 hotkey_orig_mask; 1387static u32 hotkey_all_mask; 1388static u32 hotkey_reserved_mask; 1389static u32 hotkey_mask; 1390 1391static unsigned int hotkey_report_mode; 1392 1393static u16 *hotkey_keycode_map; 1394 1395static struct attribute_set *hotkey_dev_attributes; 1396 1397#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1398#define HOTKEY_CONFIG_CRITICAL_START \ 1399 do { \ 1400 mutex_lock(&hotkey_thread_data_mutex); \ 1401 hotkey_config_change++; \ 1402 } while (0); 1403#define HOTKEY_CONFIG_CRITICAL_END \ 1404 mutex_unlock(&hotkey_thread_data_mutex); 1405#else 1406#define HOTKEY_CONFIG_CRITICAL_START 1407#define HOTKEY_CONFIG_CRITICAL_END 1408#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1409 1410/* HKEY.MHKG() return bits */ 1411#define TP_HOTKEY_TABLET_MASK (1 << 3) 1412 1413static int hotkey_get_wlsw(int *status) 1414{ 1415#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 1416 if (dbg_wlswemul) { 1417 *status = !!tpacpi_wlsw_emulstate; 1418 return 0; 1419 } 1420#endif 1421 if (!acpi_evalf(hkey_handle, status, "WLSW", "d")) 1422 return -EIO; 1423 return 0; 1424} 1425 1426static int hotkey_get_tablet_mode(int *status) 1427{ 1428 int s; 1429 1430 if (!acpi_evalf(hkey_handle, &s, "MHKG", "d")) 1431 return -EIO; 1432 1433 *status = ((s & TP_HOTKEY_TABLET_MASK) != 0); 1434 return 0; 1435} 1436 1437/* 1438 * Call with hotkey_mutex held 1439 */ 1440static int hotkey_mask_get(void) 1441{ 1442 u32 m = 0; 1443 1444 if (tp_features.hotkey_mask) { 1445 if (!acpi_evalf(hkey_handle, &m, "DHKN", "d")) 1446 return -EIO; 1447 } 1448 hotkey_mask = m | (hotkey_source_mask & hotkey_mask); 1449 1450 return 0; 1451} 1452 1453/* 1454 * Call with hotkey_mutex held 1455 */ 1456static int hotkey_mask_set(u32 mask) 1457{ 1458 int i; 1459 int rc = 0; 1460 1461 if (tp_features.hotkey_mask) { 1462 if (!tp_warned.hotkey_mask_ff && 1463 (mask == 0xffff || mask == 0xffffff || 1464 mask == 0xffffffff)) { 1465 tp_warned.hotkey_mask_ff = 1; 1466 printk(TPACPI_NOTICE 1467 "setting the hotkey mask to 0x%08x is likely " 1468 "not the best way to go about it\n", mask); 1469 printk(TPACPI_NOTICE 1470 "please consider using the driver defaults, " 1471 "and refer to up-to-date thinkpad-acpi " 1472 "documentation\n"); 1473 } 1474 1475 HOTKEY_CONFIG_CRITICAL_START 1476 for (i = 0; i < 32; i++) { 1477 u32 m = 1 << i; 1478 /* enable in firmware mask only keys not in NVRAM 1479 * mode, but enable the key in the cached hotkey_mask 1480 * regardless of mode, or the key will end up 1481 * disabled by hotkey_mask_get() */ 1482 if (!acpi_evalf(hkey_handle, 1483 NULL, "MHKM", "vdd", i + 1, 1484 !!((mask & ~hotkey_source_mask) & m))) { 1485 rc = -EIO; 1486 break; 1487 } else { 1488 hotkey_mask = (hotkey_mask & ~m) | (mask & m); 1489 } 1490 } 1491 HOTKEY_CONFIG_CRITICAL_END 1492 1493 /* hotkey_mask_get must be called unconditionally below */ 1494 if (!hotkey_mask_get() && !rc && 1495 (hotkey_mask & ~hotkey_source_mask) != 1496 (mask & ~hotkey_source_mask)) { 1497 printk(TPACPI_NOTICE 1498 "requested hot key mask 0x%08x, but " 1499 "firmware forced it to 0x%08x\n", 1500 mask, hotkey_mask); 1501 } 1502 } else { 1503#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1504 HOTKEY_CONFIG_CRITICAL_START 1505 hotkey_mask = mask & hotkey_source_mask; 1506 HOTKEY_CONFIG_CRITICAL_END 1507 hotkey_mask_get(); 1508 if (hotkey_mask != mask) { 1509 printk(TPACPI_NOTICE 1510 "requested hot key mask 0x%08x, " 1511 "forced to 0x%08x (NVRAM poll mask is " 1512 "0x%08x): no firmware mask support\n", 1513 mask, hotkey_mask, hotkey_source_mask); 1514 } 1515#else 1516 hotkey_mask_get(); 1517 rc = -ENXIO; 1518#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1519 } 1520 1521 return rc; 1522} 1523 1524static int hotkey_status_get(int *status) 1525{ 1526 if (!acpi_evalf(hkey_handle, status, "DHKC", "d")) 1527 return -EIO; 1528 1529 return 0; 1530} 1531 1532static int hotkey_status_set(int status) 1533{ 1534 if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status)) 1535 return -EIO; 1536 1537 return 0; 1538} 1539 1540static void tpacpi_input_send_tabletsw(void) 1541{ 1542 int state; 1543 1544 if (tp_features.hotkey_tablet && 1545 !hotkey_get_tablet_mode(&state)) { 1546 mutex_lock(&tpacpi_inputdev_send_mutex); 1547 1548 input_report_switch(tpacpi_inputdev, 1549 SW_TABLET_MODE, !!state); 1550 input_sync(tpacpi_inputdev); 1551 1552 mutex_unlock(&tpacpi_inputdev_send_mutex); 1553 } 1554} 1555 1556static void tpacpi_input_send_key(unsigned int scancode) 1557{ 1558 unsigned int keycode; 1559 1560 keycode = hotkey_keycode_map[scancode]; 1561 1562 if (keycode != KEY_RESERVED) { 1563 mutex_lock(&tpacpi_inputdev_send_mutex); 1564 1565 input_report_key(tpacpi_inputdev, keycode, 1); 1566 if (keycode == KEY_UNKNOWN) 1567 input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, 1568 scancode); 1569 input_sync(tpacpi_inputdev); 1570 1571 input_report_key(tpacpi_inputdev, keycode, 0); 1572 if (keycode == KEY_UNKNOWN) 1573 input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, 1574 scancode); 1575 input_sync(tpacpi_inputdev); 1576 1577 mutex_unlock(&tpacpi_inputdev_send_mutex); 1578 } 1579} 1580 1581#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1582static struct tp_acpi_drv_struct ibm_hotkey_acpidriver; 1583 1584static void tpacpi_hotkey_send_key(unsigned int scancode) 1585{ 1586 tpacpi_input_send_key(scancode); 1587 if (hotkey_report_mode < 2) { 1588 acpi_bus_generate_proc_event(ibm_hotkey_acpidriver.device, 1589 0x80, 0x1001 + scancode); 1590 } 1591} 1592 1593static void hotkey_read_nvram(struct tp_nvram_state *n, u32 m) 1594{ 1595 u8 d; 1596 1597 if (m & TP_NVRAM_HKEY_GROUP_HK2) { 1598 d = nvram_read_byte(TP_NVRAM_ADDR_HK2); 1599 n->thinkpad_toggle = !!(d & TP_NVRAM_MASK_HKT_THINKPAD); 1600 n->zoom_toggle = !!(d & TP_NVRAM_MASK_HKT_ZOOM); 1601 n->display_toggle = !!(d & TP_NVRAM_MASK_HKT_DISPLAY); 1602 n->hibernate_toggle = !!(d & TP_NVRAM_MASK_HKT_HIBERNATE); 1603 } 1604 if (m & TP_ACPI_HKEY_THNKLGHT_MASK) { 1605 d = nvram_read_byte(TP_NVRAM_ADDR_THINKLIGHT); 1606 n->thinklight_toggle = !!(d & TP_NVRAM_MASK_THINKLIGHT); 1607 } 1608 if (m & TP_ACPI_HKEY_DISPXPAND_MASK) { 1609 d = nvram_read_byte(TP_NVRAM_ADDR_VIDEO); 1610 n->displayexp_toggle = 1611 !!(d & TP_NVRAM_MASK_HKT_DISPEXPND); 1612 } 1613 if (m & TP_NVRAM_HKEY_GROUP_BRIGHTNESS) { 1614 d = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS); 1615 n->brightness_level = (d & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) 1616 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; 1617 n->brightness_toggle = 1618 !!(d & TP_NVRAM_MASK_HKT_BRIGHTNESS); 1619 } 1620 if (m & TP_NVRAM_HKEY_GROUP_VOLUME) { 1621 d = nvram_read_byte(TP_NVRAM_ADDR_MIXER); 1622 n->volume_level = (d & TP_NVRAM_MASK_LEVEL_VOLUME) 1623 >> TP_NVRAM_POS_LEVEL_VOLUME; 1624 n->mute = !!(d & TP_NVRAM_MASK_MUTE); 1625 n->volume_toggle = !!(d & TP_NVRAM_MASK_HKT_VOLUME); 1626 } 1627} 1628 1629#define TPACPI_COMPARE_KEY(__scancode, __member) \ 1630 do { \ 1631 if ((mask & (1 << __scancode)) && \ 1632 oldn->__member != newn->__member) \ 1633 tpacpi_hotkey_send_key(__scancode); \ 1634 } while (0) 1635 1636#define TPACPI_MAY_SEND_KEY(__scancode) \ 1637 do { if (mask & (1 << __scancode)) \ 1638 tpacpi_hotkey_send_key(__scancode); } while (0) 1639 1640static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn, 1641 struct tp_nvram_state *newn, 1642 u32 mask) 1643{ 1644 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle); 1645 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle); 1646 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle); 1647 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF12, hibernate_toggle); 1648 1649 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNPAGEUP, thinklight_toggle); 1650 1651 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF8, displayexp_toggle); 1652 1653 /* handle volume */ 1654 if (oldn->volume_toggle != newn->volume_toggle) { 1655 if (oldn->mute != newn->mute) { 1656 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE); 1657 } 1658 if (oldn->volume_level > newn->volume_level) { 1659 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN); 1660 } else if (oldn->volume_level < newn->volume_level) { 1661 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP); 1662 } else if (oldn->mute == newn->mute) { 1663 /* repeated key presses that didn't change state */ 1664 if (newn->mute) { 1665 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE); 1666 } else if (newn->volume_level != 0) { 1667 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP); 1668 } else { 1669 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN); 1670 } 1671 } 1672 } 1673 1674 /* handle brightness */ 1675 if (oldn->brightness_toggle != newn->brightness_toggle) { 1676 if (oldn->brightness_level < newn->brightness_level) { 1677 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME); 1678 } else if (oldn->brightness_level > newn->brightness_level) { 1679 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND); 1680 } else { 1681 /* repeated key presses that didn't change state */ 1682 if (newn->brightness_level != 0) { 1683 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME); 1684 } else { 1685 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND); 1686 } 1687 } 1688 } 1689} 1690 1691#undef TPACPI_COMPARE_KEY 1692#undef TPACPI_MAY_SEND_KEY 1693 1694static int hotkey_kthread(void *data) 1695{ 1696 struct tp_nvram_state s[2]; 1697 u32 mask; 1698 unsigned int si, so; 1699 unsigned long t; 1700 unsigned int change_detector, must_reset; 1701 1702 mutex_lock(&hotkey_thread_mutex); 1703 1704 if (tpacpi_lifecycle == TPACPI_LIFE_EXITING) 1705 goto exit; 1706 1707 set_freezable(); 1708 1709 so = 0; 1710 si = 1; 1711 t = 0; 1712 1713 /* Initial state for compares */ 1714 mutex_lock(&hotkey_thread_data_mutex); 1715 change_detector = hotkey_config_change; 1716 mask = hotkey_source_mask & hotkey_mask; 1717 mutex_unlock(&hotkey_thread_data_mutex); 1718 hotkey_read_nvram(&s[so], mask); 1719 1720 while (!kthread_should_stop() && hotkey_poll_freq) { 1721 if (t == 0) 1722 t = 1000/hotkey_poll_freq; 1723 t = msleep_interruptible(t); 1724 if (unlikely(kthread_should_stop())) 1725 break; 1726 must_reset = try_to_freeze(); 1727 if (t > 0 && !must_reset) 1728 continue; 1729 1730 mutex_lock(&hotkey_thread_data_mutex); 1731 if (must_reset || hotkey_config_change != change_detector) { 1732 /* forget old state on thaw or config change */ 1733 si = so; 1734 t = 0; 1735 change_detector = hotkey_config_change; 1736 } 1737 mask = hotkey_source_mask & hotkey_mask; 1738 mutex_unlock(&hotkey_thread_data_mutex); 1739 1740 if (likely(mask)) { 1741 hotkey_read_nvram(&s[si], mask); 1742 if (likely(si != so)) { 1743 hotkey_compare_and_issue_event(&s[so], &s[si], 1744 mask); 1745 } 1746 } 1747 1748 so = si; 1749 si ^= 1; 1750 } 1751 1752exit: 1753 mutex_unlock(&hotkey_thread_mutex); 1754 return 0; 1755} 1756 1757static void hotkey_poll_stop_sync(void) 1758{ 1759 if (tpacpi_hotkey_task) { 1760 if (frozen(tpacpi_hotkey_task) || 1761 freezing(tpacpi_hotkey_task)) 1762 thaw_process(tpacpi_hotkey_task); 1763 1764 kthread_stop(tpacpi_hotkey_task); 1765 tpacpi_hotkey_task = NULL; 1766 mutex_lock(&hotkey_thread_mutex); 1767 /* at this point, the thread did exit */ 1768 mutex_unlock(&hotkey_thread_mutex); 1769 } 1770} 1771 1772/* call with hotkey_mutex held */ 1773static void hotkey_poll_setup(int may_warn) 1774{ 1775 if ((hotkey_source_mask & hotkey_mask) != 0 && 1776 hotkey_poll_freq > 0 && 1777 (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) { 1778 if (!tpacpi_hotkey_task) { 1779 tpacpi_hotkey_task = kthread_run(hotkey_kthread, 1780 NULL, TPACPI_NVRAM_KTHREAD_NAME); 1781 if (IS_ERR(tpacpi_hotkey_task)) { 1782 tpacpi_hotkey_task = NULL; 1783 printk(TPACPI_ERR 1784 "could not create kernel thread " 1785 "for hotkey polling\n"); 1786 } 1787 } 1788 } else { 1789 hotkey_poll_stop_sync(); 1790 if (may_warn && 1791 hotkey_source_mask != 0 && hotkey_poll_freq == 0) { 1792 printk(TPACPI_NOTICE 1793 "hot keys 0x%08x require polling, " 1794 "which is currently disabled\n", 1795 hotkey_source_mask); 1796 } 1797 } 1798} 1799 1800static void hotkey_poll_setup_safe(int may_warn) 1801{ 1802 mutex_lock(&hotkey_mutex); 1803 hotkey_poll_setup(may_warn); 1804 mutex_unlock(&hotkey_mutex); 1805} 1806 1807#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1808 1809static void hotkey_poll_setup_safe(int __unused) 1810{ 1811} 1812 1813#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1814 1815static int hotkey_inputdev_open(struct input_dev *dev) 1816{ 1817 switch (tpacpi_lifecycle) { 1818 case TPACPI_LIFE_INIT: 1819 /* 1820 * hotkey_init will call hotkey_poll_setup_safe 1821 * at the appropriate moment 1822 */ 1823 return 0; 1824 case TPACPI_LIFE_EXITING: 1825 return -EBUSY; 1826 case TPACPI_LIFE_RUNNING: 1827 hotkey_poll_setup_safe(0); 1828 return 0; 1829 } 1830 1831 /* Should only happen if tpacpi_lifecycle is corrupt */ 1832 BUG(); 1833 return -EBUSY; 1834} 1835 1836static void hotkey_inputdev_close(struct input_dev *dev) 1837{ 1838 /* disable hotkey polling when possible */ 1839 if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING) 1840 hotkey_poll_setup_safe(0); 1841} 1842 1843/* sysfs hotkey enable ------------------------------------------------- */ 1844static ssize_t hotkey_enable_show(struct device *dev, 1845 struct device_attribute *attr, 1846 char *buf) 1847{ 1848 int res, status; 1849 1850 res = hotkey_status_get(&status); 1851 if (res) 1852 return res; 1853 1854 return snprintf(buf, PAGE_SIZE, "%d\n", status); 1855} 1856 1857static ssize_t hotkey_enable_store(struct device *dev, 1858 struct device_attribute *attr, 1859 const char *buf, size_t count) 1860{ 1861 unsigned long t; 1862 int res; 1863 1864 if (parse_strtoul(buf, 1, &t)) 1865 return -EINVAL; 1866 1867 res = hotkey_status_set(t); 1868 1869 return (res) ? res : count; 1870} 1871 1872static struct device_attribute dev_attr_hotkey_enable = 1873 __ATTR(hotkey_enable, S_IWUSR | S_IRUGO, 1874 hotkey_enable_show, hotkey_enable_store); 1875 1876/* sysfs hotkey mask --------------------------------------------------- */ 1877static ssize_t hotkey_mask_show(struct device *dev, 1878 struct device_attribute *attr, 1879 char *buf) 1880{ 1881 int res; 1882 1883 if (mutex_lock_killable(&hotkey_mutex)) 1884 return -ERESTARTSYS; 1885 res = hotkey_mask_get(); 1886 mutex_unlock(&hotkey_mutex); 1887 1888 return (res)? 1889 res : snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_mask); 1890} 1891 1892static ssize_t hotkey_mask_store(struct device *dev, 1893 struct device_attribute *attr, 1894 const char *buf, size_t count) 1895{ 1896 unsigned long t; 1897 int res; 1898 1899 if (parse_strtoul(buf, 0xffffffffUL, &t)) 1900 return -EINVAL; 1901 1902 if (mutex_lock_killable(&hotkey_mutex)) 1903 return -ERESTARTSYS; 1904 1905 res = hotkey_mask_set(t); 1906 1907#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1908 hotkey_poll_setup(1); 1909#endif 1910 1911 mutex_unlock(&hotkey_mutex); 1912 1913 return (res) ? res : count; 1914} 1915 1916static struct device_attribute dev_attr_hotkey_mask = 1917 __ATTR(hotkey_mask, S_IWUSR | S_IRUGO, 1918 hotkey_mask_show, hotkey_mask_store); 1919 1920/* sysfs hotkey bios_enabled ------------------------------------------- */ 1921static ssize_t hotkey_bios_enabled_show(struct device *dev, 1922 struct device_attribute *attr, 1923 char *buf) 1924{ 1925 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status); 1926} 1927 1928static struct device_attribute dev_attr_hotkey_bios_enabled = 1929 __ATTR(hotkey_bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL); 1930 1931/* sysfs hotkey bios_mask ---------------------------------------------- */ 1932static ssize_t hotkey_bios_mask_show(struct device *dev, 1933 struct device_attribute *attr, 1934 char *buf) 1935{ 1936 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask); 1937} 1938 1939static struct device_attribute dev_attr_hotkey_bios_mask = 1940 __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL); 1941 1942/* sysfs hotkey all_mask ----------------------------------------------- */ 1943static ssize_t hotkey_all_mask_show(struct device *dev, 1944 struct device_attribute *attr, 1945 char *buf) 1946{ 1947 return snprintf(buf, PAGE_SIZE, "0x%08x\n", 1948 hotkey_all_mask | hotkey_source_mask); 1949} 1950 1951static struct device_attribute dev_attr_hotkey_all_mask = 1952 __ATTR(hotkey_all_mask, S_IRUGO, hotkey_all_mask_show, NULL); 1953 1954/* sysfs hotkey recommended_mask --------------------------------------- */ 1955static ssize_t hotkey_recommended_mask_show(struct device *dev, 1956 struct device_attribute *attr, 1957 char *buf) 1958{ 1959 return snprintf(buf, PAGE_SIZE, "0x%08x\n", 1960 (hotkey_all_mask | hotkey_source_mask) 1961 & ~hotkey_reserved_mask); 1962} 1963 1964static struct device_attribute dev_attr_hotkey_recommended_mask = 1965 __ATTR(hotkey_recommended_mask, S_IRUGO, 1966 hotkey_recommended_mask_show, NULL); 1967 1968#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1969 1970/* sysfs hotkey hotkey_source_mask ------------------------------------- */ 1971static ssize_t hotkey_source_mask_show(struct device *dev, 1972 struct device_attribute *attr, 1973 char *buf) 1974{ 1975 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_source_mask); 1976} 1977 1978static ssize_t hotkey_source_mask_store(struct device *dev, 1979 struct device_attribute *attr, 1980 const char *buf, size_t count) 1981{ 1982 unsigned long t; 1983 1984 if (parse_strtoul(buf, 0xffffffffUL, &t) || 1985 ((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0)) 1986 return -EINVAL; 1987 1988 if (mutex_lock_killable(&hotkey_mutex)) 1989 return -ERESTARTSYS; 1990 1991 HOTKEY_CONFIG_CRITICAL_START 1992 hotkey_source_mask = t; 1993 HOTKEY_CONFIG_CRITICAL_END 1994 1995 hotkey_poll_setup(1); 1996 1997 mutex_unlock(&hotkey_mutex); 1998 1999 return count; 2000} 2001 2002static struct device_attribute dev_attr_hotkey_source_mask = 2003 __ATTR(hotkey_source_mask, S_IWUSR | S_IRUGO, 2004 hotkey_source_mask_show, hotkey_source_mask_store); 2005 2006/* sysfs hotkey hotkey_poll_freq --------------------------------------- */ 2007static ssize_t hotkey_poll_freq_show(struct device *dev, 2008 struct device_attribute *attr, 2009 char *buf) 2010{ 2011 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_poll_freq); 2012} 2013 2014static ssize_t hotkey_poll_freq_store(struct device *dev, 2015 struct device_attribute *attr, 2016 const char *buf, size_t count) 2017{ 2018 unsigned long t; 2019 2020 if (parse_strtoul(buf, 25, &t)) 2021 return -EINVAL; 2022 2023 if (mutex_lock_killable(&hotkey_mutex)) 2024 return -ERESTARTSYS; 2025 2026 hotkey_poll_freq = t; 2027 2028 hotkey_poll_setup(1); 2029 mutex_unlock(&hotkey_mutex); 2030 2031 return count; 2032} 2033 2034static struct device_attribute dev_attr_hotkey_poll_freq = 2035 __ATTR(hotkey_poll_freq, S_IWUSR | S_IRUGO, 2036 hotkey_poll_freq_show, hotkey_poll_freq_store); 2037 2038#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 2039 2040/* sysfs hotkey radio_sw (pollable) ------------------------------------ */ 2041static ssize_t hotkey_radio_sw_show(struct device *dev, 2042 struct device_attribute *attr, 2043 char *buf) 2044{ 2045 int res, s; 2046 res = hotkey_get_wlsw(&s); 2047 if (res < 0) 2048 return res; 2049 2050 return snprintf(buf, PAGE_SIZE, "%d\n", !!s); 2051} 2052 2053static struct device_attribute dev_attr_hotkey_radio_sw = 2054 __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL); 2055 2056static void hotkey_radio_sw_notify_change(void) 2057{ 2058 if (tp_features.hotkey_wlsw) 2059 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 2060 "hotkey_radio_sw"); 2061} 2062 2063/* sysfs hotkey tablet mode (pollable) --------------------------------- */ 2064static ssize_t hotkey_tablet_mode_show(struct device *dev, 2065 struct device_attribute *attr, 2066 char *buf) 2067{ 2068 int res, s; 2069 res = hotkey_get_tablet_mode(&s); 2070 if (res < 0) 2071 return res; 2072 2073 return snprintf(buf, PAGE_SIZE, "%d\n", !!s); 2074} 2075 2076static struct device_attribute dev_attr_hotkey_tablet_mode = 2077 __ATTR(hotkey_tablet_mode, S_IRUGO, hotkey_tablet_mode_show, NULL); 2078 2079static void hotkey_tablet_mode_notify_change(void) 2080{ 2081 if (tp_features.hotkey_tablet) 2082 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 2083 "hotkey_tablet_mode"); 2084} 2085 2086/* sysfs hotkey report_mode -------------------------------------------- */ 2087static ssize_t hotkey_report_mode_show(struct device *dev, 2088 struct device_attribute *attr, 2089 char *buf) 2090{ 2091 return snprintf(buf, PAGE_SIZE, "%d\n", 2092 (hotkey_report_mode != 0) ? hotkey_report_mode : 1); 2093} 2094 2095static struct device_attribute dev_attr_hotkey_report_mode = 2096 __ATTR(hotkey_report_mode, S_IRUGO, hotkey_report_mode_show, NULL); 2097 2098/* sysfs wakeup reason (pollable) -------------------------------------- */ 2099static ssize_t hotkey_wakeup_reason_show(struct device *dev, 2100 struct device_attribute *attr, 2101 char *buf) 2102{ 2103 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_wakeup_reason); 2104} 2105 2106static struct device_attribute dev_attr_hotkey_wakeup_reason = 2107 __ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL); 2108 2109static void hotkey_wakeup_reason_notify_change(void) 2110{ 2111 if (tp_features.hotkey_mask) 2112 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 2113 "wakeup_reason"); 2114} 2115 2116/* sysfs wakeup hotunplug_complete (pollable) -------------------------- */ 2117static ssize_t hotkey_wakeup_hotunplug_complete_show(struct device *dev, 2118 struct device_attribute *attr, 2119 char *buf) 2120{ 2121 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_autosleep_ack); 2122} 2123 2124static struct device_attribute dev_attr_hotkey_wakeup_hotunplug_complete = 2125 __ATTR(wakeup_hotunplug_complete, S_IRUGO, 2126 hotkey_wakeup_hotunplug_complete_show, NULL); 2127 2128static void hotkey_wakeup_hotunplug_complete_notify_change(void) 2129{ 2130 if (tp_features.hotkey_mask) 2131 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 2132 "wakeup_hotunplug_complete"); 2133} 2134 2135/* --------------------------------------------------------------------- */ 2136 2137static struct attribute *hotkey_attributes[] __initdata = { 2138 &dev_attr_hotkey_enable.attr, 2139 &dev_attr_hotkey_bios_enabled.attr, 2140 &dev_attr_hotkey_report_mode.attr, 2141#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2142 &dev_attr_hotkey_mask.attr, 2143 &dev_attr_hotkey_all_mask.attr, 2144 &dev_attr_hotkey_recommended_mask.attr, 2145 &dev_attr_hotkey_source_mask.attr, 2146 &dev_attr_hotkey_poll_freq.attr, 2147#endif 2148}; 2149 2150static struct attribute *hotkey_mask_attributes[] __initdata = { 2151 &dev_attr_hotkey_bios_mask.attr, 2152#ifndef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2153 &dev_attr_hotkey_mask.attr, 2154 &dev_attr_hotkey_all_mask.attr, 2155 &dev_attr_hotkey_recommended_mask.attr, 2156#endif 2157 &dev_attr_hotkey_wakeup_reason.attr, 2158 &dev_attr_hotkey_wakeup_hotunplug_complete.attr, 2159}; 2160 2161static void bluetooth_update_rfk(void); 2162static void wan_update_rfk(void); 2163static void uwb_update_rfk(void); 2164static void tpacpi_send_radiosw_update(void) 2165{ 2166 int wlsw; 2167 2168 /* Sync these BEFORE sending any rfkill events */ 2169 if (tp_features.bluetooth) 2170 bluetooth_update_rfk(); 2171 if (tp_features.wan) 2172 wan_update_rfk(); 2173 if (tp_features.uwb) 2174 uwb_update_rfk(); 2175 2176 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) { 2177 mutex_lock(&tpacpi_inputdev_send_mutex); 2178 2179 input_report_switch(tpacpi_inputdev, 2180 SW_RFKILL_ALL, !!wlsw); 2181 input_sync(tpacpi_inputdev); 2182 2183 mutex_unlock(&tpacpi_inputdev_send_mutex); 2184 } 2185 hotkey_radio_sw_notify_change(); 2186} 2187 2188static void hotkey_exit(void) 2189{ 2190#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2191 hotkey_poll_stop_sync(); 2192#endif 2193 2194 if (hotkey_dev_attributes) 2195 delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); 2196 2197 kfree(hotkey_keycode_map); 2198 2199 if (tp_features.hotkey) { 2200 dbg_printk(TPACPI_DBG_EXIT, 2201 "restoring original hot key mask\n"); 2202 /* no short-circuit boolean operator below! */ 2203 if ((hotkey_mask_set(hotkey_orig_mask) | 2204 hotkey_status_set(hotkey_orig_status)) != 0) 2205 printk(TPACPI_ERR 2206 "failed to restore hot key mask " 2207 "to BIOS defaults\n"); 2208 } 2209} 2210 2211static int __init hotkey_init(struct ibm_init_struct *iibm) 2212{ 2213 /* Requirements for changing the default keymaps: 2214 * 2215 * 1. Many of the keys are mapped to KEY_RESERVED for very 2216 * good reasons. Do not change them unless you have deep 2217 * knowledge on the IBM and Lenovo ThinkPad firmware for 2218 * the various ThinkPad models. The driver behaves 2219 * differently for KEY_RESERVED: such keys have their 2220 * hot key mask *unset* in mask_recommended, and also 2221 * in the initial hot key mask programmed into the 2222 * firmware at driver load time, which means the firm- 2223 * ware may react very differently if you change them to 2224 * something else; 2225 * 2226 * 2. You must be subscribed to the linux-thinkpad and 2227 * ibm-acpi-devel mailing lists, and you should read the 2228 * list archives since 2007 if you want to change the 2229 * keymaps. This requirement exists so that you will 2230 * know the past history of problems with the thinkpad- 2231 * acpi driver keymaps, and also that you will be 2232 * listening to any bug reports; 2233 * 2234 * 3. Do not send thinkpad-acpi specific patches directly to 2235 * for merging, *ever*. Send them to the linux-acpi 2236 * mailinglist for comments. Merging is to be done only 2237 * through acpi-test and the ACPI maintainer. 2238 * 2239 * If the above is too much to ask, don't change the keymap. 2240 * Ask the thinkpad-acpi maintainer to do it, instead. 2241 */ 2242 static u16 ibm_keycode_map[] __initdata = { 2243 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ 2244 KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP, 2245 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, 2246 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, 2247 2248 /* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */ 2249 KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ 2250 KEY_UNKNOWN, /* 0x0D: FN+INSERT */ 2251 KEY_UNKNOWN, /* 0x0E: FN+DELETE */ 2252 2253 /* brightness: firmware always reacts to them, unless 2254 * X.org did some tricks in the radeon BIOS scratch 2255 * registers of *some* models */ 2256 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ 2257 KEY_RESERVED, /* 0x10: FN+END (brightness down) */ 2258 2259 /* Thinklight: firmware always react to it */ 2260 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ 2261 2262 KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ 2263 KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ 2264 2265 /* Volume: firmware always react to it and reprograms 2266 * the built-in *extra* mixer. Never map it to control 2267 * another mixer by default. */ 2268 KEY_RESERVED, /* 0x14: VOLUME UP */ 2269 KEY_RESERVED, /* 0x15: VOLUME DOWN */ 2270 KEY_RESERVED, /* 0x16: MUTE */ 2271 2272 KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ 2273 2274 /* (assignments unknown, please report if found) */ 2275 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 2276 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 2277 }; 2278 static u16 lenovo_keycode_map[] __initdata = { 2279 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ 2280 KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP, 2281 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, 2282 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, 2283 2284 /* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */ 2285 KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ 2286 KEY_UNKNOWN, /* 0x0D: FN+INSERT */ 2287 KEY_UNKNOWN, /* 0x0E: FN+DELETE */ 2288 2289 /* These either have to go through ACPI video, or 2290 * act like in the IBM ThinkPads, so don't ever 2291 * enable them by default */ 2292 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ 2293 KEY_RESERVED, /* 0x10: FN+END (brightness down) */ 2294 2295 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ 2296 2297 KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ 2298 KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ 2299 2300 /* Volume: z60/z61, T60 (BIOS version?): firmware always 2301 * react to it and reprograms the built-in *extra* mixer. 2302 * Never map it to control another mixer by default. 2303 * 2304 * T60?, T61, R60?, R61: firmware and EC tries to send 2305 * these over the regular keyboard, so these are no-ops, 2306 * but there are still weird bugs re. MUTE, so do not 2307 * change unless you get test reports from all Lenovo 2308 * models. May cause the BIOS to interfere with the 2309 * HDA mixer. 2310 */ 2311 KEY_RESERVED, /* 0x14: VOLUME UP */ 2312 KEY_RESERVED, /* 0x15: VOLUME DOWN */ 2313 KEY_RESERVED, /* 0x16: MUTE */ 2314 2315 KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ 2316 2317 /* (assignments unknown, please report if found) */ 2318 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 2319 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 2320 }; 2321 2322#define TPACPI_HOTKEY_MAP_LEN ARRAY_SIZE(ibm_keycode_map) 2323#define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map) 2324#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0]) 2325 2326 int res, i; 2327 int status; 2328 int hkeyv; 2329 2330 vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n"); 2331 2332 BUG_ON(!tpacpi_inputdev); 2333 BUG_ON(tpacpi_inputdev->open != NULL || 2334 tpacpi_inputdev->close != NULL); 2335 2336 TPACPI_ACPIHANDLE_INIT(hkey); 2337 mutex_init(&hotkey_mutex); 2338 2339#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2340 mutex_init(&hotkey_thread_mutex); 2341 mutex_init(&hotkey_thread_data_mutex); 2342#endif 2343 2344 /* hotkey not supported on 570 */ 2345 tp_features.hotkey = hkey_handle != NULL; 2346 2347 vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n", 2348 str_supported(tp_features.hotkey)); 2349 2350 if (!tp_features.hotkey) 2351 return 1; 2352 2353 tpacpi_disable_brightness_delay(); 2354 2355 hotkey_dev_attributes = create_attr_set(13, NULL); 2356 if (!hotkey_dev_attributes) 2357 return -ENOMEM; 2358 res = add_many_to_attr_set(hotkey_dev_attributes, 2359 hotkey_attributes, 2360 ARRAY_SIZE(hotkey_attributes)); 2361 if (res) 2362 goto err_exit; 2363 2364 /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 2365 A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking 2366 for HKEY interface version 0x100 */ 2367 if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { 2368 if ((hkeyv >> 8) != 1) { 2369 printk(TPACPI_ERR "unknown version of the " 2370 "HKEY interface: 0x%x\n", hkeyv); 2371 printk(TPACPI_ERR "please report this to %s\n", 2372 TPACPI_MAIL); 2373 } else { 2374 /* 2375 * MHKV 0x100 in A31, R40, R40e, 2376 * T4x, X31, and later 2377 */ 2378 tp_features.hotkey_mask = 1; 2379 } 2380 } 2381 2382 vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", 2383 str_supported(tp_features.hotkey_mask)); 2384 2385 if (tp_features.hotkey_mask) { 2386 if (!acpi_evalf(hkey_handle, &hotkey_all_mask, 2387 "MHKA", "qd")) { 2388 printk(TPACPI_ERR 2389 "missing MHKA handler, " 2390 "please report this to %s\n", 2391 TPACPI_MAIL); 2392 /* FN+F12, FN+F4, FN+F3 */ 2393 hotkey_all_mask = 0x080cU; 2394 } 2395 } 2396 2397 /* hotkey_source_mask *must* be zero for 2398 * the first hotkey_mask_get */ 2399 res = hotkey_status_get(&hotkey_orig_status); 2400 if (res) 2401 goto err_exit; 2402 2403 if (tp_features.hotkey_mask) { 2404 res = hotkey_mask_get(); 2405 if (res) 2406 goto err_exit; 2407 2408 hotkey_orig_mask = hotkey_mask; 2409 res = add_many_to_attr_set( 2410 hotkey_dev_attributes, 2411 hotkey_mask_attributes, 2412 ARRAY_SIZE(hotkey_mask_attributes)); 2413 if (res) 2414 goto err_exit; 2415 } 2416 2417#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2418 if (tp_features.hotkey_mask) { 2419 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK 2420 & ~hotkey_all_mask; 2421 } else { 2422 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK; 2423 } 2424 2425 vdbg_printk(TPACPI_DBG_INIT, 2426 "hotkey source mask 0x%08x, polling freq %d\n", 2427 hotkey_source_mask, hotkey_poll_freq); 2428#endif 2429 2430#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 2431 if (dbg_wlswemul) { 2432 tp_features.hotkey_wlsw = 1; 2433 printk(TPACPI_INFO 2434 "radio switch emulation enabled\n"); 2435 } else 2436#endif 2437 /* Not all thinkpads have a hardware radio switch */ 2438 if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { 2439 tp_features.hotkey_wlsw = 1; 2440 printk(TPACPI_INFO 2441 "radio switch found; radios are %s\n", 2442 enabled(status, 0)); 2443 } 2444 if (tp_features.hotkey_wlsw) 2445 res = add_to_attr_set(hotkey_dev_attributes, 2446 &dev_attr_hotkey_radio_sw.attr); 2447 2448 /* For X41t, X60t, X61t Tablets... */ 2449 if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { 2450 tp_features.hotkey_tablet = 1; 2451 printk(TPACPI_INFO 2452 "possible tablet mode switch found; " 2453 "ThinkPad in %s mode\n", 2454 (status & TP_HOTKEY_TABLET_MASK)? 2455 "tablet" : "laptop"); 2456 res = add_to_attr_set(hotkey_dev_attributes, 2457 &dev_attr_hotkey_tablet_mode.attr); 2458 } 2459 2460 if (!res) 2461 res = register_attr_set_with_sysfs( 2462 hotkey_dev_attributes, 2463 &tpacpi_pdev->dev.kobj); 2464 if (res) 2465 goto err_exit; 2466 2467 /* Set up key map */ 2468 2469 hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, 2470 GFP_KERNEL); 2471 if (!hotkey_keycode_map) { 2472 printk(TPACPI_ERR 2473 "failed to allocate memory for key map\n"); 2474 res = -ENOMEM; 2475 goto err_exit; 2476 } 2477 2478 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { 2479 dbg_printk(TPACPI_DBG_INIT, 2480 "using Lenovo default hot key map\n"); 2481 memcpy(hotkey_keycode_map, &lenovo_keycode_map, 2482 TPACPI_HOTKEY_MAP_SIZE); 2483 } else { 2484 dbg_printk(TPACPI_DBG_INIT, 2485 "using IBM default hot key map\n"); 2486 memcpy(hotkey_keycode_map, &ibm_keycode_map, 2487 TPACPI_HOTKEY_MAP_SIZE); 2488 } 2489 2490 set_bit(EV_KEY, tpacpi_inputdev->evbit); 2491 set_bit(EV_MSC, tpacpi_inputdev->evbit); 2492 set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); 2493 tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; 2494 tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; 2495 tpacpi_inputdev->keycode = hotkey_keycode_map; 2496 for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { 2497 if (hotkey_keycode_map[i] != KEY_RESERVED) { 2498 set_bit(hotkey_keycode_map[i], 2499 tpacpi_inputdev->keybit); 2500 } else { 2501 if (i < sizeof(hotkey_reserved_mask)*8) 2502 hotkey_reserved_mask |= 1 << i; 2503 } 2504 } 2505 2506 if (tp_features.hotkey_wlsw) { 2507 set_bit(EV_SW, tpacpi_inputdev->evbit); 2508 set_bit(SW_RFKILL_ALL, tpacpi_inputdev->swbit); 2509 } 2510 if (tp_features.hotkey_tablet) { 2511 set_bit(EV_SW, tpacpi_inputdev->evbit); 2512 set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); 2513 } 2514 2515 /* Do not issue duplicate brightness change events to 2516 * userspace */ 2517 if (!tp_features.bright_acpimode) 2518 /* update bright_acpimode... */ 2519 tpacpi_check_std_acpi_brightness_support(); 2520 2521 if (tp_features.bright_acpimode) { 2522 printk(TPACPI_INFO 2523 "This ThinkPad has standard ACPI backlight " 2524 "brightness control, supported by the ACPI " 2525 "video driver\n"); 2526 printk(TPACPI_NOTICE 2527 "Disabling thinkpad-acpi brightness events " 2528 "by default...\n"); 2529 2530 /* The hotkey_reserved_mask change below is not 2531 * necessary while the keys are at KEY_RESERVED in the 2532 * default map, but better safe than sorry, leave it 2533 * here as a marker of what we have to do, especially 2534 * when we finally become able to set this at runtime 2535 * on response to X.org requests */ 2536 hotkey_reserved_mask |= 2537 (1 << TP_ACPI_HOTKEYSCAN_FNHOME) 2538 | (1 << TP_ACPI_HOTKEYSCAN_FNEND); 2539 } 2540 2541 dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n"); 2542 res = hotkey_status_set(1); 2543 if (res) { 2544 hotkey_exit(); 2545 return res; 2546 } 2547 res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask) 2548 & ~hotkey_reserved_mask) 2549 | hotkey_orig_mask); 2550 if (res < 0 && res != -ENXIO) { 2551 hotkey_exit(); 2552 return res; 2553 } 2554 2555 dbg_printk(TPACPI_DBG_INIT, 2556 "legacy hot key reporting over procfs %s\n", 2557 (hotkey_report_mode < 2) ? 2558 "enabled" : "disabled"); 2559 2560 tpacpi_inputdev->open = &hotkey_inputdev_open; 2561 tpacpi_inputdev->close = &hotkey_inputdev_close; 2562 2563 hotkey_poll_setup_safe(1); 2564 tpacpi_send_radiosw_update(); 2565 tpacpi_input_send_tabletsw(); 2566 2567 return 0; 2568 2569err_exit: 2570 delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); 2571 hotkey_dev_attributes = NULL; 2572 2573 return (res < 0)? res : 1; 2574} 2575 2576static bool hotkey_notify_hotkey(const u32 hkey, 2577 bool *send_acpi_ev, 2578 bool *ignore_acpi_ev) 2579{ 2580 /* 0x1000-0x1FFF: key presses */ 2581 unsigned int scancode = hkey & 0xfff; 2582 *send_acpi_ev = true; 2583 *ignore_acpi_ev = false; 2584 2585 if (scancode > 0 && scancode < 0x21) { 2586 scancode--; 2587 if (!(hotkey_source_mask & (1 << scancode))) { 2588 tpacpi_input_send_key(scancode); 2589 *send_acpi_ev = false; 2590 } else { 2591 *ignore_acpi_ev = true; 2592 } 2593 return true; 2594 } 2595 return false; 2596} 2597 2598static bool hotkey_notify_wakeup(const u32 hkey, 2599 bool *send_acpi_ev, 2600 bool *ignore_acpi_ev) 2601{ 2602 /* 0x2000-0x2FFF: Wakeup reason */ 2603 *send_acpi_ev = true; 2604 *ignore_acpi_ev = false; 2605 2606 switch (hkey) { 2607 case 0x2304: /* suspend, undock */ 2608 case 0x2404: /* hibernation, undock */ 2609 hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK; 2610 *ignore_acpi_ev = true; 2611 break; 2612 2613 case 0x2305: /* suspend, bay eject */ 2614 case 0x2405: /* hibernation, bay eject */ 2615 hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ; 2616 *ignore_acpi_ev = true; 2617 break; 2618 2619 case 0x2313: /* Battery on critical low level (S3) */ 2620 case 0x2413: /* Battery on critical low level (S4) */ 2621 printk(TPACPI_ALERT 2622 "EMERGENCY WAKEUP: battery almost empty\n"); 2623 /* how to auto-heal: */ 2624 /* 2313: woke up from S3, go to S4/S5 */ 2625 /* 2413: woke up from S4, go to S5 */ 2626 break; 2627 2628 default: 2629 return false; 2630 } 2631 2632 if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) { 2633 printk(TPACPI_INFO 2634 "woke up due to a hot-unplug " 2635 "request...\n"); 2636 hotkey_wakeup_reason_notify_change(); 2637 } 2638 return true; 2639} 2640 2641static bool hotkey_notify_usrevent(const u32 hkey, 2642 bool *send_acpi_ev, 2643 bool *ignore_acpi_ev) 2644{ 2645 /* 0x5000-0x5FFF: human interface helpers */ 2646 *send_acpi_ev = true; 2647 *ignore_acpi_ev = false; 2648 2649 switch (hkey) { 2650 case 0x5010: /* Lenovo new BIOS: brightness changed */ 2651 case 0x500b: /* X61t: tablet pen inserted into bay */ 2652 case 0x500c: /* X61t: tablet pen removed from bay */ 2653 return true; 2654 2655 case 0x5009: /* X41t-X61t: swivel up (tablet mode) */ 2656 case 0x500a: /* X41t-X61t: swivel down (normal mode) */ 2657 tpacpi_input_send_tabletsw(); 2658 hotkey_tablet_mode_notify_change(); 2659 *send_acpi_ev = false; 2660 return true; 2661 2662 case 0x5001: 2663 case 0x5002: 2664 /* LID switch events. Do not propagate */ 2665 *ignore_acpi_ev = true; 2666 return true; 2667 2668 default: 2669 return false; 2670 } 2671} 2672 2673static bool hotkey_notify_thermal(const u32 hkey, 2674 bool *send_acpi_ev, 2675 bool *ignore_acpi_ev) 2676{ 2677 /* 0x6000-0x6FFF: thermal alarms */ 2678 *send_acpi_ev = true; 2679 *ignore_acpi_ev = false; 2680 2681 switch (hkey) { 2682 case 0x6011: 2683 printk(TPACPI_CRIT 2684 "THERMAL ALARM: battery is too hot!\n"); 2685 /* recommended action: warn user through gui */ 2686 return true; 2687 case 0x6012: 2688 printk(TPACPI_ALERT 2689 "THERMAL EMERGENCY: battery is extremely hot!\n"); 2690 /* recommended action: immediate sleep/hibernate */ 2691 return true; 2692 case 0x6021: 2693 printk(TPACPI_CRIT 2694 "THERMAL ALARM: " 2695 "a sensor reports something is too hot!\n"); 2696 /* recommended action: warn user through gui, that */ 2697 /* some internal component is too hot */ 2698 return true; 2699 case 0x6022: 2700 printk(TPACPI_ALERT 2701 "THERMAL EMERGENCY: " 2702 "a sensor reports something is extremely hot!\n"); 2703 /* recommended action: immediate sleep/hibernate */ 2704 return true; 2705 case 0x6030: 2706 printk(TPACPI_INFO 2707 "EC reports that Thermal Table has changed\n"); 2708 /* recommended action: do nothing, we don't have 2709 * Lenovo ATM information */ 2710 return true; 2711 default: 2712 printk(TPACPI_ALERT 2713 "THERMAL ALERT: unknown thermal alarm received\n"); 2714 return false; 2715 } 2716} 2717 2718static void hotkey_notify(struct ibm_struct *ibm, u32 event) 2719{ 2720 u32 hkey; 2721 bool send_acpi_ev; 2722 bool ignore_acpi_ev; 2723 bool known_ev; 2724 2725 if (event != 0x80) { 2726 printk(TPACPI_ERR 2727 "unknown HKEY notification event %d\n", event); 2728 /* forward it to userspace, maybe it knows how to handle it */ 2729 acpi_bus_generate_netlink_event( 2730 ibm->acpi->device->pnp.device_class, 2731 dev_name(&ibm->acpi->device->dev), 2732 event, 0); 2733 return; 2734 } 2735 2736 while (1) { 2737 if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { 2738 printk(TPACPI_ERR "failed to retrieve HKEY event\n"); 2739 return; 2740 } 2741 2742 if (hkey == 0) { 2743 /* queue empty */ 2744 return; 2745 } 2746 2747 send_acpi_ev = true; 2748 ignore_acpi_ev = false; 2749 2750 switch (hkey >> 12) { 2751 case 1: 2752 /* 0x1000-0x1FFF: key presses */ 2753 known_ev = hotkey_notify_hotkey(hkey, &send_acpi_ev, 2754 &ignore_acpi_ev); 2755 break; 2756 case 2: 2757 /* 0x2000-0x2FFF: Wakeup reason */ 2758 known_ev = hotkey_notify_wakeup(hkey, &send_acpi_ev, 2759 &ignore_acpi_ev); 2760 break; 2761 case 3: 2762 /* 0x3000-0x3FFF: bay-related wakeups */ 2763 if (hkey == 0x3003) { 2764 hotkey_autosleep_ack = 1; 2765 printk(TPACPI_INFO 2766 "bay ejected\n"); 2767 hotkey_wakeup_hotunplug_complete_notify_change(); 2768 known_ev = true; 2769 } else { 2770 known_ev = false; 2771 } 2772 break; 2773 case 4: 2774 /* 0x4000-0x4FFF: dock-related wakeups */ 2775 if (hkey == 0x4003) { 2776 hotkey_autosleep_ack = 1; 2777 printk(TPACPI_INFO 2778 "undocked\n"); 2779 hotkey_wakeup_hotunplug_complete_notify_change(); 2780 known_ev = true; 2781 } else { 2782 known_ev = false; 2783 } 2784 break; 2785 case 5: 2786 /* 0x5000-0x5FFF: human interface helpers */ 2787 known_ev = hotkey_notify_usrevent(hkey, &send_acpi_ev, 2788 &ignore_acpi_ev); 2789 break; 2790 case 6: 2791 /* 0x6000-0x6FFF: thermal alarms */ 2792 known_ev = hotkey_notify_thermal(hkey, &send_acpi_ev, 2793 &ignore_acpi_ev); 2794 break; 2795 case 7: 2796 /* 0x7000-0x7FFF: misc */ 2797 if (tp_features.hotkey_wlsw && hkey == 0x7000) { 2798 tpacpi_send_radiosw_update(); 2799 send_acpi_ev = 0; 2800 known_ev = true; 2801 break; 2802 } 2803 /* fallthrough to default */ 2804 default: 2805 known_ev = false; 2806 } 2807 if (!known_ev) { 2808 printk(TPACPI_NOTICE 2809 "unhandled HKEY event 0x%04x\n", hkey); 2810 printk(TPACPI_NOTICE 2811 "please report the conditions when this " 2812 "event happened to %s\n", TPACPI_MAIL); 2813 } 2814 2815 /* Legacy events */ 2816 if (!ignore_acpi_ev && 2817 (send_acpi_ev || hotkey_report_mode < 2)) { 2818 acpi_bus_generate_proc_event(ibm->acpi->device, 2819 event, hkey); 2820 } 2821 2822 /* netlink events */ 2823 if (!ignore_acpi_ev && send_acpi_ev) { 2824 acpi_bus_generate_netlink_event( 2825 ibm->acpi->device->pnp.device_class, 2826 dev_name(&ibm->acpi->device->dev), 2827 event, hkey); 2828 } 2829 } 2830} 2831 2832static void hotkey_suspend(pm_message_t state) 2833{ 2834 /* Do these on suspend, we get the events on early resume! */ 2835 hotkey_wakeup_reason = TP_ACPI_WAKEUP_NONE; 2836 hotkey_autosleep_ack = 0; 2837} 2838 2839static void hotkey_resume(void) 2840{ 2841 tpacpi_disable_brightness_delay(); 2842 2843 if (hotkey_mask_get()) 2844 printk(TPACPI_ERR 2845 "error while trying to read hot key mask " 2846 "from firmware\n"); 2847 tpacpi_send_radiosw_update(); 2848 hotkey_tablet_mode_notify_change(); 2849 hotkey_wakeup_reason_notify_change(); 2850 hotkey_wakeup_hotunplug_complete_notify_change(); 2851 hotkey_poll_setup_safe(0); 2852} 2853 2854/* procfs -------------------------------------------------------------- */ 2855static int hotkey_read(char *p) 2856{ 2857 int res, status; 2858 int len = 0; 2859 2860 if (!tp_features.hotkey) { 2861 len += sprintf(p + len, "status:\t\tnot supported\n"); 2862 return len; 2863 } 2864 2865 if (mutex_lock_killable(&hotkey_mutex)) 2866 return -ERESTARTSYS; 2867 res = hotkey_status_get(&status); 2868 if (!res) 2869 res = hotkey_mask_get(); 2870 mutex_unlock(&hotkey_mutex); 2871 if (res) 2872 return res; 2873 2874 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); 2875 if (tp_features.hotkey_mask) { 2876 len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_mask); 2877 len += sprintf(p + len, 2878 "commands:\tenable, disable, reset, <mask>\n"); 2879 } else { 2880 len += sprintf(p + len, "mask:\t\tnot supported\n"); 2881 len += sprintf(p + len, "commands:\tenable, disable, reset\n"); 2882 } 2883 2884 return len; 2885} 2886 2887static int hotkey_write(char *buf) 2888{ 2889 int res, status; 2890 u32 mask; 2891 char *cmd; 2892 2893 if (!tp_features.hotkey) 2894 return -ENODEV; 2895 2896 if (mutex_lock_killable(&hotkey_mutex)) 2897 return -ERESTARTSYS; 2898 2899 status = -1; 2900 mask = hotkey_mask; 2901 2902 res = 0; 2903 while ((cmd = next_cmd(&buf))) { 2904 if (strlencmp(cmd, "enable") == 0) { 2905 status = 1; 2906 } else if (strlencmp(cmd, "disable") == 0) { 2907 status = 0; 2908 } else if (strlencmp(cmd, "reset") == 0) { 2909 status = hotkey_orig_status; 2910 mask = hotkey_orig_mask; 2911 } else if (sscanf(cmd, "0x%x", &mask) == 1) { 2912 /* mask set */ 2913 } else if (sscanf(cmd, "%x", &mask) == 1) { 2914 /* mask set */ 2915 } else { 2916 res = -EINVAL; 2917 goto errexit; 2918 } 2919 } 2920 if (status != -1) 2921 res = hotkey_status_set(status); 2922 2923 if (!res && mask != hotkey_mask) 2924 res = hotkey_mask_set(mask); 2925 2926errexit: 2927 mutex_unlock(&hotkey_mutex); 2928 return res; 2929} 2930 2931static const struct acpi_device_id ibm_htk_device_ids[] = { 2932 {TPACPI_ACPI_HKEY_HID, 0}, 2933 {"", 0}, 2934}; 2935 2936static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = { 2937 .hid = ibm_htk_device_ids, 2938 .notify = hotkey_notify, 2939 .handle = &hkey_handle, 2940 .type = ACPI_DEVICE_NOTIFY, 2941}; 2942 2943static struct ibm_struct hotkey_driver_data = { 2944 .name = "hotkey", 2945 .read = hotkey_read, 2946 .write = hotkey_write, 2947 .exit = hotkey_exit, 2948 .resume = hotkey_resume, 2949 .suspend = hotkey_suspend, 2950 .acpi = &ibm_hotkey_acpidriver, 2951}; 2952 2953/************************************************************************* 2954 * Bluetooth subdriver 2955 */ 2956 2957enum { 2958 /* ACPI GBDC/SBDC bits */ 2959 TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */ 2960 TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */ 2961 TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume: 2962 off / last state */ 2963}; 2964 2965enum { 2966 /* ACPI \BLTH commands */ 2967 TP_ACPI_BLTH_GET_ULTRAPORT_ID = 0x00, /* Get Ultraport BT ID */ 2968 TP_ACPI_BLTH_GET_PWR_ON_RESUME = 0x01, /* Get power-on-resume state */ 2969 TP_ACPI_BLTH_PWR_ON_ON_RESUME = 0x02, /* Resume powered on */ 2970 TP_ACPI_BLTH_PWR_OFF_ON_RESUME = 0x03, /* Resume powered off */ 2971 TP_ACPI_BLTH_SAVE_STATE = 0x05, /* Save state for S4/S5 */ 2972}; 2973 2974static struct rfkill *tpacpi_bluetooth_rfkill; 2975 2976static void bluetooth_suspend(pm_message_t state) 2977{ 2978 /* Try to make sure radio will resume powered off */ 2979 acpi_evalf(NULL, NULL, "\\BLTH", "vd", 2980 TP_ACPI_BLTH_PWR_OFF_ON_RESUME); 2981} 2982 2983static int bluetooth_get_radiosw(void) 2984{ 2985 int status; 2986 2987 if (!tp_features.bluetooth) 2988 return -ENODEV; 2989 2990 /* WLSW overrides bluetooth in firmware/hardware, reflect that */ 2991 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status) 2992 return RFKILL_STATE_HARD_BLOCKED; 2993 2994#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 2995 if (dbg_bluetoothemul) 2996 return (tpacpi_bluetooth_emulstate) ? 2997 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 2998#endif 2999 3000 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) 3001 return -EIO; 3002 3003 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ? 3004 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3005} 3006 3007static void bluetooth_update_rfk(void) 3008{ 3009 int status; 3010 3011 if (!tpacpi_bluetooth_rfkill) 3012 return; 3013 3014 status = bluetooth_get_radiosw(); 3015 if (status < 0) 3016 return; 3017 rfkill_force_state(tpacpi_bluetooth_rfkill, status); 3018} 3019 3020static int bluetooth_set_radiosw(int radio_on, int update_rfk) 3021{ 3022 int status; 3023 3024 if (!tp_features.bluetooth) 3025 return -ENODEV; 3026 3027 /* WLSW overrides bluetooth in firmware/hardware, but there is no 3028 * reason to risk weird behaviour. */ 3029 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status 3030 && radio_on) 3031 return -EPERM; 3032 3033#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3034 if (dbg_bluetoothemul) { 3035 tpacpi_bluetooth_emulstate = !!radio_on; 3036 if (update_rfk) 3037 bluetooth_update_rfk(); 3038 return 0; 3039 } 3040#endif 3041 3042 /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */ 3043 if (radio_on) 3044 status = TP_ACPI_BLUETOOTH_RADIOSSW; 3045 else 3046 status = 0; 3047 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) 3048 return -EIO; 3049 3050 if (update_rfk) 3051 bluetooth_update_rfk(); 3052 3053 return 0; 3054} 3055 3056/* sysfs bluetooth enable ---------------------------------------------- */ 3057static ssize_t bluetooth_enable_show(struct device *dev, 3058 struct device_attribute *attr, 3059 char *buf) 3060{ 3061 int status; 3062 3063 status = bluetooth_get_radiosw(); 3064 if (status < 0) 3065 return status; 3066 3067 return snprintf(buf, PAGE_SIZE, "%d\n", 3068 (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0); 3069} 3070 3071static ssize_t bluetooth_enable_store(struct device *dev, 3072 struct device_attribute *attr, 3073 const char *buf, size_t count) 3074{ 3075 unsigned long t; 3076 int res; 3077 3078 if (parse_strtoul(buf, 1, &t)) 3079 return -EINVAL; 3080 3081 res = bluetooth_set_radiosw(t, 1); 3082 3083 return (res) ? res : count; 3084} 3085 3086static struct device_attribute dev_attr_bluetooth_enable = 3087 __ATTR(bluetooth_enable, S_IWUSR | S_IRUGO, 3088 bluetooth_enable_show, bluetooth_enable_store); 3089 3090/* --------------------------------------------------------------------- */ 3091 3092static struct attribute *bluetooth_attributes[] = { 3093 &dev_attr_bluetooth_enable.attr, 3094 NULL 3095}; 3096 3097static const struct attribute_group bluetooth_attr_group = { 3098 .attrs = bluetooth_attributes, 3099}; 3100 3101static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state) 3102{ 3103 int bts = bluetooth_get_radiosw(); 3104 3105 if (bts < 0) 3106 return bts; 3107 3108 *state = bts; 3109 return 0; 3110} 3111 3112static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state) 3113{ 3114 return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); 3115} 3116 3117static void bluetooth_shutdown(void) 3118{ 3119 /* Order firmware to save current state to NVRAM */ 3120 if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd", 3121 TP_ACPI_BLTH_SAVE_STATE)) 3122 printk(TPACPI_NOTICE 3123 "failed to save bluetooth state to NVRAM\n"); 3124} 3125 3126static void bluetooth_exit(void) 3127{ 3128 bluetooth_shutdown(); 3129 3130 if (tpacpi_bluetooth_rfkill) 3131 rfkill_unregister(tpacpi_bluetooth_rfkill); 3132 3133 sysfs_remove_group(&tpacpi_pdev->dev.kobj, 3134 &bluetooth_attr_group); 3135} 3136 3137static int __init bluetooth_init(struct ibm_init_struct *iibm) 3138{ 3139 int res; 3140 int status = 0; 3141 3142 vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n"); 3143 3144 TPACPI_ACPIHANDLE_INIT(hkey); 3145 3146 /* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 3147 G4x, R30, R31, R40e, R50e, T20-22, X20-21 */ 3148 tp_features.bluetooth = hkey_handle && 3149 acpi_evalf(hkey_handle, &status, "GBDC", "qd"); 3150 3151 vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n", 3152 str_supported(tp_features.bluetooth), 3153 status); 3154 3155#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3156 if (dbg_bluetoothemul) { 3157 tp_features.bluetooth = 1; 3158 printk(TPACPI_INFO 3159 "bluetooth switch emulation enabled\n"); 3160 } else 3161#endif 3162 if (tp_features.bluetooth && 3163 !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) { 3164 /* no bluetooth hardware present in system */ 3165 tp_features.bluetooth = 0; 3166 dbg_printk(TPACPI_DBG_INIT, 3167 "bluetooth hardware not installed\n"); 3168 } 3169 3170 if (!tp_features.bluetooth) 3171 return 1; 3172 3173 res = sysfs_create_group(&tpacpi_pdev->dev.kobj, 3174 &bluetooth_attr_group); 3175 if (res) 3176 return res; 3177 3178 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID, 3179 &tpacpi_bluetooth_rfkill, 3180 RFKILL_TYPE_BLUETOOTH, 3181 "tpacpi_bluetooth_sw", 3182 true, 3183 tpacpi_bluetooth_rfk_set, 3184 tpacpi_bluetooth_rfk_get); 3185 if (res) { 3186 bluetooth_exit(); 3187 return res; 3188 } 3189 3190 return 0; 3191} 3192 3193/* procfs -------------------------------------------------------------- */ 3194static int bluetooth_read(char *p) 3195{ 3196 int len = 0; 3197 int status = bluetooth_get_radiosw(); 3198 3199 if (!tp_features.bluetooth) 3200 len += sprintf(p + len, "status:\t\tnot supported\n"); 3201 else { 3202 len += sprintf(p + len, "status:\t\t%s\n", 3203 (status == RFKILL_STATE_UNBLOCKED) ? 3204 "enabled" : "disabled"); 3205 len += sprintf(p + len, "commands:\tenable, disable\n"); 3206 } 3207 3208 return len; 3209} 3210 3211static int bluetooth_write(char *buf) 3212{ 3213 char *cmd; 3214 3215 if (!tp_features.bluetooth) 3216 return -ENODEV; 3217 3218 while ((cmd = next_cmd(&buf))) { 3219 if (strlencmp(cmd, "enable") == 0) { 3220 bluetooth_set_radiosw(1, 1); 3221 } else if (strlencmp(cmd, "disable") == 0) { 3222 bluetooth_set_radiosw(0, 1); 3223 } else 3224 return -EINVAL; 3225 } 3226 3227 return 0; 3228} 3229 3230static struct ibm_struct bluetooth_driver_data = { 3231 .name = "bluetooth", 3232 .read = bluetooth_read, 3233 .write = bluetooth_write, 3234 .exit = bluetooth_exit, 3235 .suspend = bluetooth_suspend, 3236 .shutdown = bluetooth_shutdown, 3237}; 3238 3239/************************************************************************* 3240 * Wan subdriver 3241 */ 3242 3243enum { 3244 /* ACPI GWAN/SWAN bits */ 3245 TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */ 3246 TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */ 3247 TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume: 3248 off / last state */ 3249}; 3250 3251static struct rfkill *tpacpi_wan_rfkill; 3252 3253static void wan_suspend(pm_message_t state) 3254{ 3255 /* Try to make sure radio will resume powered off */ 3256 acpi_evalf(NULL, NULL, "\\WGSV", "qvd", 3257 TP_ACPI_WGSV_PWR_OFF_ON_RESUME); 3258} 3259 3260static int wan_get_radiosw(void) 3261{ 3262 int status; 3263 3264 if (!tp_features.wan) 3265 return -ENODEV; 3266 3267 /* WLSW overrides WWAN in firmware/hardware, reflect that */ 3268 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status) 3269 return RFKILL_STATE_HARD_BLOCKED; 3270 3271#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3272 if (dbg_wwanemul) 3273 return (tpacpi_wwan_emulstate) ? 3274 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3275#endif 3276 3277 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) 3278 return -EIO; 3279 3280 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ? 3281 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3282} 3283 3284static void wan_update_rfk(void) 3285{ 3286 int status; 3287 3288 if (!tpacpi_wan_rfkill) 3289 return; 3290 3291 status = wan_get_radiosw(); 3292 if (status < 0) 3293 return; 3294 rfkill_force_state(tpacpi_wan_rfkill, status); 3295} 3296 3297static int wan_set_radiosw(int radio_on, int update_rfk) 3298{ 3299 int status; 3300 3301 if (!tp_features.wan) 3302 return -ENODEV; 3303 3304 /* WLSW overrides bluetooth in firmware/hardware, but there is no 3305 * reason to risk weird behaviour. */ 3306 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status 3307 && radio_on) 3308 return -EPERM; 3309 3310#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3311 if (dbg_wwanemul) { 3312 tpacpi_wwan_emulstate = !!radio_on; 3313 if (update_rfk) 3314 wan_update_rfk(); 3315 return 0; 3316 } 3317#endif 3318 3319 /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */ 3320 if (radio_on) 3321 status = TP_ACPI_WANCARD_RADIOSSW; 3322 else 3323 status = 0; 3324 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) 3325 return -EIO; 3326 3327 if (update_rfk) 3328 wan_update_rfk(); 3329 3330 return 0; 3331} 3332 3333/* sysfs wan enable ---------------------------------------------------- */ 3334static ssize_t wan_enable_show(struct device *dev, 3335 struct device_attribute *attr, 3336 char *buf) 3337{ 3338 int status; 3339 3340 status = wan_get_radiosw(); 3341 if (status < 0) 3342 return status; 3343 3344 return snprintf(buf, PAGE_SIZE, "%d\n", 3345 (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0); 3346} 3347 3348static ssize_t wan_enable_store(struct device *dev, 3349 struct device_attribute *attr, 3350 const char *buf, size_t count) 3351{ 3352 unsigned long t; 3353 int res; 3354 3355 if (parse_strtoul(buf, 1, &t)) 3356 return -EINVAL; 3357 3358 res = wan_set_radiosw(t, 1); 3359 3360 return (res) ? res : count; 3361} 3362 3363static struct device_attribute dev_attr_wan_enable = 3364 __ATTR(wwan_enable, S_IWUSR | S_IRUGO, 3365 wan_enable_show, wan_enable_store); 3366 3367/* --------------------------------------------------------------------- */ 3368 3369static struct attribute *wan_attributes[] = { 3370 &dev_attr_wan_enable.attr, 3371 NULL 3372}; 3373 3374static const struct attribute_group wan_attr_group = { 3375 .attrs = wan_attributes, 3376}; 3377 3378static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state) 3379{ 3380 int wans = wan_get_radiosw(); 3381 3382 if (wans < 0) 3383 return wans; 3384 3385 *state = wans; 3386 return 0; 3387} 3388 3389static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state) 3390{ 3391 return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); 3392} 3393 3394static void wan_shutdown(void) 3395{ 3396 /* Order firmware to save current state to NVRAM */ 3397 if (!acpi_evalf(NULL, NULL, "\\WGSV", "vd", 3398 TP_ACPI_WGSV_SAVE_STATE)) 3399 printk(TPACPI_NOTICE 3400 "failed to save WWAN state to NVRAM\n"); 3401} 3402 3403static void wan_exit(void) 3404{ 3405 wan_shutdown(); 3406 3407 if (tpacpi_wan_rfkill) 3408 rfkill_unregister(tpacpi_wan_rfkill); 3409 3410 sysfs_remove_group(&tpacpi_pdev->dev.kobj, 3411 &wan_attr_group); 3412} 3413 3414static int __init wan_init(struct ibm_init_struct *iibm) 3415{ 3416 int res; 3417 int status = 0; 3418 3419 vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n"); 3420 3421 TPACPI_ACPIHANDLE_INIT(hkey); 3422 3423 tp_features.wan = hkey_handle && 3424 acpi_evalf(hkey_handle, &status, "GWAN", "qd"); 3425 3426 vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n", 3427 str_supported(tp_features.wan), 3428 status); 3429 3430#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3431 if (dbg_wwanemul) { 3432 tp_features.wan = 1; 3433 printk(TPACPI_INFO 3434 "wwan switch emulation enabled\n"); 3435 } else 3436#endif 3437 if (tp_features.wan && 3438 !(status & TP_ACPI_WANCARD_HWPRESENT)) { 3439 /* no wan hardware present in system */ 3440 tp_features.wan = 0; 3441 dbg_printk(TPACPI_DBG_INIT, 3442 "wan hardware not installed\n"); 3443 } 3444 3445 if (!tp_features.wan) 3446 return 1; 3447 3448 res = sysfs_create_group(&tpacpi_pdev->dev.kobj, 3449 &wan_attr_group); 3450 if (res) 3451 return res; 3452 3453 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID, 3454 &tpacpi_wan_rfkill, 3455 RFKILL_TYPE_WWAN, 3456 "tpacpi_wwan_sw", 3457 true, 3458 tpacpi_wan_rfk_set, 3459 tpacpi_wan_rfk_get); 3460 if (res) { 3461 wan_exit(); 3462 return res; 3463 } 3464 3465 return 0; 3466} 3467 3468/* procfs -------------------------------------------------------------- */ 3469static int wan_read(char *p) 3470{ 3471 int len = 0; 3472 int status = wan_get_radiosw(); 3473 3474 if (!tp_features.wan) 3475 len += sprintf(p + len, "status:\t\tnot supported\n"); 3476 else { 3477 len += sprintf(p + len, "status:\t\t%s\n", 3478 (status == RFKILL_STATE_UNBLOCKED) ? 3479 "enabled" : "disabled"); 3480 len += sprintf(p + len, "commands:\tenable, disable\n"); 3481 } 3482 3483 return len; 3484} 3485 3486static int wan_write(char *buf) 3487{ 3488 char *cmd; 3489 3490 if (!tp_features.wan) 3491 return -ENODEV; 3492 3493 while ((cmd = next_cmd(&buf))) { 3494 if (strlencmp(cmd, "enable") == 0) { 3495 wan_set_radiosw(1, 1); 3496 } else if (strlencmp(cmd, "disable") == 0) { 3497 wan_set_radiosw(0, 1); 3498 } else 3499 return -EINVAL; 3500 } 3501 3502 return 0; 3503} 3504 3505static struct ibm_struct wan_driver_data = { 3506 .name = "wan", 3507 .read = wan_read, 3508 .write = wan_write, 3509 .exit = wan_exit, 3510 .suspend = wan_suspend, 3511 .shutdown = wan_shutdown, 3512}; 3513 3514/************************************************************************* 3515 * UWB subdriver 3516 */ 3517 3518enum { 3519 /* ACPI GUWB/SUWB bits */ 3520 TP_ACPI_UWB_HWPRESENT = 0x01, /* UWB hw available */ 3521 TP_ACPI_UWB_RADIOSSW = 0x02, /* UWB radio enabled */ 3522}; 3523 3524static struct rfkill *tpacpi_uwb_rfkill; 3525 3526static int uwb_get_radiosw(void) 3527{ 3528 int status; 3529 3530 if (!tp_features.uwb) 3531 return -ENODEV; 3532 3533 /* WLSW overrides UWB in firmware/hardware, reflect that */ 3534 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status) 3535 return RFKILL_STATE_HARD_BLOCKED; 3536 3537#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3538 if (dbg_uwbemul) 3539 return (tpacpi_uwb_emulstate) ? 3540 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3541#endif 3542 3543 if (!acpi_evalf(hkey_handle, &status, "GUWB", "d")) 3544 return -EIO; 3545 3546 return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ? 3547 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3548} 3549 3550static void uwb_update_rfk(void) 3551{ 3552 int status; 3553 3554 if (!tpacpi_uwb_rfkill) 3555 return; 3556 3557 status = uwb_get_radiosw(); 3558 if (status < 0) 3559 return; 3560 rfkill_force_state(tpacpi_uwb_rfkill, status); 3561} 3562 3563static int uwb_set_radiosw(int radio_on, int update_rfk) 3564{ 3565 int status; 3566 3567 if (!tp_features.uwb) 3568 return -ENODEV; 3569 3570 /* WLSW overrides UWB in firmware/hardware, but there is no 3571 * reason to risk weird behaviour. */ 3572 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status 3573 && radio_on) 3574 return -EPERM; 3575 3576#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3577 if (dbg_uwbemul) { 3578 tpacpi_uwb_emulstate = !!radio_on; 3579 if (update_rfk) 3580 uwb_update_rfk(); 3581 return 0; 3582 } 3583#endif 3584 3585 status = (radio_on) ? TP_ACPI_UWB_RADIOSSW : 0; 3586 if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status)) 3587 return -EIO; 3588 3589 if (update_rfk) 3590 uwb_update_rfk(); 3591 3592 return 0; 3593} 3594 3595/* --------------------------------------------------------------------- */ 3596 3597static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state) 3598{ 3599 int uwbs = uwb_get_radiosw(); 3600 3601 if (uwbs < 0) 3602 return uwbs; 3603 3604 *state = uwbs; 3605 return 0; 3606} 3607 3608static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state) 3609{ 3610 return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); 3611} 3612 3613static void uwb_exit(void) 3614{ 3615 if (tpacpi_uwb_rfkill) 3616 rfkill_unregister(tpacpi_uwb_rfkill); 3617} 3618 3619static int __init uwb_init(struct ibm_init_struct *iibm) 3620{ 3621 int res; 3622 int status = 0; 3623 3624 vdbg_printk(TPACPI_DBG_INIT, "initializing uwb subdriver\n"); 3625 3626 TPACPI_ACPIHANDLE_INIT(hkey); 3627 3628 tp_features.uwb = hkey_handle && 3629 acpi_evalf(hkey_handle, &status, "GUWB", "qd"); 3630 3631 vdbg_printk(TPACPI_DBG_INIT, "uwb is %s, status 0x%02x\n", 3632 str_supported(tp_features.uwb), 3633 status); 3634 3635#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3636 if (dbg_uwbemul) { 3637 tp_features.uwb = 1; 3638 printk(TPACPI_INFO 3639 "uwb switch emulation enabled\n"); 3640 } else 3641#endif 3642 if (tp_features.uwb && 3643 !(status & TP_ACPI_UWB_HWPRESENT)) { 3644 /* no uwb hardware present in system */ 3645 tp_features.uwb = 0; 3646 dbg_printk(TPACPI_DBG_INIT, 3647 "uwb hardware not installed\n"); 3648 } 3649 3650 if (!tp_features.uwb) 3651 return 1; 3652 3653 res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID, 3654 &tpacpi_uwb_rfkill, 3655 RFKILL_TYPE_UWB, 3656 "tpacpi_uwb_sw", 3657 false, 3658 tpacpi_uwb_rfk_set, 3659 tpacpi_uwb_rfk_get); 3660 3661 return res; 3662} 3663 3664static struct ibm_struct uwb_driver_data = { 3665 .name = "uwb", 3666 .exit = uwb_exit, 3667 .flags.experimental = 1, 3668}; 3669 3670/************************************************************************* 3671 * Video subdriver 3672 */ 3673 3674#ifdef CONFIG_THINKPAD_ACPI_VIDEO 3675 3676enum video_access_mode { 3677 TPACPI_VIDEO_NONE = 0, 3678 TPACPI_VIDEO_570, /* 570 */ 3679 TPACPI_VIDEO_770, /* 600e/x, 770e, 770x */ 3680 TPACPI_VIDEO_NEW, /* all others */ 3681}; 3682 3683enum { /* video status flags, based on VIDEO_570 */ 3684 TP_ACPI_VIDEO_S_LCD = 0x01, /* LCD output enabled */ 3685 TP_ACPI_VIDEO_S_CRT = 0x02, /* CRT output enabled */ 3686 TP_ACPI_VIDEO_S_DVI = 0x08, /* DVI output enabled */ 3687}; 3688 3689enum { /* TPACPI_VIDEO_570 constants */ 3690 TP_ACPI_VIDEO_570_PHSCMD = 0x87, /* unknown magic constant :( */ 3691 TP_ACPI_VIDEO_570_PHSMASK = 0x03, /* PHS bits that map to 3692 * video_status_flags */ 3693 TP_ACPI_VIDEO_570_PHS2CMD = 0x8b, /* unknown magic constant :( */ 3694 TP_ACPI_VIDEO_570_PHS2SET = 0x80, /* unknown magic constant :( */ 3695}; 3696 3697static enum video_access_mode video_supported; 3698static int video_orig_autosw; 3699 3700static int video_autosw_get(void); 3701static int video_autosw_set(int enable); 3702 3703TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID"); /* G41 */ 3704 3705static int __init video_init(struct ibm_init_struct *iibm) 3706{ 3707 int ivga; 3708 3709 vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n"); 3710 3711 TPACPI_ACPIHANDLE_INIT(vid); 3712 TPACPI_ACPIHANDLE_INIT(vid2); 3713 3714 if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga) 3715 /* G41, assume IVGA doesn't change */ 3716 vid_handle = vid2_handle; 3717 3718 if (!vid_handle) 3719 /* video switching not supported on R30, R31 */ 3720 video_supported = TPACPI_VIDEO_NONE; 3721 else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd")) 3722 /* 570 */ 3723 video_supported = TPACPI_VIDEO_570; 3724 else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd")) 3725 /* 600e/x, 770e, 770x */ 3726 video_supported = TPACPI_VIDEO_770; 3727 else 3728 /* all others */ 3729 video_supported = TPACPI_VIDEO_NEW; 3730 3731 vdbg_printk(TPACPI_DBG_INIT, "video is %s, mode %d\n", 3732 str_supported(video_supported != TPACPI_VIDEO_NONE), 3733 video_supported); 3734 3735 return (video_supported != TPACPI_VIDEO_NONE)? 0 : 1; 3736} 3737 3738static void video_exit(void) 3739{ 3740 dbg_printk(TPACPI_DBG_EXIT, 3741 "restoring original video autoswitch mode\n"); 3742 if (video_autosw_set(video_orig_autosw)) 3743 printk(TPACPI_ERR "error while trying to restore original " 3744 "video autoswitch mode\n"); 3745} 3746 3747static int video_outputsw_get(void) 3748{ 3749 int status = 0; 3750 int i; 3751 3752 switch (video_supported) { 3753 case TPACPI_VIDEO_570: 3754 if (!acpi_evalf(NULL, &i, "\\_SB.PHS", "dd", 3755 TP_ACPI_VIDEO_570_PHSCMD)) 3756 return -EIO; 3757 status = i & TP_ACPI_VIDEO_570_PHSMASK; 3758 break; 3759 case TPACPI_VIDEO_770: 3760 if (!acpi_evalf(NULL, &i, "\\VCDL", "d")) 3761 return -EIO; 3762 if (i) 3763 status |= TP_ACPI_VIDEO_S_LCD; 3764 if (!acpi_evalf(NULL, &i, "\\VCDC", "d")) 3765 return -EIO; 3766 if (i) 3767 status |= TP_ACPI_VIDEO_S_CRT; 3768 break; 3769 case TPACPI_VIDEO_NEW: 3770 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1) || 3771 !acpi_evalf(NULL, &i, "\\VCDC", "d")) 3772 return -EIO; 3773 if (i) 3774 status |= TP_ACPI_VIDEO_S_CRT; 3775 3776 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0) || 3777 !acpi_evalf(NULL, &i, "\\VCDL", "d")) 3778 return -EIO; 3779 if (i) 3780 status |= TP_ACPI_VIDEO_S_LCD; 3781 if (!acpi_evalf(NULL, &i, "\\VCDD", "d")) 3782 return -EIO; 3783 if (i) 3784 status |= TP_ACPI_VIDEO_S_DVI; 3785 break; 3786 default: 3787 return -ENOSYS; 3788 } 3789 3790 return status; 3791} 3792 3793static int video_outputsw_set(int status) 3794{ 3795 int autosw; 3796 int res = 0; 3797 3798 switch (video_supported) { 3799 case TPACPI_VIDEO_570: 3800 res = acpi_evalf(NULL, NULL, 3801 "\\_SB.PHS2", "vdd", 3802 TP_ACPI_VIDEO_570_PHS2CMD, 3803 status | TP_ACPI_VIDEO_570_PHS2SET); 3804 break; 3805 case TPACPI_VIDEO_770: 3806 autosw = video_autosw_get(); 3807 if (autosw < 0) 3808 return autosw; 3809 3810 res = video_autosw_set(1); 3811 if (res) 3812 return res; 3813 res = acpi_evalf(vid_handle, NULL, 3814 "ASWT", "vdd", status * 0x100, 0); 3815 if (!autosw && video_autosw_set(autosw)) { 3816 printk(TPACPI_ERR 3817 "video auto-switch left enabled due to error\n"); 3818 return -EIO; 3819 } 3820 break; 3821 case TPACPI_VIDEO_NEW: 3822 res = acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80) && 3823 acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1); 3824 break; 3825 default: 3826 return -ENOSYS; 3827 } 3828 3829 return (res)? 0 : -EIO; 3830} 3831 3832static int video_autosw_get(void) 3833{ 3834 int autosw = 0; 3835 3836 switch (video_supported) { 3837 case TPACPI_VIDEO_570: 3838 if (!acpi_evalf(vid_handle, &autosw, "SWIT", "d")) 3839 return -EIO; 3840 break; 3841 case TPACPI_VIDEO_770: 3842 case TPACPI_VIDEO_NEW: 3843 if (!acpi_evalf(vid_handle, &autosw, "^VDEE", "d")) 3844 return -EIO; 3845 break; 3846 default: 3847 return -ENOSYS; 3848 } 3849 3850 return autosw & 1; 3851} 3852 3853static int video_autosw_set(int enable) 3854{ 3855 if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", (enable)? 1 : 0)) 3856 return -EIO; 3857 return 0; 3858} 3859 3860static int video_outputsw_cycle(void) 3861{ 3862 int autosw = video_autosw_get(); 3863 int res; 3864 3865 if (autosw < 0) 3866 return autosw; 3867 3868 switch (video_supported) { 3869 case TPACPI_VIDEO_570: 3870 res = video_autosw_set(1); 3871 if (res) 3872 return res; 3873 res = acpi_evalf(ec_handle, NULL, "_Q16", "v"); 3874 break; 3875 case TPACPI_VIDEO_770: 3876 case TPACPI_VIDEO_NEW: 3877 res = video_autosw_set(1); 3878 if (res) 3879 return res; 3880 res = acpi_evalf(vid_handle, NULL, "VSWT", "v"); 3881 break; 3882 default: 3883 return -ENOSYS; 3884 } 3885 if (!autosw && video_autosw_set(autosw)) { 3886 printk(TPACPI_ERR 3887 "video auto-switch left enabled due to error\n"); 3888 return -EIO; 3889 } 3890 3891 return (res)? 0 : -EIO; 3892} 3893 3894static int video_expand_toggle(void) 3895{ 3896 switch (video_supported) { 3897 case TPACPI_VIDEO_570: 3898 return acpi_evalf(ec_handle, NULL, "_Q17", "v")? 3899 0 : -EIO; 3900 case TPACPI_VIDEO_770: 3901 return acpi_evalf(vid_handle, NULL, "VEXP", "v")? 3902 0 : -EIO; 3903 case TPACPI_VIDEO_NEW: 3904 return acpi_evalf(NULL, NULL, "\\VEXP", "v")? 3905 0 : -EIO; 3906 default: 3907 return -ENOSYS; 3908 } 3909 /* not reached */ 3910} 3911 3912static int video_read(char *p) 3913{ 3914 int status, autosw; 3915 int len = 0; 3916 3917 if (video_supported == TPACPI_VIDEO_NONE) { 3918 len += sprintf(p + len, "status:\t\tnot supported\n"); 3919 return len; 3920 } 3921 3922 status = video_outputsw_get(); 3923 if (status < 0) 3924 return status; 3925 3926 autosw = video_autosw_get(); 3927 if (autosw < 0) 3928 return autosw; 3929 3930 len += sprintf(p + len, "status:\t\tsupported\n"); 3931 len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0)); 3932 len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1)); 3933 if (video_supported == TPACPI_VIDEO_NEW) 3934 len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3)); 3935 len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0)); 3936 len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n"); 3937 len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n"); 3938 if (video_supported == TPACPI_VIDEO_NEW) 3939 len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n"); 3940 len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n"); 3941 len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n"); 3942 3943 return len; 3944} 3945 3946static int video_write(char *buf) 3947{ 3948 char *cmd; 3949 int enable, disable, status; 3950 int res; 3951 3952 if (video_supported == TPACPI_VIDEO_NONE) 3953 return -ENODEV; 3954 3955 enable = 0; 3956 disable = 0; 3957 3958 while ((cmd = next_cmd(&buf))) { 3959 if (strlencmp(cmd, "lcd_enable") == 0) { 3960 enable |= TP_ACPI_VIDEO_S_LCD; 3961 } else if (strlencmp(cmd, "lcd_disable") == 0) { 3962 disable |= TP_ACPI_VIDEO_S_LCD; 3963 } else if (strlencmp(cmd, "crt_enable") == 0) { 3964 enable |= TP_ACPI_VIDEO_S_CRT; 3965 } else if (strlencmp(cmd, "crt_disable") == 0) { 3966 disable |= TP_ACPI_VIDEO_S_CRT; 3967 } else if (video_supported == TPACPI_VIDEO_NEW && 3968 strlencmp(cmd, "dvi_enable") == 0) { 3969 enable |= TP_ACPI_VIDEO_S_DVI; 3970 } else if (video_supported == TPACPI_VIDEO_NEW && 3971 strlencmp(cmd, "dvi_disable") == 0) { 3972 disable |= TP_ACPI_VIDEO_S_DVI; 3973 } else if (strlencmp(cmd, "auto_enable") == 0) { 3974 res = video_autosw_set(1); 3975 if (res) 3976 return res; 3977 } else if (strlencmp(cmd, "auto_disable") == 0) { 3978 res = video_autosw_set(0); 3979 if (res) 3980 return res; 3981 } else if (strlencmp(cmd, "video_switch") == 0) { 3982 res = video_outputsw_cycle(); 3983 if (res) 3984 return res; 3985 } else if (strlencmp(cmd, "expand_toggle") == 0) { 3986 res = video_expand_toggle(); 3987 if (res) 3988 return res; 3989 } else 3990 return -EINVAL; 3991 } 3992 3993 if (enable || disable) { 3994 status = video_outputsw_get(); 3995 if (status < 0) 3996 return status; 3997 res = video_outputsw_set((status & ~disable) | enable); 3998 if (res) 3999 return res; 4000 } 4001 4002 return 0; 4003} 4004 4005static struct ibm_struct video_driver_data = { 4006 .name = "video", 4007 .read = video_read, 4008 .write = video_write, 4009 .exit = video_exit, 4010}; 4011 4012#endif /* CONFIG_THINKPAD_ACPI_VIDEO */ 4013 4014/************************************************************************* 4015 * Light (thinklight) subdriver 4016 */ 4017 4018TPACPI_HANDLE(lght, root, "\\LGHT"); /* A21e, A2xm/p, T20-22, X20-21 */ 4019TPACPI_HANDLE(ledb, ec, "LEDB"); /* G4x */ 4020 4021static int light_get_status(void) 4022{ 4023 int status = 0; 4024 4025 if (tp_features.light_status) { 4026 if (!acpi_evalf(ec_handle, &status, "KBLT", "d")) 4027 return -EIO; 4028 return (!!status); 4029 } 4030 4031 return -ENXIO; 4032} 4033 4034static int light_set_status(int status) 4035{ 4036 int rc; 4037 4038 if (tp_features.light) { 4039 if (cmos_handle) { 4040 rc = acpi_evalf(cmos_handle, NULL, NULL, "vd", 4041 (status)? 4042 TP_CMOS_THINKLIGHT_ON : 4043 TP_CMOS_THINKLIGHT_OFF); 4044 } else { 4045 rc = acpi_evalf(lght_handle, NULL, NULL, "vd", 4046 (status)? 1 : 0); 4047 } 4048 return (rc)? 0 : -EIO; 4049 } 4050 4051 return -ENXIO; 4052} 4053 4054static void light_set_status_worker(struct work_struct *work) 4055{ 4056 struct tpacpi_led_classdev *data = 4057 container_of(work, struct tpacpi_led_classdev, work); 4058 4059 if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) 4060 light_set_status((data->new_brightness != LED_OFF)); 4061} 4062 4063static void light_sysfs_set(struct led_classdev *led_cdev, 4064 enum led_brightness brightness) 4065{ 4066 struct tpacpi_led_classdev *data = 4067 container_of(led_cdev, 4068 struct tpacpi_led_classdev, 4069 led_classdev); 4070 data->new_brightness = brightness; 4071 queue_work(tpacpi_wq, &data->work); 4072} 4073 4074static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev) 4075{ 4076 return (light_get_status() == 1)? LED_FULL : LED_OFF; 4077} 4078 4079static struct tpacpi_led_classdev tpacpi_led_thinklight = { 4080 .led_classdev = { 4081 .name = "tpacpi::thinklight", 4082 .brightness_set = &light_sysfs_set, 4083 .brightness_get = &light_sysfs_get, 4084 } 4085}; 4086 4087static int __init light_init(struct ibm_init_struct *iibm) 4088{ 4089 int rc; 4090 4091 vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n"); 4092 4093 TPACPI_ACPIHANDLE_INIT(ledb); 4094 TPACPI_ACPIHANDLE_INIT(lght); 4095 TPACPI_ACPIHANDLE_INIT(cmos); 4096 INIT_WORK(&tpacpi_led_thinklight.work, light_set_status_worker); 4097 4098 /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */ 4099 tp_features.light = (cmos_handle || lght_handle) && !ledb_handle; 4100 4101 if (tp_features.light) 4102 /* light status not supported on 4103 570, 600e/x, 770e, 770x, G4x, R30, R31, R32, X20 */ 4104 tp_features.light_status = 4105 acpi_evalf(ec_handle, NULL, "KBLT", "qv"); 4106 4107 vdbg_printk(TPACPI_DBG_INIT, "light is %s, light status is %s\n", 4108 str_supported(tp_features.light), 4109 str_supported(tp_features.light_status)); 4110 4111 if (!tp_features.light) 4112 return 1; 4113 4114 rc = led_classdev_register(&tpacpi_pdev->dev, 4115 &tpacpi_led_thinklight.led_classdev); 4116 4117 if (rc < 0) { 4118 tp_features.light = 0; 4119 tp_features.light_status = 0; 4120 } else { 4121 rc = 0; 4122 } 4123 4124 return rc; 4125} 4126 4127static void light_exit(void) 4128{ 4129 led_classdev_unregister(&tpacpi_led_thinklight.led_classdev); 4130 if (work_pending(&tpacpi_led_thinklight.work)) 4131 flush_workqueue(tpacpi_wq); 4132} 4133 4134static int light_read(char *p) 4135{ 4136 int len = 0; 4137 int status; 4138 4139 if (!tp_features.light) { 4140 len += sprintf(p + len, "status:\t\tnot supported\n"); 4141 } else if (!tp_features.light_status) { 4142 len += sprintf(p + len, "status:\t\tunknown\n"); 4143 len += sprintf(p + len, "commands:\ton, off\n"); 4144 } else { 4145 status = light_get_status(); 4146 if (status < 0) 4147 return status; 4148 len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0)); 4149 len += sprintf(p + len, "commands:\ton, off\n"); 4150 } 4151 4152 return len; 4153} 4154 4155static int light_write(char *buf) 4156{ 4157 char *cmd; 4158 int newstatus = 0; 4159 4160 if (!tp_features.light) 4161 return -ENODEV; 4162 4163 while ((cmd = next_cmd(&buf))) { 4164 if (strlencmp(cmd, "on") == 0) { 4165 newstatus = 1; 4166 } else if (strlencmp(cmd, "off") == 0) { 4167 newstatus = 0; 4168 } else 4169 return -EINVAL; 4170 } 4171 4172 return light_set_status(newstatus); 4173} 4174 4175static struct ibm_struct light_driver_data = { 4176 .name = "light", 4177 .read = light_read, 4178 .write = light_write, 4179 .exit = light_exit, 4180}; 4181 4182/************************************************************************* 4183 * Dock subdriver 4184 */ 4185 4186#ifdef CONFIG_THINKPAD_ACPI_DOCK 4187 4188static void dock_notify(struct ibm_struct *ibm, u32 event); 4189static int dock_read(char *p); 4190static int dock_write(char *buf); 4191 4192TPACPI_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */ 4193 "\\_SB.PCI0.DOCK", /* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */ 4194 "\\_SB.PCI0.PCI1.DOCK", /* all others */ 4195 "\\_SB.PCI.ISA.SLCE", /* 570 */ 4196 ); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */ 4197 4198/* don't list other alternatives as we install a notify handler on the 570 */ 4199TPACPI_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */ 4200 4201static const struct acpi_device_id ibm_pci_device_ids[] = { 4202 {PCI_ROOT_HID_STRING, 0}, 4203 {"", 0}, 4204}; 4205 4206static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = { 4207 { 4208 .notify = dock_notify, 4209 .handle = &dock_handle, 4210 .type = ACPI_SYSTEM_NOTIFY, 4211 }, 4212 { 4213 /* THIS ONE MUST NEVER BE USED FOR DRIVER AUTOLOADING. 4214 * We just use it to get notifications of dock hotplug 4215 * in very old thinkpads */ 4216 .hid = ibm_pci_device_ids, 4217 .notify = dock_notify, 4218 .handle = &pci_handle, 4219 .type = ACPI_SYSTEM_NOTIFY, 4220 }, 4221}; 4222 4223static struct ibm_struct dock_driver_data[2] = { 4224 { 4225 .name = "dock", 4226 .read = dock_read, 4227 .write = dock_write, 4228 .acpi = &ibm_dock_acpidriver[0], 4229 }, 4230 { 4231 .name = "dock", 4232 .acpi = &ibm_dock_acpidriver[1], 4233 }, 4234}; 4235 4236#define dock_docked() (_sta(dock_handle) & 1) 4237 4238static int __init dock_init(struct ibm_init_struct *iibm) 4239{ 4240 vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver\n"); 4241 4242 TPACPI_ACPIHANDLE_INIT(dock); 4243 4244 vdbg_printk(TPACPI_DBG_INIT, "dock is %s\n", 4245 str_supported(dock_handle != NULL)); 4246 4247 return (dock_handle)? 0 : 1; 4248} 4249 4250static int __init dock_init2(struct ibm_init_struct *iibm) 4251{ 4252 int dock2_needed; 4253 4254 vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver part 2\n"); 4255 4256 if (dock_driver_data[0].flags.acpi_driver_registered && 4257 dock_driver_data[0].flags.acpi_notify_installed) { 4258 TPACPI_ACPIHANDLE_INIT(pci); 4259 dock2_needed = (pci_handle != NULL); 4260 vdbg_printk(TPACPI_DBG_INIT, 4261 "dock PCI handler for the TP 570 is %s\n", 4262 str_supported(dock2_needed)); 4263 } else { 4264 vdbg_printk(TPACPI_DBG_INIT, 4265 "dock subdriver part 2 not required\n"); 4266 dock2_needed = 0; 4267 } 4268 4269 return (dock2_needed)? 0 : 1; 4270} 4271 4272static void dock_notify(struct ibm_struct *ibm, u32 event) 4273{ 4274 int docked = dock_docked(); 4275 int pci = ibm->acpi->hid && ibm->acpi->device && 4276 acpi_match_device_ids(ibm->acpi->device, ibm_pci_device_ids); 4277 int data; 4278 4279 if (event == 1 && !pci) /* 570 */ 4280 data = 1; /* button */ 4281 else if (event == 1 && pci) /* 570 */ 4282 data = 3; /* dock */ 4283 else if (event == 3 && docked) 4284 data = 1; /* button */ 4285 else if (event == 3 && !docked) 4286 data = 2; /* undock */ 4287 else if (event == 0 && docked) 4288 data = 3; /* dock */ 4289 else { 4290 printk(TPACPI_ERR "unknown dock event %d, status %d\n", 4291 event, _sta(dock_handle)); 4292 data = 0; /* unknown */ 4293 } 4294 acpi_bus_generate_proc_event(ibm->acpi->device, event, data); 4295 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, 4296 dev_name(&ibm->acpi->device->dev), 4297 event, data); 4298} 4299 4300static int dock_read(char *p) 4301{ 4302 int len = 0; 4303 int docked = dock_docked(); 4304 4305 if (!dock_handle) 4306 len += sprintf(p + len, "status:\t\tnot supported\n"); 4307 else if (!docked) 4308 len += sprintf(p + len, "status:\t\tundocked\n"); 4309 else { 4310 len += sprintf(p + len, "status:\t\tdocked\n"); 4311 len += sprintf(p + len, "commands:\tdock, undock\n"); 4312 } 4313 4314 return len; 4315} 4316 4317static int dock_write(char *buf) 4318{ 4319 char *cmd; 4320 4321 if (!dock_docked()) 4322 return -ENODEV; 4323 4324 while ((cmd = next_cmd(&buf))) { 4325 if (strlencmp(cmd, "undock") == 0) { 4326 if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 0) || 4327 !acpi_evalf(dock_handle, NULL, "_EJ0", "vd", 1)) 4328 return -EIO; 4329 } else if (strlencmp(cmd, "dock") == 0) { 4330 if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 1)) 4331 return -EIO; 4332 } else 4333 return -EINVAL; 4334 } 4335 4336 return 0; 4337} 4338 4339#endif /* CONFIG_THINKPAD_ACPI_DOCK */ 4340 4341/************************************************************************* 4342 * Bay subdriver 4343 */ 4344 4345#ifdef CONFIG_THINKPAD_ACPI_BAY 4346 4347TPACPI_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */ 4348 "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */ 4349 "\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */ 4350 "\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */ 4351 ); /* A21e, R30, R31 */ 4352TPACPI_HANDLE(bay_ej, bay, "_EJ3", /* 600e/x, A2xm/p, A3x */ 4353 "_EJ0", /* all others */ 4354 ); /* 570,A21e,G4x,R30,R31,R32,R40e,R50e */ 4355TPACPI_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV", /* A3x, R32 */ 4356 "\\_SB.PCI0.IDE0.IDEP.IDPS", /* 600e/x, 770e, 770x */ 4357 ); /* all others */ 4358TPACPI_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */ 4359 "_EJ0", /* 770x */ 4360 ); /* all others */ 4361 4362static int __init bay_init(struct ibm_init_struct *iibm) 4363{ 4364 vdbg_printk(TPACPI_DBG_INIT, "initializing bay subdriver\n"); 4365 4366 TPACPI_ACPIHANDLE_INIT(bay); 4367 if (bay_handle) 4368 TPACPI_ACPIHANDLE_INIT(bay_ej); 4369 TPACPI_ACPIHANDLE_INIT(bay2); 4370 if (bay2_handle) 4371 TPACPI_ACPIHANDLE_INIT(bay2_ej); 4372 4373 tp_features.bay_status = bay_handle && 4374 acpi_evalf(bay_handle, NULL, "_STA", "qv"); 4375 tp_features.bay_status2 = bay2_handle && 4376 acpi_evalf(bay2_handle, NULL, "_STA", "qv"); 4377 4378 tp_features.bay_eject = bay_handle && bay_ej_handle && 4379 (strlencmp(bay_ej_path, "_EJ0") == 0 || experimental); 4380 tp_features.bay_eject2 = bay2_handle && bay2_ej_handle && 4381 (strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental); 4382 4383 vdbg_printk(TPACPI_DBG_INIT, 4384 "bay 1: status %s, eject %s; bay 2: status %s, eject %s\n", 4385 str_supported(tp_features.bay_status), 4386 str_supported(tp_features.bay_eject), 4387 str_supported(tp_features.bay_status2), 4388 str_supported(tp_features.bay_eject2)); 4389 4390 return (tp_features.bay_status || tp_features.bay_eject || 4391 tp_features.bay_status2 || tp_features.bay_eject2)? 0 : 1; 4392} 4393 4394static void bay_notify(struct ibm_struct *ibm, u32 event) 4395{ 4396 acpi_bus_generate_proc_event(ibm->acpi->device, event, 0); 4397 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, 4398 dev_name(&ibm->acpi->device->dev), 4399 event, 0); 4400} 4401 4402#define bay_occupied(b) (_sta(b##_handle) & 1) 4403 4404static int bay_read(char *p) 4405{ 4406 int len = 0; 4407 int occupied = bay_occupied(bay); 4408 int occupied2 = bay_occupied(bay2); 4409 int eject, eject2; 4410 4411 len += sprintf(p + len, "status:\t\t%s\n", 4412 tp_features.bay_status ? 4413 (occupied ? "occupied" : "unoccupied") : 4414 "not supported"); 4415 if (tp_features.bay_status2) 4416 len += sprintf(p + len, "status2:\t%s\n", occupied2 ? 4417 "occupied" : "unoccupied"); 4418 4419 eject = tp_features.bay_eject && occupied; 4420 eject2 = tp_features.bay_eject2 && occupied2; 4421 4422 if (eject && eject2) 4423 len += sprintf(p + len, "commands:\teject, eject2\n"); 4424 else if (eject) 4425 len += sprintf(p + len, "commands:\teject\n"); 4426 else if (eject2) 4427 len += sprintf(p + len, "commands:\teject2\n"); 4428 4429 return len; 4430} 4431 4432static int bay_write(char *buf) 4433{ 4434 char *cmd; 4435 4436 if (!tp_features.bay_eject && !tp_features.bay_eject2) 4437 return -ENODEV; 4438 4439 while ((cmd = next_cmd(&buf))) { 4440 if (tp_features.bay_eject && strlencmp(cmd, "eject") == 0) { 4441 if (!acpi_evalf(bay_ej_handle, NULL, NULL, "vd", 1)) 4442 return -EIO; 4443 } else if (tp_features.bay_eject2 && 4444 strlencmp(cmd, "eject2") == 0) { 4445 if (!acpi_evalf(bay2_ej_handle, NULL, NULL, "vd", 1)) 4446 return -EIO; 4447 } else 4448 return -EINVAL; 4449 } 4450 4451 return 0; 4452} 4453 4454static struct tp_acpi_drv_struct ibm_bay_acpidriver = { 4455 .notify = bay_notify, 4456 .handle = &bay_handle, 4457 .type = ACPI_SYSTEM_NOTIFY, 4458}; 4459 4460static struct ibm_struct bay_driver_data = { 4461 .name = "bay", 4462 .read = bay_read, 4463 .write = bay_write, 4464 .acpi = &ibm_bay_acpidriver, 4465}; 4466 4467#endif /* CONFIG_THINKPAD_ACPI_BAY */ 4468 4469/************************************************************************* 4470 * CMOS subdriver 4471 */ 4472 4473/* sysfs cmos_command -------------------------------------------------- */ 4474static ssize_t cmos_command_store(struct device *dev, 4475 struct device_attribute *attr, 4476 const char *buf, size_t count) 4477{ 4478 unsigned long cmos_cmd; 4479 int res; 4480 4481 if (parse_strtoul(buf, 21, &cmos_cmd)) 4482 return -EINVAL; 4483 4484 res = issue_thinkpad_cmos_command(cmos_cmd); 4485 return (res)? res : count; 4486} 4487 4488static struct device_attribute dev_attr_cmos_command = 4489 __ATTR(cmos_command, S_IWUSR, NULL, cmos_command_store); 4490 4491/* --------------------------------------------------------------------- */ 4492 4493static int __init cmos_init(struct ibm_init_struct *iibm) 4494{ 4495 int res; 4496 4497 vdbg_printk(TPACPI_DBG_INIT, 4498 "initializing cmos commands subdriver\n"); 4499 4500 TPACPI_ACPIHANDLE_INIT(cmos); 4501 4502 vdbg_printk(TPACPI_DBG_INIT, "cmos commands are %s\n", 4503 str_supported(cmos_handle != NULL)); 4504 4505 res = device_create_file(&tpacpi_pdev->dev, &dev_attr_cmos_command); 4506 if (res) 4507 return res; 4508 4509 return (cmos_handle)? 0 : 1; 4510} 4511 4512static void cmos_exit(void) 4513{ 4514 device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command); 4515} 4516 4517static int cmos_read(char *p) 4518{ 4519 int len = 0; 4520 4521 /* cmos not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 4522 R30, R31, T20-22, X20-21 */ 4523 if (!cmos_handle) 4524 len += sprintf(p + len, "status:\t\tnot supported\n"); 4525 else { 4526 len += sprintf(p + len, "status:\t\tsupported\n"); 4527 len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-21)\n"); 4528 } 4529 4530 return len; 4531} 4532 4533static int cmos_write(char *buf) 4534{ 4535 char *cmd; 4536 int cmos_cmd, res; 4537 4538 while ((cmd = next_cmd(&buf))) { 4539 if (sscanf(cmd, "%u", &cmos_cmd) == 1 && 4540 cmos_cmd >= 0 && cmos_cmd <= 21) { 4541 /* cmos_cmd set */ 4542 } else 4543 return -EINVAL; 4544 4545 res = issue_thinkpad_cmos_command(cmos_cmd); 4546 if (res) 4547 return res; 4548 } 4549 4550 return 0; 4551} 4552 4553static struct ibm_struct cmos_driver_data = { 4554 .name = "cmos", 4555 .read = cmos_read, 4556 .write = cmos_write, 4557 .exit = cmos_exit, 4558}; 4559 4560/************************************************************************* 4561 * LED subdriver 4562 */ 4563 4564enum led_access_mode { 4565 TPACPI_LED_NONE = 0, 4566 TPACPI_LED_570, /* 570 */ 4567 TPACPI_LED_OLD, /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ 4568 TPACPI_LED_NEW, /* all others */ 4569}; 4570 4571enum { /* For TPACPI_LED_OLD */ 4572 TPACPI_LED_EC_HLCL = 0x0c, /* EC reg to get led to power on */ 4573 TPACPI_LED_EC_HLBL = 0x0d, /* EC reg to blink a lit led */ 4574 TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */ 4575}; 4576 4577enum led_status_t { 4578 TPACPI_LED_OFF = 0, 4579 TPACPI_LED_ON, 4580 TPACPI_LED_BLINK, 4581}; 4582 4583static enum led_access_mode led_supported; 4584 4585TPACPI_HANDLE(led, ec, "SLED", /* 570 */ 4586 "SYSL", /* 600e/x, 770e, 770x, A21e, A2xm/p, */ 4587 /* T20-22, X20-21 */ 4588 "LED", /* all others */ 4589 ); /* R30, R31 */ 4590 4591#define TPACPI_LED_NUMLEDS 8 4592static struct tpacpi_led_classdev *tpacpi_leds; 4593static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS]; 4594static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = { 4595 /* there's a limit of 19 chars + NULL before 2.6.26 */ 4596 "tpacpi::power", 4597 "tpacpi:orange:batt", 4598 "tpacpi:green:batt", 4599 "tpacpi::dock_active", 4600 "tpacpi::bay_active", 4601 "tpacpi::dock_batt", 4602 "tpacpi::unknown_led", 4603 "tpacpi::standby", 4604}; 4605 4606static int led_get_status(const unsigned int led) 4607{ 4608 int status; 4609 enum led_status_t led_s; 4610 4611 switch (led_supported) { 4612 case TPACPI_LED_570: 4613 if (!acpi_evalf(ec_handle, 4614 &status, "GLED", "dd", 1 << led)) 4615 return -EIO; 4616 led_s = (status == 0)? 4617 TPACPI_LED_OFF : 4618 ((status == 1)? 4619 TPACPI_LED_ON : 4620 TPACPI_LED_BLINK); 4621 tpacpi_led_state_cache[led] = led_s; 4622 return led_s; 4623 default: 4624 return -ENXIO; 4625 } 4626 4627 /* not reached */ 4628} 4629 4630static int led_set_status(const unsigned int led, 4631 const enum led_status_t ledstatus) 4632{ 4633 /* off, on, blink. Index is led_status_t */ 4634 static const unsigned int led_sled_arg1[] = { 0, 1, 3 }; 4635 static const unsigned int led_led_arg1[] = { 0, 0x80, 0xc0 }; 4636 4637 int rc = 0; 4638 4639 switch (led_supported) { 4640 case TPACPI_LED_570: 4641 /* 570 */ 4642 if (led > 7) 4643 return -EINVAL; 4644 if (!acpi_evalf(led_handle, NULL, NULL, "vdd", 4645 (1 << led), led_sled_arg1[ledstatus])) 4646 rc = -EIO; 4647 break; 4648 case TPACPI_LED_OLD: 4649 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ 4650 if (led > 7) 4651 return -EINVAL; 4652 rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led)); 4653 if (rc >= 0) 4654 rc = ec_write(TPACPI_LED_EC_HLBL, 4655 (ledstatus == TPACPI_LED_BLINK) << led); 4656 if (rc >= 0) 4657 rc = ec_write(TPACPI_LED_EC_HLCL, 4658 (ledstatus != TPACPI_LED_OFF) << led); 4659 break; 4660 case TPACPI_LED_NEW: 4661 /* all others */ 4662 if (!acpi_evalf(led_handle, NULL, NULL, "vdd", 4663 led, led_led_arg1[ledstatus])) 4664 rc = -EIO; 4665 break; 4666 default: 4667 rc = -ENXIO; 4668 } 4669 4670 if (!rc) 4671 tpacpi_led_state_cache[led] = ledstatus; 4672 4673 return rc; 4674} 4675 4676static void led_sysfs_set_status(unsigned int led, 4677 enum led_brightness brightness) 4678{ 4679 led_set_status(led, 4680 (brightness == LED_OFF) ? 4681 TPACPI_LED_OFF : 4682 (tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ? 4683 TPACPI_LED_BLINK : TPACPI_LED_ON); 4684} 4685 4686static void led_set_status_worker(struct work_struct *work) 4687{ 4688 struct tpacpi_led_classdev *data = 4689 container_of(work, struct tpacpi_led_classdev, work); 4690 4691 if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) 4692 led_sysfs_set_status(data->led, data->new_brightness); 4693} 4694 4695static void led_sysfs_set(struct led_classdev *led_cdev, 4696 enum led_brightness brightness) 4697{ 4698 struct tpacpi_led_classdev *data = container_of(led_cdev, 4699 struct tpacpi_led_classdev, led_classdev); 4700 4701 data->new_brightness = brightness; 4702 queue_work(tpacpi_wq, &data->work); 4703} 4704 4705static int led_sysfs_blink_set(struct led_classdev *led_cdev, 4706 unsigned long *delay_on, unsigned long *delay_off) 4707{ 4708 struct tpacpi_led_classdev *data = container_of(led_cdev, 4709 struct tpacpi_led_classdev, led_classdev); 4710 4711 /* Can we choose the flash rate? */ 4712 if (*delay_on == 0 && *delay_off == 0) { 4713 /* yes. set them to the hardware blink rate (1 Hz) */ 4714 *delay_on = 500; /* ms */ 4715 *delay_off = 500; /* ms */ 4716 } else if ((*delay_on != 500) || (*delay_off != 500)) 4717 return -EINVAL; 4718 4719 data->new_brightness = TPACPI_LED_BLINK; 4720 queue_work(tpacpi_wq, &data->work); 4721 4722 return 0; 4723} 4724 4725static enum led_brightness led_sysfs_get(struct led_classdev *led_cdev) 4726{ 4727 int rc; 4728 4729 struct tpacpi_led_classdev *data = container_of(led_cdev, 4730 struct tpacpi_led_classdev, led_classdev); 4731 4732 rc = led_get_status(data->led); 4733 4734 if (rc == TPACPI_LED_OFF || rc < 0) 4735 rc = LED_OFF; /* no error handling in led class :( */ 4736 else 4737 rc = LED_FULL; 4738 4739 return rc; 4740} 4741 4742static void led_exit(void) 4743{ 4744 unsigned int i; 4745 4746 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) { 4747 if (tpacpi_leds[i].led_classdev.name) 4748 led_classdev_unregister(&tpacpi_leds[i].led_classdev); 4749 } 4750 4751 kfree(tpacpi_leds); 4752} 4753 4754static int __init led_init(struct ibm_init_struct *iibm) 4755{ 4756 unsigned int i; 4757 int rc; 4758 4759 vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n"); 4760 4761 TPACPI_ACPIHANDLE_INIT(led); 4762 4763 if (!led_handle) 4764 /* led not supported on R30, R31 */ 4765 led_supported = TPACPI_LED_NONE; 4766 else if (strlencmp(led_path, "SLED") == 0) 4767 /* 570 */ 4768 led_supported = TPACPI_LED_570; 4769 else if (strlencmp(led_path, "SYSL") == 0) 4770 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ 4771 led_supported = TPACPI_LED_OLD; 4772 else 4773 /* all others */ 4774 led_supported = TPACPI_LED_NEW; 4775 4776 vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n", 4777 str_supported(led_supported), led_supported); 4778 4779 tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS, 4780 GFP_KERNEL); 4781 if (!tpacpi_leds) { 4782 printk(TPACPI_ERR "Out of memory for LED data\n"); 4783 return -ENOMEM; 4784 } 4785 4786 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) { 4787 tpacpi_leds[i].led = i; 4788 4789 tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set; 4790 tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set; 4791 if (led_supported == TPACPI_LED_570) 4792 tpacpi_leds[i].led_classdev.brightness_get = 4793 &led_sysfs_get; 4794 4795 tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i]; 4796 4797 INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker); 4798 4799 rc = led_classdev_register(&tpacpi_pdev->dev, 4800 &tpacpi_leds[i].led_classdev); 4801 if (rc < 0) { 4802 tpacpi_leds[i].led_classdev.name = NULL; 4803 led_exit(); 4804 return rc; 4805 } 4806 } 4807 4808 return (led_supported != TPACPI_LED_NONE)? 0 : 1; 4809} 4810 4811#define str_led_status(s) \ 4812 ((s) == TPACPI_LED_OFF ? "off" : \ 4813 ((s) == TPACPI_LED_ON ? "on" : "blinking")) 4814 4815static int led_read(char *p) 4816{ 4817 int len = 0; 4818 4819 if (!led_supported) { 4820 len += sprintf(p + len, "status:\t\tnot supported\n"); 4821 return len; 4822 } 4823 len += sprintf(p + len, "status:\t\tsupported\n"); 4824 4825 if (led_supported == TPACPI_LED_570) { 4826 /* 570 */ 4827 int i, status; 4828 for (i = 0; i < 8; i++) { 4829 status = led_get_status(i); 4830 if (status < 0) 4831 return -EIO; 4832 len += sprintf(p + len, "%d:\t\t%s\n", 4833 i, str_led_status(status)); 4834 } 4835 } 4836 4837 len += sprintf(p + len, "commands:\t" 4838 "<led> on, <led> off, <led> blink (<led> is 0-7)\n"); 4839 4840 return len; 4841} 4842 4843static int led_write(char *buf) 4844{ 4845 char *cmd; 4846 int led, rc; 4847 enum led_status_t s; 4848 4849 if (!led_supported) 4850 return -ENODEV; 4851 4852 while ((cmd = next_cmd(&buf))) { 4853 if (sscanf(cmd, "%d", &led) != 1 || led < 0 || led > 7) 4854 return -EINVAL; 4855 4856 if (strstr(cmd, "off")) { 4857 s = TPACPI_LED_OFF; 4858 } else if (strstr(cmd, "on")) { 4859 s = TPACPI_LED_ON; 4860 } else if (strstr(cmd, "blink")) { 4861 s = TPACPI_LED_BLINK; 4862 } else { 4863 return -EINVAL; 4864 } 4865 4866 rc = led_set_status(led, s); 4867 if (rc < 0) 4868 return rc; 4869 } 4870 4871 return 0; 4872} 4873 4874static struct ibm_struct led_driver_data = { 4875 .name = "led", 4876 .read = led_read, 4877 .write = led_write, 4878 .exit = led_exit, 4879}; 4880 4881/************************************************************************* 4882 * Beep subdriver 4883 */ 4884 4885TPACPI_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */ 4886 4887static int __init beep_init(struct ibm_init_struct *iibm) 4888{ 4889 vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n"); 4890 4891 TPACPI_ACPIHANDLE_INIT(beep); 4892 4893 vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n", 4894 str_supported(beep_handle != NULL)); 4895 4896 return (beep_handle)? 0 : 1; 4897} 4898 4899static int beep_read(char *p) 4900{ 4901 int len = 0; 4902 4903 if (!beep_handle) 4904 len += sprintf(p + len, "status:\t\tnot supported\n"); 4905 else { 4906 len += sprintf(p + len, "status:\t\tsupported\n"); 4907 len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-17)\n"); 4908 } 4909 4910 return len; 4911} 4912 4913static int beep_write(char *buf) 4914{ 4915 char *cmd; 4916 int beep_cmd; 4917 4918 if (!beep_handle) 4919 return -ENODEV; 4920 4921 while ((cmd = next_cmd(&buf))) { 4922 if (sscanf(cmd, "%u", &beep_cmd) == 1 && 4923 beep_cmd >= 0 && beep_cmd <= 17) { 4924 /* beep_cmd set */ 4925 } else 4926 return -EINVAL; 4927 if (!acpi_evalf(beep_handle, NULL, NULL, "vdd", beep_cmd, 0)) 4928 return -EIO; 4929 } 4930 4931 return 0; 4932} 4933 4934static struct ibm_struct beep_driver_data = { 4935 .name = "beep", 4936 .read = beep_read, 4937 .write = beep_write, 4938}; 4939 4940/************************************************************************* 4941 * Thermal subdriver 4942 */ 4943 4944enum thermal_access_mode { 4945 TPACPI_THERMAL_NONE = 0, /* No thermal support */ 4946 TPACPI_THERMAL_ACPI_TMP07, /* Use ACPI TMP0-7 */ 4947 TPACPI_THERMAL_ACPI_UPDT, /* Use ACPI TMP0-7 with UPDT */ 4948 TPACPI_THERMAL_TPEC_8, /* Use ACPI EC regs, 8 sensors */ 4949 TPACPI_THERMAL_TPEC_16, /* Use ACPI EC regs, 16 sensors */ 4950}; 4951 4952enum { /* TPACPI_THERMAL_TPEC_* */ 4953 TP_EC_THERMAL_TMP0 = 0x78, /* ACPI EC regs TMP 0..7 */ 4954 TP_EC_THERMAL_TMP8 = 0xC0, /* ACPI EC regs TMP 8..15 */ 4955 TP_EC_THERMAL_TMP_NA = -128, /* ACPI EC sensor not available */ 4956}; 4957 4958#define TPACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */ 4959struct ibm_thermal_sensors_struct { 4960 s32 temp[TPACPI_MAX_THERMAL_SENSORS]; 4961}; 4962 4963static enum thermal_access_mode thermal_read_mode; 4964 4965/* idx is zero-based */ 4966static int thermal_get_sensor(int idx, s32 *value) 4967{ 4968 int t; 4969 s8 tmp; 4970 char tmpi[5]; 4971 4972 t = TP_EC_THERMAL_TMP0; 4973 4974 switch (thermal_read_mode) { 4975#if TPACPI_MAX_THERMAL_SENSORS >= 16 4976 case TPACPI_THERMAL_TPEC_16: 4977 if (idx >= 8 && idx <= 15) { 4978 t = TP_EC_THERMAL_TMP8; 4979 idx -= 8; 4980 } 4981 /* fallthrough */ 4982#endif 4983 case TPACPI_THERMAL_TPEC_8: 4984 if (idx <= 7) { 4985 if (!acpi_ec_read(t + idx, &tmp)) 4986 return -EIO; 4987 *value = tmp * 1000; 4988 return 0; 4989 } 4990 break; 4991 4992 case TPACPI_THERMAL_ACPI_UPDT: 4993 if (idx <= 7) { 4994 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx); 4995 if (!acpi_evalf(ec_handle, NULL, "UPDT", "v")) 4996 return -EIO; 4997 if (!acpi_evalf(ec_handle, &t, tmpi, "d")) 4998 return -EIO; 4999 *value = (t - 2732) * 100; 5000 return 0; 5001 } 5002 break; 5003 5004 case TPACPI_THERMAL_ACPI_TMP07: 5005 if (idx <= 7) { 5006 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx); 5007 if (!acpi_evalf(ec_handle, &t, tmpi, "d")) 5008 return -EIO; 5009 if (t > 127 || t < -127) 5010 t = TP_EC_THERMAL_TMP_NA; 5011 *value = t * 1000; 5012 return 0; 5013 } 5014 break; 5015 5016 case TPACPI_THERMAL_NONE: 5017 default: 5018 return -ENOSYS; 5019 } 5020 5021 return -EINVAL; 5022} 5023 5024static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s) 5025{ 5026 int res, i; 5027 int n; 5028 5029 n = 8; 5030 i = 0; 5031 5032 if (!s) 5033 return -EINVAL; 5034 5035 if (thermal_read_mode == TPACPI_THERMAL_TPEC_16) 5036 n = 16; 5037 5038 for (i = 0 ; i < n; i++) { 5039 res = thermal_get_sensor(i, &s->temp[i]); 5040 if (res) 5041 return res; 5042 } 5043 5044 return n; 5045} 5046 5047/* sysfs temp##_input -------------------------------------------------- */ 5048 5049static ssize_t thermal_temp_input_show(struct device *dev, 5050 struct device_attribute *attr, 5051 char *buf) 5052{ 5053 struct sensor_device_attribute *sensor_attr = 5054 to_sensor_dev_attr(attr); 5055 int idx = sensor_attr->index; 5056 s32 value; 5057 int res; 5058 5059 res = thermal_get_sensor(idx, &value); 5060 if (res) 5061 return res; 5062 if (value == TP_EC_THERMAL_TMP_NA * 1000) 5063 return -ENXIO; 5064 5065 return snprintf(buf, PAGE_SIZE, "%d\n", value); 5066} 5067 5068#define THERMAL_SENSOR_ATTR_TEMP(_idxA, _idxB) \ 5069 SENSOR_ATTR(temp##_idxA##_input, S_IRUGO, \ 5070 thermal_temp_input_show, NULL, _idxB) 5071 5072static struct sensor_device_attribute sensor_dev_attr_thermal_temp_input[] = { 5073 THERMAL_SENSOR_ATTR_TEMP(1, 0), 5074 THERMAL_SENSOR_ATTR_TEMP(2, 1), 5075 THERMAL_SENSOR_ATTR_TEMP(3, 2), 5076 THERMAL_SENSOR_ATTR_TEMP(4, 3), 5077 THERMAL_SENSOR_ATTR_TEMP(5, 4), 5078 THERMAL_SENSOR_ATTR_TEMP(6, 5), 5079 THERMAL_SENSOR_ATTR_TEMP(7, 6), 5080 THERMAL_SENSOR_ATTR_TEMP(8, 7), 5081 THERMAL_SENSOR_ATTR_TEMP(9, 8), 5082 THERMAL_SENSOR_ATTR_TEMP(10, 9), 5083 THERMAL_SENSOR_ATTR_TEMP(11, 10), 5084 THERMAL_SENSOR_ATTR_TEMP(12, 11), 5085 THERMAL_SENSOR_ATTR_TEMP(13, 12), 5086 THERMAL_SENSOR_ATTR_TEMP(14, 13), 5087 THERMAL_SENSOR_ATTR_TEMP(15, 14), 5088 THERMAL_SENSOR_ATTR_TEMP(16, 15), 5089}; 5090 5091#define THERMAL_ATTRS(X) \ 5092 &sensor_dev_attr_thermal_temp_input[X].dev_attr.attr 5093 5094static struct attribute *thermal_temp_input_attr[] = { 5095 THERMAL_ATTRS(8), 5096 THERMAL_ATTRS(9), 5097 THERMAL_ATTRS(10), 5098 THERMAL_ATTRS(11), 5099 THERMAL_ATTRS(12), 5100 THERMAL_ATTRS(13), 5101 THERMAL_ATTRS(14), 5102 THERMAL_ATTRS(15), 5103 THERMAL_ATTRS(0), 5104 THERMAL_ATTRS(1), 5105 THERMAL_ATTRS(2), 5106 THERMAL_ATTRS(3), 5107 THERMAL_ATTRS(4), 5108 THERMAL_ATTRS(5), 5109 THERMAL_ATTRS(6), 5110 THERMAL_ATTRS(7), 5111 NULL 5112}; 5113 5114static const struct attribute_group thermal_temp_input16_group = { 5115 .attrs = thermal_temp_input_attr 5116}; 5117 5118static const struct attribute_group thermal_temp_input8_group = { 5119 .attrs = &thermal_temp_input_attr[8] 5120}; 5121 5122#undef THERMAL_SENSOR_ATTR_TEMP 5123#undef THERMAL_ATTRS 5124 5125/* --------------------------------------------------------------------- */ 5126 5127static int __init thermal_init(struct ibm_init_struct *iibm) 5128{ 5129 u8 t, ta1, ta2; 5130 int i; 5131 int acpi_tmp7; 5132 int res; 5133 5134 vdbg_printk(TPACPI_DBG_INIT, "initializing thermal subdriver\n"); 5135 5136 acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); 5137 5138 if (thinkpad_id.ec_model) { 5139 /* 5140 * Direct EC access mode: sensors at registers 5141 * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for 5142 * non-implemented, thermal sensors return 0x80 when 5143 * not available 5144 */ 5145 5146 ta1 = ta2 = 0; 5147 for (i = 0; i < 8; i++) { 5148 if (acpi_ec_read(TP_EC_THERMAL_TMP0 + i, &t)) { 5149 ta1 |= t; 5150 } else { 5151 ta1 = 0; 5152 break; 5153 } 5154 if (acpi_ec_read(TP_EC_THERMAL_TMP8 + i, &t)) { 5155 ta2 |= t; 5156 } else { 5157 ta1 = 0; 5158 break; 5159 } 5160 } 5161 if (ta1 == 0) { 5162 /* This is sheer paranoia, but we handle it anyway */ 5163 if (acpi_tmp7) { 5164 printk(TPACPI_ERR 5165 "ThinkPad ACPI EC access misbehaving, " 5166 "falling back to ACPI TMPx access " 5167 "mode\n"); 5168 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07; 5169 } else { 5170 printk(TPACPI_ERR 5171 "ThinkPad ACPI EC access misbehaving, " 5172 "disabling thermal sensors access\n"); 5173 thermal_read_mode = TPACPI_THERMAL_NONE; 5174 } 5175 } else { 5176 thermal_read_mode = 5177 (ta2 != 0) ? 5178 TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8; 5179 } 5180 } else if (acpi_tmp7) { 5181 if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) { 5182 /* 600e/x, 770e, 770x */ 5183 thermal_read_mode = TPACPI_THERMAL_ACPI_UPDT; 5184 } else { 5185 /* Standard ACPI TMPx access, max 8 sensors */ 5186 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07; 5187 } 5188 } else { 5189 /* temperatures not supported on 570, G4x, R30, R31, R32 */ 5190 thermal_read_mode = TPACPI_THERMAL_NONE; 5191 } 5192 5193 vdbg_printk(TPACPI_DBG_INIT, "thermal is %s, mode %d\n", 5194 str_supported(thermal_read_mode != TPACPI_THERMAL_NONE), 5195 thermal_read_mode); 5196 5197 switch (thermal_read_mode) { 5198 case TPACPI_THERMAL_TPEC_16: 5199 res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, 5200 &thermal_temp_input16_group); 5201 if (res) 5202 return res; 5203 break; 5204 case TPACPI_THERMAL_TPEC_8: 5205 case TPACPI_THERMAL_ACPI_TMP07: 5206 case TPACPI_THERMAL_ACPI_UPDT: 5207 res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, 5208 &thermal_temp_input8_group); 5209 if (res) 5210 return res; 5211 break; 5212 case TPACPI_THERMAL_NONE: 5213 default: 5214 return 1; 5215 } 5216 5217 return 0; 5218} 5219 5220static void thermal_exit(void) 5221{ 5222 switch (thermal_read_mode) { 5223 case TPACPI_THERMAL_TPEC_16: 5224 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, 5225 &thermal_temp_input16_group); 5226 break; 5227 case TPACPI_THERMAL_TPEC_8: 5228 case TPACPI_THERMAL_ACPI_TMP07: 5229 case TPACPI_THERMAL_ACPI_UPDT: 5230 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, 5231 &thermal_temp_input16_group); 5232 break; 5233 case TPACPI_THERMAL_NONE: 5234 default: 5235 break; 5236 } 5237} 5238 5239static int thermal_read(char *p) 5240{ 5241 int len = 0; 5242 int n, i; 5243 struct ibm_thermal_sensors_struct t; 5244 5245 n = thermal_get_sensors(&t); 5246 if (unlikely(n < 0)) 5247 return n; 5248 5249 len += sprintf(p + len, "temperatures:\t"); 5250 5251 if (n > 0) { 5252 for (i = 0; i < (n - 1); i++) 5253 len += sprintf(p + len, "%d ", t.temp[i] / 1000); 5254 len += sprintf(p + len, "%d\n", t.temp[i] / 1000); 5255 } else 5256 len += sprintf(p + len, "not supported\n"); 5257 5258 return len; 5259} 5260 5261static struct ibm_struct thermal_driver_data = { 5262 .name = "thermal", 5263 .read = thermal_read, 5264 .exit = thermal_exit, 5265}; 5266 5267/************************************************************************* 5268 * EC Dump subdriver 5269 */ 5270 5271static u8 ecdump_regs[256]; 5272 5273static int ecdump_read(char *p) 5274{ 5275 int len = 0; 5276 int i, j; 5277 u8 v; 5278 5279 len += sprintf(p + len, "EC " 5280 " +00 +01 +02 +03 +04 +05 +06 +07" 5281 " +08 +09 +0a +0b +0c +0d +0e +0f\n"); 5282 for (i = 0; i < 256; i += 16) { 5283 len += sprintf(p + len, "EC 0x%02x:", i); 5284 for (j = 0; j < 16; j++) { 5285 if (!acpi_ec_read(i + j, &v)) 5286 break; 5287 if (v != ecdump_regs[i + j]) 5288 len += sprintf(p + len, " *%02x", v); 5289 else 5290 len += sprintf(p + len, " %02x", v); 5291 ecdump_regs[i + j] = v; 5292 } 5293 len += sprintf(p + len, "\n"); 5294 if (j != 16) 5295 break; 5296 } 5297 5298 /* These are way too dangerous to advertise openly... */ 5299#if 0 5300 len += sprintf(p + len, "commands:\t0x<offset> 0x<value>" 5301 " (<offset> is 00-ff, <value> is 00-ff)\n"); 5302 len += sprintf(p + len, "commands:\t0x<offset> <value> " 5303 " (<offset> is 00-ff, <value> is 0-255)\n"); 5304#endif 5305 return len; 5306} 5307 5308static int ecdump_write(char *buf) 5309{ 5310 char *cmd; 5311 int i, v; 5312 5313 while ((cmd = next_cmd(&buf))) { 5314 if (sscanf(cmd, "0x%x 0x%x", &i, &v) == 2) { 5315 /* i and v set */ 5316 } else if (sscanf(cmd, "0x%x %u", &i, &v) == 2) { 5317 /* i and v set */ 5318 } else 5319 return -EINVAL; 5320 if (i >= 0 && i < 256 && v >= 0 && v < 256) { 5321 if (!acpi_ec_write(i, v)) 5322 return -EIO; 5323 } else 5324 return -EINVAL; 5325 } 5326 5327 return 0; 5328} 5329 5330static struct ibm_struct ecdump_driver_data = { 5331 .name = "ecdump", 5332 .read = ecdump_read, 5333 .write = ecdump_write, 5334 .flags.experimental = 1, 5335}; 5336 5337/************************************************************************* 5338 * Backlight/brightness subdriver 5339 */ 5340 5341#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen" 5342 5343enum { 5344 TP_EC_BACKLIGHT = 0x31, 5345 5346 /* TP_EC_BACKLIGHT bitmasks */ 5347 TP_EC_BACKLIGHT_LVLMSK = 0x1F, 5348 TP_EC_BACKLIGHT_CMDMSK = 0xE0, 5349 TP_EC_BACKLIGHT_MAPSW = 0x20, 5350}; 5351 5352static struct backlight_device *ibm_backlight_device; 5353static int brightness_mode; 5354static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */ 5355 5356static struct mutex brightness_mutex; 5357 5358/* 5359 * ThinkPads can read brightness from two places: EC 0x31, or 5360 * CMOS NVRAM byte 0x5E, bits 0-3. 5361 * 5362 * EC 0x31 has the following layout 5363 * Bit 7: unknown function 5364 * Bit 6: unknown function 5365 * Bit 5: Z: honour scale changes, NZ: ignore scale changes 5366 * Bit 4: must be set to zero to avoid problems 5367 * Bit 3-0: backlight brightness level 5368 * 5369 * brightness_get_raw returns status data in the EC 0x31 layout 5370 */ 5371static int brightness_get_raw(int *status) 5372{ 5373 u8 lec = 0, lcmos = 0, level = 0; 5374 5375 if (brightness_mode & 1) { 5376 if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec)) 5377 return -EIO; 5378 level = lec & TP_EC_BACKLIGHT_LVLMSK; 5379 }; 5380 if (brightness_mode & 2) { 5381 lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) 5382 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) 5383 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; 5384 lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07; 5385 level = lcmos; 5386 } 5387 5388 if (brightness_mode == 3) { 5389 *status = lec; /* Prefer EC, CMOS is just a backing store */ 5390 lec &= TP_EC_BACKLIGHT_LVLMSK; 5391 if (lec == lcmos) 5392 tp_warned.bright_cmos_ec_unsync = 0; 5393 else { 5394 if (!tp_warned.bright_cmos_ec_unsync) { 5395 printk(TPACPI_ERR 5396 "CMOS NVRAM (%u) and EC (%u) do not " 5397 "agree on display brightness level\n", 5398 (unsigned int) lcmos, 5399 (unsigned int) lec); 5400 tp_warned.bright_cmos_ec_unsync = 1; 5401 } 5402 return -EIO; 5403 } 5404 } else { 5405 *status = level; 5406 } 5407 5408 return 0; 5409} 5410 5411/* May return EINTR which can always be mapped to ERESTARTSYS */ 5412static int brightness_set(int value) 5413{ 5414 int cmos_cmd, inc, i, res; 5415 int current_value; 5416 int command_bits; 5417 5418 if (value > ((tp_features.bright_16levels)? 15 : 7) || 5419 value < 0) 5420 return -EINVAL; 5421 5422 res = mutex_lock_killable(&brightness_mutex); 5423 if (res < 0) 5424 return res; 5425 5426 res = brightness_get_raw(¤t_value); 5427 if (res < 0) 5428 goto errout; 5429 5430 command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK; 5431 current_value &= TP_EC_BACKLIGHT_LVLMSK; 5432 5433 cmos_cmd = value > current_value ? 5434 TP_CMOS_BRIGHTNESS_UP : 5435 TP_CMOS_BRIGHTNESS_DOWN; 5436 inc = (value > current_value)? 1 : -1; 5437 5438 res = 0; 5439 for (i = current_value; i != value; i += inc) { 5440 if ((brightness_mode & 2) && 5441 issue_thinkpad_cmos_command(cmos_cmd)) { 5442 res = -EIO; 5443 goto errout; 5444 } 5445 if ((brightness_mode & 1) && 5446 !acpi_ec_write(TP_EC_BACKLIGHT, 5447 (i + inc) | command_bits)) { 5448 res = -EIO; 5449 goto errout;; 5450 } 5451 } 5452 5453errout: 5454 mutex_unlock(&brightness_mutex); 5455 return res; 5456} 5457 5458/* sysfs backlight class ----------------------------------------------- */ 5459 5460static int brightness_update_status(struct backlight_device *bd) 5461{ 5462 /* it is the backlight class's job (caller) to handle 5463 * EINTR and other errors properly */ 5464 return brightness_set( 5465 (bd->props.fb_blank == FB_BLANK_UNBLANK && 5466 bd->props.power == FB_BLANK_UNBLANK) ? 5467 bd->props.brightness : 0); 5468} 5469 5470static int brightness_get(struct backlight_device *bd) 5471{ 5472 int status, res; 5473 5474 res = brightness_get_raw(&status); 5475 if (res < 0) 5476 return 0; /* FIXME: teach backlight about error handling */ 5477 5478 return status & TP_EC_BACKLIGHT_LVLMSK; 5479} 5480 5481static struct backlight_ops ibm_backlight_data = { 5482 .get_brightness = brightness_get, 5483 .update_status = brightness_update_status, 5484}; 5485 5486/* --------------------------------------------------------------------- */ 5487 5488static int __init brightness_init(struct ibm_init_struct *iibm) 5489{ 5490 int b; 5491 5492 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n"); 5493 5494 mutex_init(&brightness_mutex); 5495 5496 /* 5497 * We always attempt to detect acpi support, so as to switch 5498 * Lenovo Vista BIOS to ACPI brightness mode even if we are not 5499 * going to publish a backlight interface 5500 */ 5501 b = tpacpi_check_std_acpi_brightness_support(); 5502 if (b > 0) { 5503 5504 if (acpi_video_backlight_support()) { 5505 if (brightness_enable > 1) { 5506 printk(TPACPI_NOTICE 5507 "Standard ACPI backlight interface " 5508 "available, not loading native one.\n"); 5509 return 1; 5510 } else if (brightness_enable == 1) { 5511 printk(TPACPI_NOTICE 5512 "Backlight control force enabled, even if standard " 5513 "ACPI backlight interface is available\n"); 5514 } 5515 } else { 5516 if (brightness_enable > 1) { 5517 printk(TPACPI_NOTICE 5518 "Standard ACPI backlight interface not " 5519 "available, thinkpad_acpi native " 5520 "brightness control enabled\n"); 5521 } 5522 } 5523 } 5524 5525 if (!brightness_enable) { 5526 dbg_printk(TPACPI_DBG_INIT, 5527 "brightness support disabled by " 5528 "module parameter\n"); 5529 return 1; 5530 } 5531 5532 if (b > 16) { 5533 printk(TPACPI_ERR 5534 "Unsupported brightness interface, " 5535 "please contact %s\n", TPACPI_MAIL); 5536 return 1; 5537 } 5538 if (b == 16) 5539 tp_features.bright_16levels = 1; 5540 5541 if (!brightness_mode) { 5542 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) 5543 brightness_mode = 2; 5544 else 5545 brightness_mode = 3; 5546 5547 dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n", 5548 brightness_mode); 5549 } 5550 5551 if (brightness_mode > 3) 5552 return -EINVAL; 5553 5554 if (brightness_get_raw(&b) < 0) 5555 return 1; 5556 5557 if (tp_features.bright_16levels) 5558 printk(TPACPI_INFO 5559 "detected a 16-level brightness capable ThinkPad\n"); 5560 5561 ibm_backlight_device = backlight_device_register( 5562 TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, 5563 &ibm_backlight_data); 5564 if (IS_ERR(ibm_backlight_device)) { 5565 printk(TPACPI_ERR "Could not register backlight device\n"); 5566 return PTR_ERR(ibm_backlight_device); 5567 } 5568 vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n"); 5569 5570 ibm_backlight_device->props.max_brightness = 5571 (tp_features.bright_16levels)? 15 : 7; 5572 ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; 5573 backlight_update_status(ibm_backlight_device); 5574 5575 return 0; 5576} 5577 5578static void brightness_exit(void) 5579{ 5580 if (ibm_backlight_device) { 5581 vdbg_printk(TPACPI_DBG_EXIT, 5582 "calling backlight_device_unregister()\n"); 5583 backlight_device_unregister(ibm_backlight_device); 5584 } 5585} 5586 5587static int brightness_read(char *p) 5588{ 5589 int len = 0; 5590 int level; 5591 5592 level = brightness_get(NULL); 5593 if (level < 0) { 5594 len += sprintf(p + len, "level:\t\tunreadable\n"); 5595 } else { 5596 len += sprintf(p + len, "level:\t\t%d\n", level); 5597 len += sprintf(p + len, "commands:\tup, down\n"); 5598 len += sprintf(p + len, "commands:\tlevel <level>" 5599 " (<level> is 0-%d)\n", 5600 (tp_features.bright_16levels) ? 15 : 7); 5601 } 5602 5603 return len; 5604} 5605 5606static int brightness_write(char *buf) 5607{ 5608 int level; 5609 int rc; 5610 char *cmd; 5611 int max_level = (tp_features.bright_16levels) ? 15 : 7; 5612 5613 level = brightness_get(NULL); 5614 if (level < 0) 5615 return level; 5616 5617 while ((cmd = next_cmd(&buf))) { 5618 if (strlencmp(cmd, "up") == 0) { 5619 if (level < max_level) 5620 level++; 5621 } else if (strlencmp(cmd, "down") == 0) { 5622 if (level > 0) 5623 level--; 5624 } else if (sscanf(cmd, "level %d", &level) == 1 && 5625 level >= 0 && level <= max_level) { 5626 /* new level set */ 5627 } else 5628 return -EINVAL; 5629 } 5630 5631 /* 5632 * Now we know what the final level should be, so we try to set it. 5633 * Doing it this way makes the syscall restartable in case of EINTR 5634 */ 5635 rc = brightness_set(level); 5636 return (rc == -EINTR)? ERESTARTSYS : rc; 5637} 5638 5639static struct ibm_struct brightness_driver_data = { 5640 .name = "brightness", 5641 .read = brightness_read, 5642 .write = brightness_write, 5643 .exit = brightness_exit, 5644}; 5645 5646/************************************************************************* 5647 * Volume subdriver 5648 */ 5649 5650static int volume_offset = 0x30; 5651 5652static int volume_read(char *p) 5653{ 5654 int len = 0; 5655 u8 level; 5656 5657 if (!acpi_ec_read(volume_offset, &level)) { 5658 len += sprintf(p + len, "level:\t\tunreadable\n"); 5659 } else { 5660 len += sprintf(p + len, "level:\t\t%d\n", level & 0xf); 5661 len += sprintf(p + len, "mute:\t\t%s\n", onoff(level, 6)); 5662 len += sprintf(p + len, "commands:\tup, down, mute\n"); 5663 len += sprintf(p + len, "commands:\tlevel <level>" 5664 " (<level> is 0-15)\n"); 5665 } 5666 5667 return len; 5668} 5669 5670static int volume_write(char *buf) 5671{ 5672 int cmos_cmd, inc, i; 5673 u8 level, mute; 5674 int new_level, new_mute; 5675 char *cmd; 5676 5677 while ((cmd = next_cmd(&buf))) { 5678 if (!acpi_ec_read(volume_offset, &level)) 5679 return -EIO; 5680 new_mute = mute = level & 0x40; 5681 new_level = level = level & 0xf; 5682 5683 if (strlencmp(cmd, "up") == 0) { 5684 if (mute) 5685 new_mute = 0; 5686 else 5687 new_level = level == 15 ? 15 : level + 1; 5688 } else if (strlencmp(cmd, "down") == 0) { 5689 if (mute) 5690 new_mute = 0; 5691 else 5692 new_level = level == 0 ? 0 : level - 1; 5693 } else if (sscanf(cmd, "level %d", &new_level) == 1 && 5694 new_level >= 0 && new_level <= 15) { 5695 /* new_level set */ 5696 } else if (strlencmp(cmd, "mute") == 0) { 5697 new_mute = 0x40; 5698 } else 5699 return -EINVAL; 5700 5701 if (new_level != level) { 5702 /* mute doesn't change */ 5703 5704 cmos_cmd = (new_level > level) ? 5705 TP_CMOS_VOLUME_UP : TP_CMOS_VOLUME_DOWN; 5706 inc = new_level > level ? 1 : -1; 5707 5708 if (mute && (issue_thinkpad_cmos_command(cmos_cmd) || 5709 !acpi_ec_write(volume_offset, level))) 5710 return -EIO; 5711 5712 for (i = level; i != new_level; i += inc) 5713 if (issue_thinkpad_cmos_command(cmos_cmd) || 5714 !acpi_ec_write(volume_offset, i + inc)) 5715 return -EIO; 5716 5717 if (mute && 5718 (issue_thinkpad_cmos_command(TP_CMOS_VOLUME_MUTE) || 5719 !acpi_ec_write(volume_offset, new_level + mute))) { 5720 return -EIO; 5721 } 5722 } 5723 5724 if (new_mute != mute) { 5725 /* level doesn't change */ 5726 5727 cmos_cmd = (new_mute) ? 5728 TP_CMOS_VOLUME_MUTE : TP_CMOS_VOLUME_UP; 5729 5730 if (issue_thinkpad_cmos_command(cmos_cmd) || 5731 !acpi_ec_write(volume_offset, level + new_mute)) 5732 return -EIO; 5733 } 5734 } 5735 5736 return 0; 5737} 5738 5739static struct ibm_struct volume_driver_data = { 5740 .name = "volume", 5741 .read = volume_read, 5742 .write = volume_write, 5743}; 5744 5745/************************************************************************* 5746 * Fan subdriver 5747 */ 5748 5749/* 5750 * FAN ACCESS MODES 5751 * 5752 * TPACPI_FAN_RD_ACPI_GFAN: 5753 * ACPI GFAN method: returns fan level 5754 * 5755 * see TPACPI_FAN_WR_ACPI_SFAN 5756 * EC 0x2f (HFSP) not available if GFAN exists 5757 * 5758 * TPACPI_FAN_WR_ACPI_SFAN: 5759 * ACPI SFAN method: sets fan level, 0 (stop) to 7 (max) 5760 * 5761 * EC 0x2f (HFSP) might be available *for reading*, but do not use 5762 * it for writing. 5763 * 5764 * TPACPI_FAN_WR_TPEC: 5765 * ThinkPad EC register 0x2f (HFSP): fan control loop mode 5766 * Supported on almost all ThinkPads 5767 * 5768 * Fan speed changes of any sort (including those caused by the 5769 * disengaged mode) are usually done slowly by the firmware as the 5770 * maximum ammount of fan duty cycle change per second seems to be 5771 * limited. 5772 * 5773 * Reading is not available if GFAN exists. 5774 * Writing is not available if SFAN exists. 5775 * 5776 * Bits 5777 * 7 automatic mode engaged; 5778 * (default operation mode of the ThinkPad) 5779 * fan level is ignored in this mode. 5780 * 6 full speed mode (takes precedence over bit 7); 5781 * not available on all thinkpads. May disable 5782 * the tachometer while the fan controller ramps up 5783 * the speed (which can take up to a few *minutes*). 5784 * Speeds up fan to 100% duty-cycle, which is far above 5785 * the standard RPM levels. It is not impossible that 5786 * it could cause hardware damage. 5787 * 5-3 unused in some models. Extra bits for fan level 5788 * in others, but still useless as all values above 5789 * 7 map to the same speed as level 7 in these models. 5790 * 2-0 fan level (0..7 usually) 5791 * 0x00 = stop 5792 * 0x07 = max (set when temperatures critical) 5793 * Some ThinkPads may have other levels, see 5794 * TPACPI_FAN_WR_ACPI_FANS (X31/X40/X41) 5795 * 5796 * FIRMWARE BUG: on some models, EC 0x2f might not be initialized at 5797 * boot. Apparently the EC does not intialize it, so unless ACPI DSDT 5798 * does so, its initial value is meaningless (0x07). 5799 * 5800 * For firmware bugs, refer to: 5801 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues 5802 * 5803 * ---- 5804 * 5805 * ThinkPad EC register 0x84 (LSB), 0x85 (MSB): 5806 * Main fan tachometer reading (in RPM) 5807 * 5808 * This register is present on all ThinkPads with a new-style EC, and 5809 * it is known not to be present on the A21m/e, and T22, as there is 5810 * something else in offset 0x84 according to the ACPI DSDT. Other 5811 * ThinkPads from this same time period (and earlier) probably lack the 5812 * tachometer as well. 5813 * 5814 * Unfortunately a lot of ThinkPads with new-style ECs but whose firmware 5815 * was never fixed by IBM to report the EC firmware version string 5816 * probably support the tachometer (like the early X models), so 5817 * detecting it is quite hard. We need more data to know for sure. 5818 * 5819 * FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings 5820 * might result. 5821 * 5822 * FIRMWARE BUG: may go stale while the EC is switching to full speed 5823 * mode. 5824 * 5825 * For firmware bugs, refer to: 5826 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues 5827 * 5828 * TPACPI_FAN_WR_ACPI_FANS: 5829 * ThinkPad X31, X40, X41. Not available in the X60. 5830 * 5831 * FANS ACPI handle: takes three arguments: low speed, medium speed, 5832 * high speed. ACPI DSDT seems to map these three speeds to levels 5833 * as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH 5834 * (this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3") 5835 * 5836 * The speeds are stored on handles 5837 * (FANA:FAN9), (FANC:FANB), (FANE:FAND). 5838 * 5839 * There are three default speed sets, acessible as handles: 5840 * FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H 5841 * 5842 * ACPI DSDT switches which set is in use depending on various 5843 * factors. 5844 * 5845 * TPACPI_FAN_WR_TPEC is also available and should be used to 5846 * command the fan. The X31/X40/X41 seems to have 8 fan levels, 5847 * but the ACPI tables just mention level 7. 5848 */ 5849 5850enum { /* Fan control constants */ 5851 fan_status_offset = 0x2f, /* EC register 0x2f */ 5852 fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM) 5853 * 0x84 must be read before 0x85 */ 5854 5855 TP_EC_FAN_FULLSPEED = 0x40, /* EC fan mode: full speed */ 5856 TP_EC_FAN_AUTO = 0x80, /* EC fan mode: auto fan control */ 5857 5858 TPACPI_FAN_LAST_LEVEL = 0x100, /* Use cached last-seen fan level */ 5859}; 5860 5861enum fan_status_access_mode { 5862 TPACPI_FAN_NONE = 0, /* No fan status or control */ 5863 TPACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */ 5864 TPACPI_FAN_RD_TPEC, /* Use ACPI EC regs 0x2f, 0x84-0x85 */ 5865}; 5866 5867enum fan_control_access_mode { 5868 TPACPI_FAN_WR_NONE = 0, /* No fan control */ 5869 TPACPI_FAN_WR_ACPI_SFAN, /* Use ACPI SFAN */ 5870 TPACPI_FAN_WR_TPEC, /* Use ACPI EC reg 0x2f */ 5871 TPACPI_FAN_WR_ACPI_FANS, /* Use ACPI FANS and EC reg 0x2f */ 5872}; 5873 5874enum fan_control_commands { 5875 TPACPI_FAN_CMD_SPEED = 0x0001, /* speed command */ 5876 TPACPI_FAN_CMD_LEVEL = 0x0002, /* level command */ 5877 TPACPI_FAN_CMD_ENABLE = 0x0004, /* enable/disable cmd, 5878 * and also watchdog cmd */ 5879}; 5880 5881static int fan_control_allowed; 5882 5883static enum fan_status_access_mode fan_status_access_mode; 5884static enum fan_control_access_mode fan_control_access_mode; 5885static enum fan_control_commands fan_control_commands; 5886 5887static u8 fan_control_initial_status; 5888static u8 fan_control_desired_level; 5889static u8 fan_control_resume_level; 5890static int fan_watchdog_maxinterval; 5891 5892static struct mutex fan_mutex; 5893 5894static void fan_watchdog_fire(struct work_struct *ignored); 5895static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire); 5896 5897TPACPI_HANDLE(fans, ec, "FANS"); /* X31, X40, X41 */ 5898TPACPI_HANDLE(gfan, ec, "GFAN", /* 570 */ 5899 "\\FSPD", /* 600e/x, 770e, 770x */ 5900 ); /* all others */ 5901TPACPI_HANDLE(sfan, ec, "SFAN", /* 570 */ 5902 "JFNS", /* 770x-JL */ 5903 ); /* all others */ 5904 5905/* 5906 * Unitialized HFSP quirk: ACPI DSDT and EC fail to initialize the 5907 * HFSP register at boot, so it contains 0x07 but the Thinkpad could 5908 * be in auto mode (0x80). 5909 * 5910 * This is corrected by any write to HFSP either by the driver, or 5911 * by the firmware. 5912 * 5913 * We assume 0x07 really means auto mode while this quirk is active, 5914 * as this is far more likely than the ThinkPad being in level 7, 5915 * which is only used by the firmware during thermal emergencies. 5916 */ 5917 5918static void fan_quirk1_detect(void) 5919{ 5920 /* In some ThinkPads, neither the EC nor the ACPI 5921 * DSDT initialize the HFSP register, and it ends up 5922 * being initially set to 0x07 when it *could* be 5923 * either 0x07 or 0x80. 5924 * 5925 * Enable for TP-1Y (T43), TP-78 (R51e), 5926 * TP-76 (R52), TP-70 (T43, R52), which are known 5927 * to be buggy. */ 5928 if (fan_control_initial_status == 0x07) { 5929 switch (thinkpad_id.ec_model) { 5930 case 0x5931: /* TP-1Y */ 5931 case 0x3837: /* TP-78 */ 5932 case 0x3637: /* TP-76 */ 5933 case 0x3037: /* TP-70 */ 5934 printk(TPACPI_NOTICE 5935 "fan_init: initial fan status is unknown, " 5936 "assuming it is in auto mode\n"); 5937 tp_features.fan_ctrl_status_undef = 1; 5938 ;; 5939 } 5940 } 5941} 5942 5943static void fan_quirk1_handle(u8 *fan_status) 5944{ 5945 if (unlikely(tp_features.fan_ctrl_status_undef)) { 5946 if (*fan_status != fan_control_initial_status) { 5947 /* something changed the HFSP regisnter since 5948 * driver init time, so it is not undefined 5949 * anymore */ 5950 tp_features.fan_ctrl_status_undef = 0; 5951 } else { 5952 /* Return most likely status. In fact, it 5953 * might be the only possible status */ 5954 *fan_status = TP_EC_FAN_AUTO; 5955 } 5956 } 5957} 5958 5959/* 5960 * Call with fan_mutex held 5961 */ 5962static void fan_update_desired_level(u8 status) 5963{ 5964 if ((status & 5965 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) { 5966 if (status > 7) 5967 fan_control_desired_level = 7; 5968 else 5969 fan_control_desired_level = status; 5970 } 5971} 5972 5973static int fan_get_status(u8 *status) 5974{ 5975 u8 s; 5976 5977 /* TODO: 5978 * Add TPACPI_FAN_RD_ACPI_FANS ? */ 5979 5980 switch (fan_status_access_mode) { 5981 case TPACPI_FAN_RD_ACPI_GFAN: 5982 /* 570, 600e/x, 770e, 770x */ 5983 5984 if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d"))) 5985 return -EIO; 5986 5987 if (likely(status)) 5988 *status = s & 0x07; 5989 5990 break; 5991 5992 case TPACPI_FAN_RD_TPEC: 5993 /* all except 570, 600e/x, 770e, 770x */ 5994 if (unlikely(!acpi_ec_read(fan_status_offset, &s))) 5995 return -EIO; 5996 5997 if (likely(status)) { 5998 *status = s; 5999 fan_quirk1_handle(status); 6000 } 6001 6002 break; 6003 6004 default: 6005 return -ENXIO; 6006 } 6007 6008 return 0; 6009} 6010 6011static int fan_get_status_safe(u8 *status) 6012{ 6013 int rc; 6014 u8 s; 6015 6016 if (mutex_lock_killable(&fan_mutex)) 6017 return -ERESTARTSYS; 6018 rc = fan_get_status(&s); 6019 if (!rc) 6020 fan_update_desired_level(s); 6021 mutex_unlock(&fan_mutex); 6022 6023 if (status) 6024 *status = s; 6025 6026 return rc; 6027} 6028 6029static int fan_get_speed(unsigned int *speed) 6030{ 6031 u8 hi, lo; 6032 6033 switch (fan_status_access_mode) { 6034 case TPACPI_FAN_RD_TPEC: 6035 /* all except 570, 600e/x, 770e, 770x */ 6036 if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) || 6037 !acpi_ec_read(fan_rpm_offset + 1, &hi))) 6038 return -EIO; 6039 6040 if (likely(speed)) 6041 *speed = (hi << 8) | lo; 6042 6043 break; 6044 6045 default: 6046 return -ENXIO; 6047 } 6048 6049 return 0; 6050} 6051 6052static int fan_set_level(int level) 6053{ 6054 if (!fan_control_allowed) 6055 return -EPERM; 6056 6057 switch (fan_control_access_mode) { 6058 case TPACPI_FAN_WR_ACPI_SFAN: 6059 if (level >= 0 && level <= 7) { 6060 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level)) 6061 return -EIO; 6062 } else 6063 return -EINVAL; 6064 break; 6065 6066 case TPACPI_FAN_WR_ACPI_FANS: 6067 case TPACPI_FAN_WR_TPEC: 6068 if (!(level & TP_EC_FAN_AUTO) && 6069 !(level & TP_EC_FAN_FULLSPEED) && 6070 ((level < 0) || (level > 7))) 6071 return -EINVAL; 6072 6073 /* safety net should the EC not support AUTO 6074 * or FULLSPEED mode bits and just ignore them */ 6075 if (level & TP_EC_FAN_FULLSPEED) 6076 level |= 7; /* safety min speed 7 */ 6077 else if (level & TP_EC_FAN_AUTO) 6078 level |= 4; /* safety min speed 4 */ 6079 6080 if (!acpi_ec_write(fan_status_offset, level)) 6081 return -EIO; 6082 else 6083 tp_features.fan_ctrl_status_undef = 0; 6084 break; 6085 6086 default: 6087 return -ENXIO; 6088 } 6089 return 0; 6090} 6091 6092static int fan_set_level_safe(int level) 6093{ 6094 int rc; 6095 6096 if (!fan_control_allowed) 6097 return -EPERM; 6098 6099 if (mutex_lock_killable(&fan_mutex)) 6100 return -ERESTARTSYS; 6101 6102 if (level == TPACPI_FAN_LAST_LEVEL) 6103 level = fan_control_desired_level; 6104 6105 rc = fan_set_level(level); 6106 if (!rc) 6107 fan_update_desired_level(level); 6108 6109 mutex_unlock(&fan_mutex); 6110 return rc; 6111} 6112 6113static int fan_set_enable(void) 6114{ 6115 u8 s; 6116 int rc; 6117 6118 if (!fan_control_allowed) 6119 return -EPERM; 6120 6121 if (mutex_lock_killable(&fan_mutex)) 6122 return -ERESTARTSYS; 6123 6124 switch (fan_control_access_mode) { 6125 case TPACPI_FAN_WR_ACPI_FANS: 6126 case TPACPI_FAN_WR_TPEC: 6127 rc = fan_get_status(&s); 6128 if (rc < 0) 6129 break; 6130 6131 /* Don't go out of emergency fan mode */ 6132 if (s != 7) { 6133 s &= 0x07; 6134 s |= TP_EC_FAN_AUTO | 4; /* min fan speed 4 */ 6135 } 6136 6137 if (!acpi_ec_write(fan_status_offset, s)) 6138 rc = -EIO; 6139 else { 6140 tp_features.fan_ctrl_status_undef = 0; 6141 rc = 0; 6142 } 6143 break; 6144 6145 case TPACPI_FAN_WR_ACPI_SFAN: 6146 rc = fan_get_status(&s); 6147 if (rc < 0) 6148 break; 6149 6150 s &= 0x07; 6151 6152 /* Set fan to at least level 4 */ 6153 s |= 4; 6154 6155 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s)) 6156 rc = -EIO; 6157 else 6158 rc = 0; 6159 break; 6160 6161 default: 6162 rc = -ENXIO; 6163 } 6164 6165 mutex_unlock(&fan_mutex); 6166 return rc; 6167} 6168 6169static int fan_set_disable(void) 6170{ 6171 int rc; 6172 6173 if (!fan_control_allowed) 6174 return -EPERM; 6175 6176 if (mutex_lock_killable(&fan_mutex)) 6177 return -ERESTARTSYS; 6178 6179 rc = 0; 6180 switch (fan_control_access_mode) { 6181 case TPACPI_FAN_WR_ACPI_FANS: 6182 case TPACPI_FAN_WR_TPEC: 6183 if (!acpi_ec_write(fan_status_offset, 0x00)) 6184 rc = -EIO; 6185 else { 6186 fan_control_desired_level = 0; 6187 tp_features.fan_ctrl_status_undef = 0; 6188 } 6189 break; 6190 6191 case TPACPI_FAN_WR_ACPI_SFAN: 6192 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00)) 6193 rc = -EIO; 6194 else 6195 fan_control_desired_level = 0; 6196 break; 6197 6198 default: 6199 rc = -ENXIO; 6200 } 6201 6202 6203 mutex_unlock(&fan_mutex); 6204 return rc; 6205} 6206 6207static int fan_set_speed(int speed) 6208{ 6209 int rc; 6210 6211 if (!fan_control_allowed) 6212 return -EPERM; 6213 6214 if (mutex_lock_killable(&fan_mutex)) 6215 return -ERESTARTSYS; 6216 6217 rc = 0; 6218 switch (fan_control_access_mode) { 6219 case TPACPI_FAN_WR_ACPI_FANS: 6220 if (speed >= 0 && speed <= 65535) { 6221 if (!acpi_evalf(fans_handle, NULL, NULL, "vddd", 6222 speed, speed, speed)) 6223 rc = -EIO; 6224 } else 6225 rc = -EINVAL; 6226 break; 6227 6228 default: 6229 rc = -ENXIO; 6230 } 6231 6232 mutex_unlock(&fan_mutex); 6233 return rc; 6234} 6235 6236static void fan_watchdog_reset(void) 6237{ 6238 static int fan_watchdog_active; 6239 6240 if (fan_control_access_mode == TPACPI_FAN_WR_NONE) 6241 return; 6242 6243 if (fan_watchdog_active) 6244 cancel_delayed_work(&fan_watchdog_task); 6245 6246 if (fan_watchdog_maxinterval > 0 && 6247 tpacpi_lifecycle != TPACPI_LIFE_EXITING) { 6248 fan_watchdog_active = 1; 6249 if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task, 6250 msecs_to_jiffies(fan_watchdog_maxinterval 6251 * 1000))) { 6252 printk(TPACPI_ERR 6253 "failed to queue the fan watchdog, " 6254 "watchdog will not trigger\n"); 6255 } 6256 } else 6257 fan_watchdog_active = 0; 6258} 6259 6260static void fan_watchdog_fire(struct work_struct *ignored) 6261{ 6262 int rc; 6263 6264 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING) 6265 return; 6266 6267 printk(TPACPI_NOTICE "fan watchdog: enabling fan\n"); 6268 rc = fan_set_enable(); 6269 if (rc < 0) { 6270 printk(TPACPI_ERR "fan watchdog: error %d while enabling fan, " 6271 "will try again later...\n", -rc); 6272 /* reschedule for later */ 6273 fan_watchdog_reset(); 6274 } 6275} 6276 6277/* 6278 * SYSFS fan layout: hwmon compatible (device) 6279 * 6280 * pwm*_enable: 6281 * 0: "disengaged" mode 6282 * 1: manual mode 6283 * 2: native EC "auto" mode (recommended, hardware default) 6284 * 6285 * pwm*: set speed in manual mode, ignored otherwise. 6286 * 0 is level 0; 255 is level 7. Intermediate points done with linear 6287 * interpolation. 6288 * 6289 * fan*_input: tachometer reading, RPM 6290 * 6291 * 6292 * SYSFS fan layout: extensions 6293 * 6294 * fan_watchdog (driver): 6295 * fan watchdog interval in seconds, 0 disables (default), max 120 6296 */ 6297 6298/* sysfs fan pwm1_enable ----------------------------------------------- */ 6299static ssize_t fan_pwm1_enable_show(struct device *dev, 6300 struct device_attribute *attr, 6301 char *buf) 6302{ 6303 int res, mode; 6304 u8 status; 6305 6306 res = fan_get_status_safe(&status); 6307 if (res) 6308 return res; 6309 6310 if (status & TP_EC_FAN_FULLSPEED) { 6311 mode = 0; 6312 } else if (status & TP_EC_FAN_AUTO) { 6313 mode = 2; 6314 } else 6315 mode = 1; 6316 6317 return snprintf(buf, PAGE_SIZE, "%d\n", mode); 6318} 6319 6320static ssize_t fan_pwm1_enable_store(struct device *dev, 6321 struct device_attribute *attr, 6322 const char *buf, size_t count) 6323{ 6324 unsigned long t; 6325 int res, level; 6326 6327 if (parse_strtoul(buf, 2, &t)) 6328 return -EINVAL; 6329 6330 switch (t) { 6331 case 0: 6332 level = TP_EC_FAN_FULLSPEED; 6333 break; 6334 case 1: 6335 level = TPACPI_FAN_LAST_LEVEL; 6336 break; 6337 case 2: 6338 level = TP_EC_FAN_AUTO; 6339 break; 6340 case 3: 6341 /* reserved for software-controlled auto mode */ 6342 return -ENOSYS; 6343 default: 6344 return -EINVAL; 6345 } 6346 6347 res = fan_set_level_safe(level); 6348 if (res == -ENXIO) 6349 return -EINVAL; 6350 else if (res < 0) 6351 return res; 6352 6353 fan_watchdog_reset(); 6354 6355 return count; 6356} 6357 6358static struct device_attribute dev_attr_fan_pwm1_enable = 6359 __ATTR(pwm1_enable, S_IWUSR | S_IRUGO, 6360 fan_pwm1_enable_show, fan_pwm1_enable_store); 6361 6362/* sysfs fan pwm1 ------------------------------------------------------ */ 6363static ssize_t fan_pwm1_show(struct device *dev, 6364 struct device_attribute *attr, 6365 char *buf) 6366{ 6367 int res; 6368 u8 status; 6369 6370 res = fan_get_status_safe(&status); 6371 if (res) 6372 return res; 6373 6374 if ((status & 6375 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0) 6376 status = fan_control_desired_level; 6377 6378 if (status > 7) 6379 status = 7; 6380 6381 return snprintf(buf, PAGE_SIZE, "%u\n", (status * 255) / 7); 6382} 6383 6384static ssize_t fan_pwm1_store(struct device *dev, 6385 struct device_attribute *attr, 6386 const char *buf, size_t count) 6387{ 6388 unsigned long s; 6389 int rc; 6390 u8 status, newlevel; 6391 6392 if (parse_strtoul(buf, 255, &s)) 6393 return -EINVAL; 6394 6395 /* scale down from 0-255 to 0-7 */ 6396 newlevel = (s >> 5) & 0x07; 6397 6398 if (mutex_lock_killable(&fan_mutex)) 6399 return -ERESTARTSYS; 6400 6401 rc = fan_get_status(&status); 6402 if (!rc && (status & 6403 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) { 6404 rc = fan_set_level(newlevel); 6405 if (rc == -ENXIO) 6406 rc = -EINVAL; 6407 else if (!rc) { 6408 fan_update_desired_level(newlevel); 6409 fan_watchdog_reset(); 6410 } 6411 } 6412 6413 mutex_unlock(&fan_mutex); 6414 return (rc)? rc : count; 6415} 6416 6417static struct device_attribute dev_attr_fan_pwm1 = 6418 __ATTR(pwm1, S_IWUSR | S_IRUGO, 6419 fan_pwm1_show, fan_pwm1_store); 6420 6421/* sysfs fan fan1_input ------------------------------------------------ */ 6422static ssize_t fan_fan1_input_show(struct device *dev, 6423 struct device_attribute *attr, 6424 char *buf) 6425{ 6426 int res; 6427 unsigned int speed; 6428 6429 res = fan_get_speed(&speed); 6430 if (res < 0) 6431 return res; 6432 6433 return snprintf(buf, PAGE_SIZE, "%u\n", speed); 6434} 6435 6436static struct device_attribute dev_attr_fan_fan1_input = 6437 __ATTR(fan1_input, S_IRUGO, 6438 fan_fan1_input_show, NULL); 6439 6440/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */ 6441static ssize_t fan_fan_watchdog_show(struct device_driver *drv, 6442 char *buf) 6443{ 6444 return snprintf(buf, PAGE_SIZE, "%u\n", fan_watchdog_maxinterval); 6445} 6446 6447static ssize_t fan_fan_watchdog_store(struct device_driver *drv, 6448 const char *buf, size_t count) 6449{ 6450 unsigned long t; 6451 6452 if (parse_strtoul(buf, 120, &t)) 6453 return -EINVAL; 6454 6455 if (!fan_control_allowed) 6456 return -EPERM; 6457 6458 fan_watchdog_maxinterval = t; 6459 fan_watchdog_reset(); 6460 6461 return count; 6462} 6463 6464static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO, 6465 fan_fan_watchdog_show, fan_fan_watchdog_store); 6466 6467/* --------------------------------------------------------------------- */ 6468static struct attribute *fan_attributes[] = { 6469 &dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr, 6470 &dev_attr_fan_fan1_input.attr, 6471 NULL 6472}; 6473 6474static const struct attribute_group fan_attr_group = { 6475 .attrs = fan_attributes, 6476}; 6477 6478static int __init fan_init(struct ibm_init_struct *iibm) 6479{ 6480 int rc; 6481 6482 vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n"); 6483 6484 mutex_init(&fan_mutex); 6485 fan_status_access_mode = TPACPI_FAN_NONE; 6486 fan_control_access_mode = TPACPI_FAN_WR_NONE; 6487 fan_control_commands = 0; 6488 fan_watchdog_maxinterval = 0; 6489 tp_features.fan_ctrl_status_undef = 0; 6490 fan_control_desired_level = 7; 6491 6492 TPACPI_ACPIHANDLE_INIT(fans); 6493 TPACPI_ACPIHANDLE_INIT(gfan); 6494 TPACPI_ACPIHANDLE_INIT(sfan); 6495 6496 if (gfan_handle) { 6497 /* 570, 600e/x, 770e, 770x */ 6498 fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN; 6499 } else { 6500 /* all other ThinkPads: note that even old-style 6501 * ThinkPad ECs supports the fan control register */ 6502 if (likely(acpi_ec_read(fan_status_offset, 6503 &fan_control_initial_status))) { 6504 fan_status_access_mode = TPACPI_FAN_RD_TPEC; 6505 fan_quirk1_detect(); 6506 } else { 6507 printk(TPACPI_ERR 6508 "ThinkPad ACPI EC access misbehaving, " 6509 "fan status and control unavailable\n"); 6510 return 1; 6511 } 6512 } 6513 6514 if (sfan_handle) { 6515 /* 570, 770x-JL */ 6516 fan_control_access_mode = TPACPI_FAN_WR_ACPI_SFAN; 6517 fan_control_commands |= 6518 TPACPI_FAN_CMD_LEVEL | TPACPI_FAN_CMD_ENABLE; 6519 } else { 6520 if (!gfan_handle) { 6521 /* gfan without sfan means no fan control */ 6522 /* all other models implement TP EC 0x2f control */ 6523 6524 if (fans_handle) { 6525 /* X31, X40, X41 */ 6526 fan_control_access_mode = 6527 TPACPI_FAN_WR_ACPI_FANS; 6528 fan_control_commands |= 6529 TPACPI_FAN_CMD_SPEED | 6530 TPACPI_FAN_CMD_LEVEL | 6531 TPACPI_FAN_CMD_ENABLE; 6532 } else { 6533 fan_control_access_mode = TPACPI_FAN_WR_TPEC; 6534 fan_control_commands |= 6535 TPACPI_FAN_CMD_LEVEL | 6536 TPACPI_FAN_CMD_ENABLE; 6537 } 6538 } 6539 } 6540 6541 vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n", 6542 str_supported(fan_status_access_mode != TPACPI_FAN_NONE || 6543 fan_control_access_mode != TPACPI_FAN_WR_NONE), 6544 fan_status_access_mode, fan_control_access_mode); 6545 6546 /* fan control master switch */ 6547 if (!fan_control_allowed) { 6548 fan_control_access_mode = TPACPI_FAN_WR_NONE; 6549 fan_control_commands = 0; 6550 dbg_printk(TPACPI_DBG_INIT, 6551 "fan control features disabled by parameter\n"); 6552 } 6553 6554 /* update fan_control_desired_level */ 6555 if (fan_status_access_mode != TPACPI_FAN_NONE) 6556 fan_get_status_safe(NULL); 6557 6558 if (fan_status_access_mode != TPACPI_FAN_NONE || 6559 fan_control_access_mode != TPACPI_FAN_WR_NONE) { 6560 rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, 6561 &fan_attr_group); 6562 if (rc < 0) 6563 return rc; 6564 6565 rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, 6566 &driver_attr_fan_watchdog); 6567 if (rc < 0) { 6568 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, 6569 &fan_attr_group); 6570 return rc; 6571 } 6572 return 0; 6573 } else 6574 return 1; 6575} 6576 6577static void fan_exit(void) 6578{ 6579 vdbg_printk(TPACPI_DBG_EXIT, 6580 "cancelling any pending fan watchdog tasks\n"); 6581 6582 /* FIXME: can we really do this unconditionally? */ 6583 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group); 6584 driver_remove_file(&tpacpi_hwmon_pdriver.driver, 6585 &driver_attr_fan_watchdog); 6586 6587 cancel_delayed_work(&fan_watchdog_task); 6588 flush_workqueue(tpacpi_wq); 6589} 6590 6591static void fan_suspend(pm_message_t state) 6592{ 6593 int rc; 6594 6595 if (!fan_control_allowed) 6596 return; 6597 6598 /* Store fan status in cache */ 6599 fan_control_resume_level = 0; 6600 rc = fan_get_status_safe(&fan_control_resume_level); 6601 if (rc < 0) 6602 printk(TPACPI_NOTICE 6603 "failed to read fan level for later " 6604 "restore during resume: %d\n", rc); 6605 6606 /* if it is undefined, don't attempt to restore it. 6607 * KEEP THIS LAST */ 6608 if (tp_features.fan_ctrl_status_undef) 6609 fan_control_resume_level = 0; 6610} 6611 6612static void fan_resume(void) 6613{ 6614 u8 current_level = 7; 6615 bool do_set = false; 6616 int rc; 6617 6618 /* DSDT *always* updates status on resume */ 6619 tp_features.fan_ctrl_status_undef = 0; 6620 6621 if (!fan_control_allowed || 6622 !fan_control_resume_level || 6623 (fan_get_status_safe(¤t_level) < 0)) 6624 return; 6625 6626 switch (fan_control_access_mode) { 6627 case TPACPI_FAN_WR_ACPI_SFAN: 6628 /* never decrease fan level */ 6629 do_set = (fan_control_resume_level > current_level); 6630 break; 6631 case TPACPI_FAN_WR_ACPI_FANS: 6632 case TPACPI_FAN_WR_TPEC: 6633 /* never decrease fan level, scale is: 6634 * TP_EC_FAN_FULLSPEED > 7 >= TP_EC_FAN_AUTO 6635 * 6636 * We expect the firmware to set either 7 or AUTO, but we 6637 * handle FULLSPEED out of paranoia. 6638 * 6639 * So, we can safely only restore FULLSPEED or 7, anything 6640 * else could slow the fan. Restoring AUTO is useless, at 6641 * best that's exactly what the DSDT already set (it is the 6642 * slower it uses). 6643 * 6644 * Always keep in mind that the DSDT *will* have set the 6645 * fans to what the vendor supposes is the best level. We 6646 * muck with it only to speed the fan up. 6647 */ 6648 if (fan_control_resume_level != 7 && 6649 !(fan_control_resume_level & TP_EC_FAN_FULLSPEED)) 6650 return; 6651 else 6652 do_set = !(current_level & TP_EC_FAN_FULLSPEED) && 6653 (current_level != fan_control_resume_level); 6654 break; 6655 default: 6656 return; 6657 } 6658 if (do_set) { 6659 printk(TPACPI_NOTICE 6660 "restoring fan level to 0x%02x\n", 6661 fan_control_resume_level); 6662 rc = fan_set_level_safe(fan_control_resume_level); 6663 if (rc < 0) 6664 printk(TPACPI_NOTICE 6665 "failed to restore fan level: %d\n", rc); 6666 } 6667} 6668 6669static int fan_read(char *p) 6670{ 6671 int len = 0; 6672 int rc; 6673 u8 status; 6674 unsigned int speed = 0; 6675 6676 switch (fan_status_access_mode) { 6677 case TPACPI_FAN_RD_ACPI_GFAN: 6678 /* 570, 600e/x, 770e, 770x */ 6679 rc = fan_get_status_safe(&status); 6680 if (rc < 0) 6681 return rc; 6682 6683 len += sprintf(p + len, "status:\t\t%s\n" 6684 "level:\t\t%d\n", 6685 (status != 0) ? "enabled" : "disabled", status); 6686 break; 6687 6688 case TPACPI_FAN_RD_TPEC: 6689 /* all except 570, 600e/x, 770e, 770x */ 6690 rc = fan_get_status_safe(&status); 6691 if (rc < 0) 6692 return rc; 6693 6694 len += sprintf(p + len, "status:\t\t%s\n", 6695 (status != 0) ? "enabled" : "disabled"); 6696 6697 rc = fan_get_speed(&speed); 6698 if (rc < 0) 6699 return rc; 6700 6701 len += sprintf(p + len, "speed:\t\t%d\n", speed); 6702 6703 if (status & TP_EC_FAN_FULLSPEED) 6704 /* Disengaged mode takes precedence */ 6705 len += sprintf(p + len, "level:\t\tdisengaged\n"); 6706 else if (status & TP_EC_FAN_AUTO) 6707 len += sprintf(p + len, "level:\t\tauto\n"); 6708 else 6709 len += sprintf(p + len, "level:\t\t%d\n", status); 6710 break; 6711 6712 case TPACPI_FAN_NONE: 6713 default: 6714 len += sprintf(p + len, "status:\t\tnot supported\n"); 6715 } 6716 6717 if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) { 6718 len += sprintf(p + len, "commands:\tlevel <level>"); 6719 6720 switch (fan_control_access_mode) { 6721 case TPACPI_FAN_WR_ACPI_SFAN: 6722 len += sprintf(p + len, " (<level> is 0-7)\n"); 6723 break; 6724 6725 default: 6726 len += sprintf(p + len, " (<level> is 0-7, " 6727 "auto, disengaged, full-speed)\n"); 6728 break; 6729 } 6730 } 6731 6732 if (fan_control_commands & TPACPI_FAN_CMD_ENABLE) 6733 len += sprintf(p + len, "commands:\tenable, disable\n" 6734 "commands:\twatchdog <timeout> (<timeout> " 6735 "is 0 (off), 1-120 (seconds))\n"); 6736 6737 if (fan_control_commands & TPACPI_FAN_CMD_SPEED) 6738 len += sprintf(p + len, "commands:\tspeed <speed>" 6739 " (<speed> is 0-65535)\n"); 6740 6741 return len; 6742} 6743 6744static int fan_write_cmd_level(const char *cmd, int *rc) 6745{ 6746 int level; 6747 6748 if (strlencmp(cmd, "level auto") == 0) 6749 level = TP_EC_FAN_AUTO; 6750 else if ((strlencmp(cmd, "level disengaged") == 0) | 6751 (strlencmp(cmd, "level full-speed") == 0)) 6752 level = TP_EC_FAN_FULLSPEED; 6753 else if (sscanf(cmd, "level %d", &level) != 1) 6754 return 0; 6755 6756 *rc = fan_set_level_safe(level); 6757 if (*rc == -ENXIO) 6758 printk(TPACPI_ERR "level command accepted for unsupported " 6759 "access mode %d", fan_control_access_mode); 6760 6761 return 1; 6762} 6763 6764static int fan_write_cmd_enable(const char *cmd, int *rc) 6765{ 6766 if (strlencmp(cmd, "enable") != 0) 6767 return 0; 6768 6769 *rc = fan_set_enable(); 6770 if (*rc == -ENXIO) 6771 printk(TPACPI_ERR "enable command accepted for unsupported " 6772 "access mode %d", fan_control_access_mode); 6773 6774 return 1; 6775} 6776 6777static int fan_write_cmd_disable(const char *cmd, int *rc) 6778{ 6779 if (strlencmp(cmd, "disable") != 0) 6780 return 0; 6781 6782 *rc = fan_set_disable(); 6783 if (*rc == -ENXIO) 6784 printk(TPACPI_ERR "disable command accepted for unsupported " 6785 "access mode %d", fan_control_access_mode); 6786 6787 return 1; 6788} 6789 6790static int fan_write_cmd_speed(const char *cmd, int *rc) 6791{ 6792 int speed; 6793 6794 /* TODO: 6795 * Support speed <low> <medium> <high> ? */ 6796 6797 if (sscanf(cmd, "speed %d", &speed) != 1) 6798 return 0; 6799 6800 *rc = fan_set_speed(speed); 6801 if (*rc == -ENXIO) 6802 printk(TPACPI_ERR "speed command accepted for unsupported " 6803 "access mode %d", fan_control_access_mode); 6804 6805 return 1; 6806} 6807 6808static int fan_write_cmd_watchdog(const char *cmd, int *rc) 6809{ 6810 int interval; 6811 6812 if (sscanf(cmd, "watchdog %d", &interval) != 1) 6813 return 0; 6814 6815 if (interval < 0 || interval > 120) 6816 *rc = -EINVAL; 6817 else 6818 fan_watchdog_maxinterval = interval; 6819 6820 return 1; 6821} 6822 6823static int fan_write(char *buf) 6824{ 6825 char *cmd; 6826 int rc = 0; 6827 6828 while (!rc && (cmd = next_cmd(&buf))) { 6829 if (!((fan_control_commands & TPACPI_FAN_CMD_LEVEL) && 6830 fan_write_cmd_level(cmd, &rc)) && 6831 !((fan_control_commands & TPACPI_FAN_CMD_ENABLE) && 6832 (fan_write_cmd_enable(cmd, &rc) || 6833 fan_write_cmd_disable(cmd, &rc) || 6834 fan_write_cmd_watchdog(cmd, &rc))) && 6835 !((fan_control_commands & TPACPI_FAN_CMD_SPEED) && 6836 fan_write_cmd_speed(cmd, &rc)) 6837 ) 6838 rc = -EINVAL; 6839 else if (!rc) 6840 fan_watchdog_reset(); 6841 } 6842 6843 return rc; 6844} 6845 6846static struct ibm_struct fan_driver_data = { 6847 .name = "fan", 6848 .read = fan_read, 6849 .write = fan_write, 6850 .exit = fan_exit, 6851 .suspend = fan_suspend, 6852 .resume = fan_resume, 6853}; 6854 6855/**************************************************************************** 6856 **************************************************************************** 6857 * 6858 * Infrastructure 6859 * 6860 **************************************************************************** 6861 ****************************************************************************/ 6862 6863/* sysfs name ---------------------------------------------------------- */ 6864static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev, 6865 struct device_attribute *attr, 6866 char *buf) 6867{ 6868 return snprintf(buf, PAGE_SIZE, "%s\n", TPACPI_NAME); 6869} 6870 6871static struct device_attribute dev_attr_thinkpad_acpi_pdev_name = 6872 __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL); 6873 6874/* --------------------------------------------------------------------- */ 6875 6876/* /proc support */ 6877static struct proc_dir_entry *proc_dir; 6878 6879/* 6880 * Module and infrastructure proble, init and exit handling 6881 */ 6882 6883static int force_load; 6884 6885#ifdef CONFIG_THINKPAD_ACPI_DEBUG 6886static const char * __init str_supported(int is_supported) 6887{ 6888 static char text_unsupported[] __initdata = "not supported"; 6889 6890 return (is_supported)? &text_unsupported[4] : &text_unsupported[0]; 6891} 6892#endif /* CONFIG_THINKPAD_ACPI_DEBUG */ 6893 6894static void ibm_exit(struct ibm_struct *ibm) 6895{ 6896 dbg_printk(TPACPI_DBG_EXIT, "removing %s\n", ibm->name); 6897 6898 list_del_init(&ibm->all_drivers); 6899 6900 if (ibm->flags.acpi_notify_installed) { 6901 dbg_printk(TPACPI_DBG_EXIT, 6902 "%s: acpi_remove_notify_handler\n", ibm->name); 6903 BUG_ON(!ibm->acpi); 6904 acpi_remove_notify_handler(*ibm->acpi->handle, 6905 ibm->acpi->type, 6906 dispatch_acpi_notify); 6907 ibm->flags.acpi_notify_installed = 0; 6908 ibm->flags.acpi_notify_installed = 0; 6909 } 6910 6911 if (ibm->flags.proc_created) { 6912 dbg_printk(TPACPI_DBG_EXIT, 6913 "%s: remove_proc_entry\n", ibm->name); 6914 remove_proc_entry(ibm->name, proc_dir); 6915 ibm->flags.proc_created = 0; 6916 } 6917 6918 if (ibm->flags.acpi_driver_registered) { 6919 dbg_printk(TPACPI_DBG_EXIT, 6920 "%s: acpi_bus_unregister_driver\n", ibm->name); 6921 BUG_ON(!ibm->acpi); 6922 acpi_bus_unregister_driver(ibm->acpi->driver); 6923 kfree(ibm->acpi->driver); 6924 ibm->acpi->driver = NULL; 6925 ibm->flags.acpi_driver_registered = 0; 6926 } 6927 6928 if (ibm->flags.init_called && ibm->exit) { 6929 ibm->exit(); 6930 ibm->flags.init_called = 0; 6931 } 6932 6933 dbg_printk(TPACPI_DBG_INIT, "finished removing %s\n", ibm->name); 6934} 6935 6936static int __init ibm_init(struct ibm_init_struct *iibm) 6937{ 6938 int ret; 6939 struct ibm_struct *ibm = iibm->data; 6940 struct proc_dir_entry *entry; 6941 6942 BUG_ON(ibm == NULL); 6943 6944 INIT_LIST_HEAD(&ibm->all_drivers); 6945 6946 if (ibm->flags.experimental && !experimental) 6947 return 0; 6948 6949 dbg_printk(TPACPI_DBG_INIT, 6950 "probing for %s\n", ibm->name); 6951 6952 if (iibm->init) { 6953 ret = iibm->init(iibm); 6954 if (ret > 0) 6955 return 0; /* probe failed */ 6956 if (ret) 6957 return ret; 6958 6959 ibm->flags.init_called = 1; 6960 } 6961 6962 if (ibm->acpi) { 6963 if (ibm->acpi->hid) { 6964 ret = register_tpacpi_subdriver(ibm); 6965 if (ret) 6966 goto err_out; 6967 } 6968 6969 if (ibm->acpi->notify) { 6970 ret = setup_acpi_notify(ibm); 6971 if (ret == -ENODEV) { 6972 printk(TPACPI_NOTICE "disabling subdriver %s\n", 6973 ibm->name); 6974 ret = 0; 6975 goto err_out; 6976 } 6977 if (ret < 0) 6978 goto err_out; 6979 } 6980 } 6981 6982 dbg_printk(TPACPI_DBG_INIT, 6983 "%s installed\n", ibm->name); 6984 6985 if (ibm->read) { 6986 entry = create_proc_entry(ibm->name, 6987 S_IFREG | S_IRUGO | S_IWUSR, 6988 proc_dir); 6989 if (!entry) { 6990 printk(TPACPI_ERR "unable to create proc entry %s\n", 6991 ibm->name); 6992 ret = -ENODEV; 6993 goto err_out; 6994 } 6995 entry->owner = THIS_MODULE; 6996 entry->data = ibm; 6997 entry->read_proc = &dispatch_procfs_read; 6998 if (ibm->write) 6999 entry->write_proc = &dispatch_procfs_write; 7000 ibm->flags.proc_created = 1; 7001 } 7002 7003 list_add_tail(&ibm->all_drivers, &tpacpi_all_drivers); 7004 7005 return 0; 7006 7007err_out: 7008 dbg_printk(TPACPI_DBG_INIT, 7009 "%s: at error exit path with result %d\n", 7010 ibm->name, ret); 7011 7012 ibm_exit(ibm); 7013 return (ret < 0)? ret : 0; 7014} 7015 7016/* Probing */ 7017 7018/* returns 0 - probe ok, or < 0 - probe error. 7019 * Probe ok doesn't mean thinkpad found. 7020 * On error, kfree() cleanup on tp->* is not performed, caller must do it */ 7021static int __must_check __init get_thinkpad_model_data( 7022 struct thinkpad_id_data *tp) 7023{ 7024 const struct dmi_device *dev = NULL; 7025 char ec_fw_string[18]; 7026 char const *s; 7027 7028 if (!tp) 7029 return -EINVAL; 7030 7031 memset(tp, 0, sizeof(*tp)); 7032 7033 if (dmi_name_in_vendors("IBM")) 7034 tp->vendor = PCI_VENDOR_ID_IBM; 7035 else if (dmi_name_in_vendors("LENOVO")) 7036 tp->vendor = PCI_VENDOR_ID_LENOVO; 7037 else 7038 return 0; 7039 7040 s = dmi_get_system_info(DMI_BIOS_VERSION); 7041 tp->bios_version_str = kstrdup(s, GFP_KERNEL); 7042 if (s && !tp->bios_version_str) 7043 return -ENOMEM; 7044 if (!tp->bios_version_str) 7045 return 0; 7046 tp->bios_model = tp->bios_version_str[0] 7047 | (tp->bios_version_str[1] << 8); 7048 7049 /* 7050 * ThinkPad T23 or newer, A31 or newer, R50e or newer, 7051 * X32 or newer, all Z series; Some models must have an 7052 * up-to-date BIOS or they will not be detected. 7053 * 7054 * See http://thinkwiki.org/wiki/List_of_DMI_IDs 7055 */ 7056 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { 7057 if (sscanf(dev->name, 7058 "IBM ThinkPad Embedded Controller -[%17c", 7059 ec_fw_string) == 1) { 7060 ec_fw_string[sizeof(ec_fw_string) - 1] = 0; 7061 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0; 7062 7063 tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL); 7064 if (!tp->ec_version_str) 7065 return -ENOMEM; 7066 tp->ec_model = ec_fw_string[0] 7067 | (ec_fw_string[1] << 8); 7068 break; 7069 } 7070 } 7071 7072 s = dmi_get_system_info(DMI_PRODUCT_VERSION); 7073 if (s && !strnicmp(s, "ThinkPad", 8)) { 7074 tp->model_str = kstrdup(s, GFP_KERNEL); 7075 if (!tp->model_str) 7076 return -ENOMEM; 7077 } 7078 7079 s = dmi_get_system_info(DMI_PRODUCT_NAME); 7080 tp->nummodel_str = kstrdup(s, GFP_KERNEL); 7081 if (s && !tp->nummodel_str) 7082 return -ENOMEM; 7083 7084 return 0; 7085} 7086 7087static int __init probe_for_thinkpad(void) 7088{ 7089 int is_thinkpad; 7090 7091 if (acpi_disabled) 7092 return -ENODEV; 7093 7094 /* 7095 * Non-ancient models have better DMI tagging, but very old models 7096 * don't. 7097 */ 7098 is_thinkpad = (thinkpad_id.model_str != NULL); 7099 7100 /* ec is required because many other handles are relative to it */ 7101 TPACPI_ACPIHANDLE_INIT(ec); 7102 if (!ec_handle) { 7103 if (is_thinkpad) 7104 printk(TPACPI_ERR 7105 "Not yet supported ThinkPad detected!\n"); 7106 return -ENODEV; 7107 } 7108 7109 /* 7110 * Risks a regression on very old machines, but reduces potential 7111 * false positives a damn great deal 7112 */ 7113 if (!is_thinkpad) 7114 is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM); 7115 7116 if (!is_thinkpad && !force_load) 7117 return -ENODEV; 7118 7119 return 0; 7120} 7121 7122 7123/* Module init, exit, parameters */ 7124 7125static struct ibm_init_struct ibms_init[] __initdata = { 7126 { 7127 .init = thinkpad_acpi_driver_init, 7128 .data = &thinkpad_acpi_driver_data, 7129 }, 7130 { 7131 .init = hotkey_init, 7132 .data = &hotkey_driver_data, 7133 }, 7134 { 7135 .init = bluetooth_init, 7136 .data = &bluetooth_driver_data, 7137 }, 7138 { 7139 .init = wan_init, 7140 .data = &wan_driver_data, 7141 }, 7142 { 7143 .init = uwb_init, 7144 .data = &uwb_driver_data, 7145 }, 7146#ifdef CONFIG_THINKPAD_ACPI_VIDEO 7147 { 7148 .init = video_init, 7149 .data = &video_driver_data, 7150 }, 7151#endif 7152 { 7153 .init = light_init, 7154 .data = &light_driver_data, 7155 }, 7156#ifdef CONFIG_THINKPAD_ACPI_DOCK 7157 { 7158 .init = dock_init, 7159 .data = &dock_driver_data[0], 7160 }, 7161 { 7162 .init = dock_init2, 7163 .data = &dock_driver_data[1], 7164 }, 7165#endif 7166#ifdef CONFIG_THINKPAD_ACPI_BAY 7167 { 7168 .init = bay_init, 7169 .data = &bay_driver_data, 7170 }, 7171#endif 7172 { 7173 .init = cmos_init, 7174 .data = &cmos_driver_data, 7175 }, 7176 { 7177 .init = led_init, 7178 .data = &led_driver_data, 7179 }, 7180 { 7181 .init = beep_init, 7182 .data = &beep_driver_data, 7183 }, 7184 { 7185 .init = thermal_init, 7186 .data = &thermal_driver_data, 7187 }, 7188 { 7189 .data = &ecdump_driver_data, 7190 }, 7191 { 7192 .init = brightness_init, 7193 .data = &brightness_driver_data, 7194 }, 7195 { 7196 .data = &volume_driver_data, 7197 }, 7198 { 7199 .init = fan_init, 7200 .data = &fan_driver_data, 7201 }, 7202}; 7203 7204static int __init set_ibm_param(const char *val, struct kernel_param *kp) 7205{ 7206 unsigned int i; 7207 struct ibm_struct *ibm; 7208 7209 if (!kp || !kp->name || !val) 7210 return -EINVAL; 7211 7212 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { 7213 ibm = ibms_init[i].data; 7214 WARN_ON(ibm == NULL); 7215 7216 if (!ibm || !ibm->name) 7217 continue; 7218 7219 if (strcmp(ibm->name, kp->name) == 0 && ibm->write) { 7220 if (strlen(val) > sizeof(ibms_init[i].param) - 2) 7221 return -ENOSPC; 7222 strcpy(ibms_init[i].param, val); 7223 strcat(ibms_init[i].param, ","); 7224 return 0; 7225 } 7226 } 7227 7228 return -EINVAL; 7229} 7230 7231module_param(experimental, int, 0); 7232MODULE_PARM_DESC(experimental, 7233 "Enables experimental features when non-zero"); 7234 7235module_param_named(debug, dbg_level, uint, 0); 7236MODULE_PARM_DESC(debug, "Sets debug level bit-mask"); 7237 7238module_param(force_load, bool, 0); 7239MODULE_PARM_DESC(force_load, 7240 "Attempts to load the driver even on a " 7241 "mis-identified ThinkPad when true"); 7242 7243module_param_named(fan_control, fan_control_allowed, bool, 0); 7244MODULE_PARM_DESC(fan_control, 7245 "Enables setting fan parameters features when true"); 7246 7247module_param_named(brightness_mode, brightness_mode, int, 0); 7248MODULE_PARM_DESC(brightness_mode, 7249 "Selects brightness control strategy: " 7250 "0=auto, 1=EC, 2=CMOS, 3=both"); 7251 7252module_param(brightness_enable, uint, 0); 7253MODULE_PARM_DESC(brightness_enable, 7254 "Enables backlight control when 1, disables when 0"); 7255 7256module_param(hotkey_report_mode, uint, 0); 7257MODULE_PARM_DESC(hotkey_report_mode, 7258 "used for backwards compatibility with userspace, " 7259 "see documentation"); 7260 7261#define TPACPI_PARAM(feature) \ 7262 module_param_call(feature, set_ibm_param, NULL, NULL, 0); \ 7263 MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command " \ 7264 "at module load, see documentation") 7265 7266TPACPI_PARAM(hotkey); 7267TPACPI_PARAM(bluetooth); 7268TPACPI_PARAM(video); 7269TPACPI_PARAM(light); 7270#ifdef CONFIG_THINKPAD_ACPI_DOCK 7271TPACPI_PARAM(dock); 7272#endif 7273#ifdef CONFIG_THINKPAD_ACPI_BAY 7274TPACPI_PARAM(bay); 7275#endif /* CONFIG_THINKPAD_ACPI_BAY */ 7276TPACPI_PARAM(cmos); 7277TPACPI_PARAM(led); 7278TPACPI_PARAM(beep); 7279TPACPI_PARAM(ecdump); 7280TPACPI_PARAM(brightness); 7281TPACPI_PARAM(volume); 7282TPACPI_PARAM(fan); 7283 7284#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 7285module_param(dbg_wlswemul, uint, 0); 7286MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation"); 7287module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0); 7288MODULE_PARM_DESC(wlsw_state, 7289 "Initial state of the emulated WLSW switch"); 7290 7291module_param(dbg_bluetoothemul, uint, 0); 7292MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation"); 7293module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0); 7294MODULE_PARM_DESC(bluetooth_state, 7295 "Initial state of the emulated bluetooth switch"); 7296 7297module_param(dbg_wwanemul, uint, 0); 7298MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation"); 7299module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0); 7300MODULE_PARM_DESC(wwan_state, 7301 "Initial state of the emulated WWAN switch"); 7302 7303module_param(dbg_uwbemul, uint, 0); 7304MODULE_PARM_DESC(dbg_uwbemul, "Enables UWB switch emulation"); 7305module_param_named(uwb_state, tpacpi_uwb_emulstate, bool, 0); 7306MODULE_PARM_DESC(uwb_state, 7307 "Initial state of the emulated UWB switch"); 7308#endif 7309 7310static void thinkpad_acpi_module_exit(void) 7311{ 7312 struct ibm_struct *ibm, *itmp; 7313 7314 tpacpi_lifecycle = TPACPI_LIFE_EXITING; 7315 7316 list_for_each_entry_safe_reverse(ibm, itmp, 7317 &tpacpi_all_drivers, 7318 all_drivers) { 7319 ibm_exit(ibm); 7320 } 7321 7322 dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n"); 7323 7324 if (tpacpi_inputdev) { 7325 if (tp_features.input_device_registered) 7326 input_unregister_device(tpacpi_inputdev); 7327 else 7328 input_free_device(tpacpi_inputdev); 7329 } 7330 7331 if (tpacpi_hwmon) 7332 hwmon_device_unregister(tpacpi_hwmon); 7333 7334 if (tp_features.sensors_pdev_attrs_registered) 7335 device_remove_file(&tpacpi_sensors_pdev->dev, 7336 &dev_attr_thinkpad_acpi_pdev_name); 7337 if (tpacpi_sensors_pdev) 7338 platform_device_unregister(tpacpi_sensors_pdev); 7339 if (tpacpi_pdev) 7340 platform_device_unregister(tpacpi_pdev); 7341 7342 if (tp_features.sensors_pdrv_attrs_registered) 7343 tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver); 7344 if (tp_features.platform_drv_attrs_registered) 7345 tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver); 7346 7347 if (tp_features.sensors_pdrv_registered) 7348 platform_driver_unregister(&tpacpi_hwmon_pdriver); 7349 7350 if (tp_features.platform_drv_registered) 7351 platform_driver_unregister(&tpacpi_pdriver); 7352 7353 if (proc_dir) 7354 remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir); 7355 7356 if (tpacpi_wq) 7357 destroy_workqueue(tpacpi_wq); 7358 7359 kfree(thinkpad_id.bios_version_str); 7360 kfree(thinkpad_id.ec_version_str); 7361 kfree(thinkpad_id.model_str); 7362} 7363 7364 7365static int __init thinkpad_acpi_module_init(void) 7366{ 7367 int ret, i; 7368 7369 tpacpi_lifecycle = TPACPI_LIFE_INIT; 7370 7371 /* Parameter checking */ 7372 if (hotkey_report_mode > 2) 7373 return -EINVAL; 7374 7375 /* Driver-level probe */ 7376 7377 ret = get_thinkpad_model_data(&thinkpad_id); 7378 if (ret) { 7379 printk(TPACPI_ERR 7380 "unable to get DMI data: %d\n", ret); 7381 thinkpad_acpi_module_exit(); 7382 return ret; 7383 } 7384 ret = probe_for_thinkpad(); 7385 if (ret) { 7386 thinkpad_acpi_module_exit(); 7387 return ret; 7388 } 7389 7390 /* Driver initialization */ 7391 7392 TPACPI_ACPIHANDLE_INIT(ecrd); 7393 TPACPI_ACPIHANDLE_INIT(ecwr); 7394 7395 tpacpi_wq = create_singlethread_workqueue(TPACPI_WORKQUEUE_NAME); 7396 if (!tpacpi_wq) { 7397 thinkpad_acpi_module_exit(); 7398 return -ENOMEM; 7399 } 7400 7401 proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir); 7402 if (!proc_dir) { 7403 printk(TPACPI_ERR 7404 "unable to create proc dir " TPACPI_PROC_DIR); 7405 thinkpad_acpi_module_exit(); 7406 return -ENODEV; 7407 } 7408 proc_dir->owner = THIS_MODULE; 7409 7410 ret = platform_driver_register(&tpacpi_pdriver); 7411 if (ret) { 7412 printk(TPACPI_ERR 7413 "unable to register main platform driver\n"); 7414 thinkpad_acpi_module_exit(); 7415 return ret; 7416 } 7417 tp_features.platform_drv_registered = 1; 7418 7419 ret = platform_driver_register(&tpacpi_hwmon_pdriver); 7420 if (ret) { 7421 printk(TPACPI_ERR 7422 "unable to register hwmon platform driver\n"); 7423 thinkpad_acpi_module_exit(); 7424 return ret; 7425 } 7426 tp_features.sensors_pdrv_registered = 1; 7427 7428 ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver); 7429 if (!ret) { 7430 tp_features.platform_drv_attrs_registered = 1; 7431 ret = tpacpi_create_driver_attributes( 7432 &tpacpi_hwmon_pdriver.driver); 7433 } 7434 if (ret) { 7435 printk(TPACPI_ERR 7436 "unable to create sysfs driver attributes\n"); 7437 thinkpad_acpi_module_exit(); 7438 return ret; 7439 } 7440 tp_features.sensors_pdrv_attrs_registered = 1; 7441 7442 7443 /* Device initialization */ 7444 tpacpi_pdev = platform_device_register_simple(TPACPI_DRVR_NAME, -1, 7445 NULL, 0); 7446 if (IS_ERR(tpacpi_pdev)) { 7447 ret = PTR_ERR(tpacpi_pdev); 7448 tpacpi_pdev = NULL; 7449 printk(TPACPI_ERR "unable to register platform device\n"); 7450 thinkpad_acpi_module_exit(); 7451 return ret; 7452 } 7453 tpacpi_sensors_pdev = platform_device_register_simple( 7454 TPACPI_HWMON_DRVR_NAME, 7455 -1, NULL, 0); 7456 if (IS_ERR(tpacpi_sensors_pdev)) { 7457 ret = PTR_ERR(tpacpi_sensors_pdev); 7458 tpacpi_sensors_pdev = NULL; 7459 printk(TPACPI_ERR 7460 "unable to register hwmon platform device\n"); 7461 thinkpad_acpi_module_exit(); 7462 return ret; 7463 } 7464 ret = device_create_file(&tpacpi_sensors_pdev->dev, 7465 &dev_attr_thinkpad_acpi_pdev_name); 7466 if (ret) { 7467 printk(TPACPI_ERR 7468 "unable to create sysfs hwmon device attributes\n"); 7469 thinkpad_acpi_module_exit(); 7470 return ret; 7471 } 7472 tp_features.sensors_pdev_attrs_registered = 1; 7473 tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev); 7474 if (IS_ERR(tpacpi_hwmon)) { 7475 ret = PTR_ERR(tpacpi_hwmon); 7476 tpacpi_hwmon = NULL; 7477 printk(TPACPI_ERR "unable to register hwmon device\n"); 7478 thinkpad_acpi_module_exit(); 7479 return ret; 7480 } 7481 mutex_init(&tpacpi_inputdev_send_mutex); 7482 tpacpi_inputdev = input_allocate_device(); 7483 if (!tpacpi_inputdev) { 7484 printk(TPACPI_ERR "unable to allocate input device\n"); 7485 thinkpad_acpi_module_exit(); 7486 return -ENOMEM; 7487 } else { 7488 /* Prepare input device, but don't register */ 7489 tpacpi_inputdev->name = "ThinkPad Extra Buttons"; 7490 tpacpi_inputdev->phys = TPACPI_DRVR_NAME "/input0"; 7491 tpacpi_inputdev->id.bustype = BUS_HOST; 7492 tpacpi_inputdev->id.vendor = (thinkpad_id.vendor) ? 7493 thinkpad_id.vendor : 7494 PCI_VENDOR_ID_IBM; 7495 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT; 7496 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION; 7497 } 7498 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { 7499 ret = ibm_init(&ibms_init[i]); 7500 if (ret >= 0 && *ibms_init[i].param) 7501 ret = ibms_init[i].data->write(ibms_init[i].param); 7502 if (ret < 0) { 7503 thinkpad_acpi_module_exit(); 7504 return ret; 7505 } 7506 } 7507 ret = input_register_device(tpacpi_inputdev); 7508 if (ret < 0) { 7509 printk(TPACPI_ERR "unable to register input device\n"); 7510 thinkpad_acpi_module_exit(); 7511 return ret; 7512 } else { 7513 tp_features.input_device_registered = 1; 7514 } 7515 7516 tpacpi_lifecycle = TPACPI_LIFE_RUNNING; 7517 return 0; 7518} 7519 7520/* Please remove this in year 2009 */ 7521MODULE_ALIAS("ibm_acpi"); 7522 7523MODULE_ALIAS(TPACPI_DRVR_SHORTNAME); 7524 7525/* 7526 * DMI matching for module autoloading 7527 * 7528 * See http://thinkwiki.org/wiki/List_of_DMI_IDs 7529 * See http://thinkwiki.org/wiki/BIOS_Upgrade_Downloads 7530 * 7531 * Only models listed in thinkwiki will be supported, so add yours 7532 * if it is not there yet. 7533 */ 7534#define IBM_BIOS_MODULE_ALIAS(__type) \ 7535 MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW*") 7536 7537/* Non-ancient thinkpads */ 7538MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*"); 7539MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*"); 7540 7541/* Ancient thinkpad BIOSes have to be identified by 7542 * BIOS type or model number, and there are far less 7543 * BIOS types than model numbers... */ 7544IBM_BIOS_MODULE_ALIAS("I[BDHIMNOTWVYZ]"); 7545IBM_BIOS_MODULE_ALIAS("1[0368A-GIKM-PST]"); 7546IBM_BIOS_MODULE_ALIAS("K[UX-Z]"); 7547 7548MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh"); 7549MODULE_DESCRIPTION(TPACPI_DESC); 7550MODULE_VERSION(TPACPI_VERSION); 7551MODULE_LICENSE("GPL"); 7552 7553module_init(thinkpad_acpi_module_init); 7554module_exit(thinkpad_acpi_module_exit); 7555