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

Configure Feed

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

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