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