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 c9a28fa7b9ac19b676deefa0a171ce7df8755c08 5073 lines 123 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-2007 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 IBM_VERSION "0.17" 25#define TPACPI_SYSFS_VERSION 0x020000 26 27/* 28 * Changelog: 29 * 2007-03-27 0.14 renamed to thinkpad_acpi and moved to 30 * drivers/misc. 31 * 32 * 2006-11-22 0.13 new maintainer 33 * changelog now lives in git commit history, and will 34 * not be updated further in-file. 35 * 36 * 2005-08-17 0.12 fix compilation on 2.6.13-rc kernels 37 * 2005-03-17 0.11 support for 600e, 770x 38 * thanks to Jamie Lentin <lentinj@dial.pipex.com> 39 * support for 770e, G41 40 * G40 and G41 don't have a thinklight 41 * temperatures no longer experimental 42 * experimental brightness control 43 * experimental volume control 44 * experimental fan enable/disable 45 * 2005-01-16 0.10 fix module loading on R30, R31 46 * 2005-01-16 0.9 support for 570, R30, R31 47 * ultrabay support on A22p, A3x 48 * limit arg for cmos, led, beep, drop experimental status 49 * more capable led control on A21e, A22p, T20-22, X20 50 * experimental temperatures and fan speed 51 * experimental embedded controller register dump 52 * mark more functions as __init, drop incorrect __exit 53 * use MODULE_VERSION 54 * thanks to Henrik Brix Andersen <brix@gentoo.org> 55 * fix parameter passing on module loading 56 * thanks to Rusty Russell <rusty@rustcorp.com.au> 57 * thanks to Jim Radford <radford@blackbean.org> 58 * 2004-11-08 0.8 fix init error case, don't return from a macro 59 * thanks to Chris Wright <chrisw@osdl.org> 60 * 2004-10-23 0.7 fix module loading on A21e, A22p, T20, T21, X20 61 * fix led control on A21e 62 * 2004-10-19 0.6 use acpi_bus_register_driver() to claim HKEY device 63 * 2004-10-18 0.5 thinklight support on A21e, G40, R32, T20, T21, X20 64 * proc file format changed 65 * video_switch command 66 * experimental cmos control 67 * experimental led control 68 * experimental acpi sounds 69 * 2004-09-16 0.4 support for module parameters 70 * hotkey mask can be prefixed by 0x 71 * video output switching 72 * video expansion control 73 * ultrabay eject support 74 * removed lcd brightness/on/off control, didn't work 75 * 2004-08-17 0.3 support for R40 76 * lcd off, brightness control 77 * thinklight on/off 78 * 2004-08-14 0.2 support for T series, X20 79 * bluetooth enable/disable 80 * hotkey events disabled by default 81 * removed fan control, currently useless 82 * 2004-08-09 0.1 initial release, support for X series 83 */ 84 85#include "thinkpad_acpi.h" 86 87MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh"); 88MODULE_DESCRIPTION(IBM_DESC); 89MODULE_VERSION(IBM_VERSION); 90MODULE_LICENSE("GPL"); 91 92/* Please remove this in year 2009 */ 93MODULE_ALIAS("ibm_acpi"); 94 95/* 96 * DMI matching for module autoloading 97 * 98 * See http://thinkwiki.org/wiki/List_of_DMI_IDs 99 * See http://thinkwiki.org/wiki/BIOS_Upgrade_Downloads 100 * 101 * Only models listed in thinkwiki will be supported, so add yours 102 * if it is not there yet. 103 */ 104#define IBM_BIOS_MODULE_ALIAS(__type) \ 105 MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW") 106 107/* Non-ancient thinkpads */ 108MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*"); 109MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*"); 110 111/* Ancient thinkpad BIOSes have to be identified by 112 * BIOS type or model number, and there are far less 113 * BIOS types than model numbers... */ 114IBM_BIOS_MODULE_ALIAS("I[B,D,H,I,M,N,O,T,W,V,Y,Z]"); 115IBM_BIOS_MODULE_ALIAS("1[0,3,6,8,A-G,I,K,M-P,S,T]"); 116IBM_BIOS_MODULE_ALIAS("K[U,X-Z]"); 117 118#define __unused __attribute__ ((unused)) 119 120static enum { 121 TPACPI_LIFE_INIT = 0, 122 TPACPI_LIFE_RUNNING, 123 TPACPI_LIFE_EXITING, 124} tpacpi_lifecycle; 125 126/**************************************************************************** 127 **************************************************************************** 128 * 129 * ACPI Helpers and device model 130 * 131 **************************************************************************** 132 ****************************************************************************/ 133 134/************************************************************************* 135 * ACPI basic handles 136 */ 137 138static acpi_handle root_handle; 139 140#define IBM_HANDLE(object, parent, paths...) \ 141 static acpi_handle object##_handle; \ 142 static acpi_handle *object##_parent = &parent##_handle; \ 143 static char *object##_path; \ 144 static char *object##_paths[] = { paths } 145 146IBM_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0", /* 240, 240x */ 147 "\\_SB.PCI.ISA.EC", /* 570 */ 148 "\\_SB.PCI0.ISA0.EC0", /* 600e/x, 770e, 770x */ 149 "\\_SB.PCI0.ISA.EC", /* A21e, A2xm/p, T20-22, X20-21 */ 150 "\\_SB.PCI0.AD4S.EC0", /* i1400, R30 */ 151 "\\_SB.PCI0.ICH3.EC0", /* R31 */ 152 "\\_SB.PCI0.LPC.EC", /* all others */ 153 ); 154 155IBM_HANDLE(ecrd, ec, "ECRD"); /* 570 */ 156IBM_HANDLE(ecwr, ec, "ECWR"); /* 570 */ 157 158 159/************************************************************************* 160 * Misc ACPI handles 161 */ 162 163IBM_HANDLE(cmos, root, "\\UCMS", /* R50, R50e, R50p, R51, T4x, X31, X40 */ 164 "\\CMOS", /* A3x, G4x, R32, T23, T30, X22-24, X30 */ 165 "\\CMS", /* R40, R40e */ 166 ); /* all others */ 167 168IBM_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */ 169 "^HKEY", /* R30, R31 */ 170 "HKEY", /* all others */ 171 ); /* 570 */ 172 173 174/************************************************************************* 175 * ACPI helpers 176 */ 177 178static int acpi_evalf(acpi_handle handle, 179 void *res, char *method, char *fmt, ...) 180{ 181 char *fmt0 = fmt; 182 struct acpi_object_list params; 183 union acpi_object in_objs[IBM_MAX_ACPI_ARGS]; 184 struct acpi_buffer result, *resultp; 185 union acpi_object out_obj; 186 acpi_status status; 187 va_list ap; 188 char res_type; 189 int success; 190 int quiet; 191 192 if (!*fmt) { 193 printk(IBM_ERR "acpi_evalf() called with empty format\n"); 194 return 0; 195 } 196 197 if (*fmt == 'q') { 198 quiet = 1; 199 fmt++; 200 } else 201 quiet = 0; 202 203 res_type = *(fmt++); 204 205 params.count = 0; 206 params.pointer = &in_objs[0]; 207 208 va_start(ap, fmt); 209 while (*fmt) { 210 char c = *(fmt++); 211 switch (c) { 212 case 'd': /* int */ 213 in_objs[params.count].integer.value = va_arg(ap, int); 214 in_objs[params.count++].type = ACPI_TYPE_INTEGER; 215 break; 216 /* add more types as needed */ 217 default: 218 printk(IBM_ERR "acpi_evalf() called " 219 "with invalid format character '%c'\n", c); 220 return 0; 221 } 222 } 223 va_end(ap); 224 225 if (res_type != 'v') { 226 result.length = sizeof(out_obj); 227 result.pointer = &out_obj; 228 resultp = &result; 229 } else 230 resultp = NULL; 231 232 status = acpi_evaluate_object(handle, method, &params, resultp); 233 234 switch (res_type) { 235 case 'd': /* int */ 236 if (res) 237 *(int *)res = out_obj.integer.value; 238 success = status == AE_OK && out_obj.type == ACPI_TYPE_INTEGER; 239 break; 240 case 'v': /* void */ 241 success = status == AE_OK; 242 break; 243 /* add more types as needed */ 244 default: 245 printk(IBM_ERR "acpi_evalf() called " 246 "with invalid format character '%c'\n", res_type); 247 return 0; 248 } 249 250 if (!success && !quiet) 251 printk(IBM_ERR "acpi_evalf(%s, %s, ...) failed: %d\n", 252 method, fmt0, status); 253 254 return success; 255} 256 257static void __unused acpi_print_int(acpi_handle handle, char *method) 258{ 259 int i; 260 261 if (acpi_evalf(handle, &i, method, "d")) 262 printk(IBM_INFO "%s = 0x%x\n", method, i); 263 else 264 printk(IBM_ERR "error calling %s\n", method); 265} 266 267static int acpi_ec_read(int i, u8 * p) 268{ 269 int v; 270 271 if (ecrd_handle) { 272 if (!acpi_evalf(ecrd_handle, &v, NULL, "dd", i)) 273 return 0; 274 *p = v; 275 } else { 276 if (ec_read(i, p) < 0) 277 return 0; 278 } 279 280 return 1; 281} 282 283static int acpi_ec_write(int i, u8 v) 284{ 285 if (ecwr_handle) { 286 if (!acpi_evalf(ecwr_handle, NULL, NULL, "vdd", i, v)) 287 return 0; 288 } else { 289 if (ec_write(i, v) < 0) 290 return 0; 291 } 292 293 return 1; 294} 295 296static int _sta(acpi_handle handle) 297{ 298 int status; 299 300 if (!handle || !acpi_evalf(handle, &status, "_STA", "d")) 301 status = 0; 302 303 return status; 304} 305 306static int issue_thinkpad_cmos_command(int cmos_cmd) 307{ 308 if (!cmos_handle) 309 return -ENXIO; 310 311 if (!acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd)) 312 return -EIO; 313 314 return 0; 315} 316 317/************************************************************************* 318 * ACPI device model 319 */ 320 321static void drv_acpi_handle_init(char *name, 322 acpi_handle *handle, acpi_handle parent, 323 char **paths, int num_paths, char **path) 324{ 325 int i; 326 acpi_status status; 327 328 vdbg_printk(TPACPI_DBG_INIT, "trying to locate ACPI handle for %s\n", 329 name); 330 331 for (i = 0; i < num_paths; i++) { 332 status = acpi_get_handle(parent, paths[i], handle); 333 if (ACPI_SUCCESS(status)) { 334 *path = paths[i]; 335 dbg_printk(TPACPI_DBG_INIT, 336 "Found ACPI handle %s for %s\n", 337 *path, name); 338 return; 339 } 340 } 341 342 vdbg_printk(TPACPI_DBG_INIT, "ACPI handle for %s not found\n", 343 name); 344 *handle = NULL; 345} 346 347static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data) 348{ 349 struct ibm_struct *ibm = data; 350 351 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING) 352 return; 353 354 if (!ibm || !ibm->acpi || !ibm->acpi->notify) 355 return; 356 357 ibm->acpi->notify(ibm, event); 358} 359 360static int __init setup_acpi_notify(struct ibm_struct *ibm) 361{ 362 acpi_status status; 363 int rc; 364 365 BUG_ON(!ibm->acpi); 366 367 if (!*ibm->acpi->handle) 368 return 0; 369 370 vdbg_printk(TPACPI_DBG_INIT, 371 "setting up ACPI notify for %s\n", ibm->name); 372 373 rc = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device); 374 if (rc < 0) { 375 printk(IBM_ERR "acpi_bus_get_device(%s) failed: %d\n", 376 ibm->name, rc); 377 return -ENODEV; 378 } 379 380 acpi_driver_data(ibm->acpi->device) = ibm; 381 sprintf(acpi_device_class(ibm->acpi->device), "%s/%s", 382 IBM_ACPI_EVENT_PREFIX, 383 ibm->name); 384 385 status = acpi_install_notify_handler(*ibm->acpi->handle, 386 ibm->acpi->type, dispatch_acpi_notify, ibm); 387 if (ACPI_FAILURE(status)) { 388 if (status == AE_ALREADY_EXISTS) { 389 printk(IBM_NOTICE "another device driver is already handling %s events\n", 390 ibm->name); 391 } else { 392 printk(IBM_ERR "acpi_install_notify_handler(%s) failed: %d\n", 393 ibm->name, status); 394 } 395 return -ENODEV; 396 } 397 ibm->flags.acpi_notify_installed = 1; 398 return 0; 399} 400 401static int __init tpacpi_device_add(struct acpi_device *device) 402{ 403 return 0; 404} 405 406static int __init register_tpacpi_subdriver(struct ibm_struct *ibm) 407{ 408 int rc; 409 410 dbg_printk(TPACPI_DBG_INIT, 411 "registering %s as an ACPI driver\n", ibm->name); 412 413 BUG_ON(!ibm->acpi); 414 415 ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL); 416 if (!ibm->acpi->driver) { 417 printk(IBM_ERR "kzalloc(ibm->driver) failed\n"); 418 return -ENOMEM; 419 } 420 421 sprintf(ibm->acpi->driver->name, "%s_%s", IBM_NAME, ibm->name); 422 ibm->acpi->driver->ids = ibm->acpi->hid; 423 424 ibm->acpi->driver->ops.add = &tpacpi_device_add; 425 426 rc = acpi_bus_register_driver(ibm->acpi->driver); 427 if (rc < 0) { 428 printk(IBM_ERR "acpi_bus_register_driver(%s) failed: %d\n", 429 ibm->name, rc); 430 kfree(ibm->acpi->driver); 431 ibm->acpi->driver = NULL; 432 } else if (!rc) 433 ibm->flags.acpi_driver_registered = 1; 434 435 return rc; 436} 437 438 439/**************************************************************************** 440 **************************************************************************** 441 * 442 * Procfs Helpers 443 * 444 **************************************************************************** 445 ****************************************************************************/ 446 447static int dispatch_procfs_read(char *page, char **start, off_t off, 448 int count, int *eof, void *data) 449{ 450 struct ibm_struct *ibm = data; 451 int len; 452 453 if (!ibm || !ibm->read) 454 return -EINVAL; 455 456 len = ibm->read(page); 457 if (len < 0) 458 return len; 459 460 if (len <= off + count) 461 *eof = 1; 462 *start = page + off; 463 len -= off; 464 if (len > count) 465 len = count; 466 if (len < 0) 467 len = 0; 468 469 return len; 470} 471 472static int dispatch_procfs_write(struct file *file, 473 const char __user * userbuf, 474 unsigned long count, void *data) 475{ 476 struct ibm_struct *ibm = data; 477 char *kernbuf; 478 int ret; 479 480 if (!ibm || !ibm->write) 481 return -EINVAL; 482 483 kernbuf = kmalloc(count + 2, GFP_KERNEL); 484 if (!kernbuf) 485 return -ENOMEM; 486 487 if (copy_from_user(kernbuf, userbuf, count)) { 488 kfree(kernbuf); 489 return -EFAULT; 490 } 491 492 kernbuf[count] = 0; 493 strcat(kernbuf, ","); 494 ret = ibm->write(kernbuf); 495 if (ret == 0) 496 ret = count; 497 498 kfree(kernbuf); 499 500 return ret; 501} 502 503static char *next_cmd(char **cmds) 504{ 505 char *start = *cmds; 506 char *end; 507 508 while ((end = strchr(start, ',')) && end == start) 509 start = end + 1; 510 511 if (!end) 512 return NULL; 513 514 *end = 0; 515 *cmds = end + 1; 516 return start; 517} 518 519 520/**************************************************************************** 521 **************************************************************************** 522 * 523 * Device model: input, hwmon and platform 524 * 525 **************************************************************************** 526 ****************************************************************************/ 527 528static struct platform_device *tpacpi_pdev; 529static struct platform_device *tpacpi_sensors_pdev; 530static struct device *tpacpi_hwmon; 531static struct input_dev *tpacpi_inputdev; 532static struct mutex tpacpi_inputdev_send_mutex; 533 534 535static int tpacpi_resume_handler(struct platform_device *pdev) 536{ 537 struct ibm_struct *ibm, *itmp; 538 539 list_for_each_entry_safe(ibm, itmp, 540 &tpacpi_all_drivers, 541 all_drivers) { 542 if (ibm->resume) 543 (ibm->resume)(); 544 } 545 546 return 0; 547} 548 549static struct platform_driver tpacpi_pdriver = { 550 .driver = { 551 .name = IBM_DRVR_NAME, 552 .owner = THIS_MODULE, 553 }, 554 .resume = tpacpi_resume_handler, 555}; 556 557static struct platform_driver tpacpi_hwmon_pdriver = { 558 .driver = { 559 .name = IBM_HWMON_DRVR_NAME, 560 .owner = THIS_MODULE, 561 }, 562}; 563 564/************************************************************************* 565 * thinkpad-acpi driver attributes 566 */ 567 568/* interface_version --------------------------------------------------- */ 569static ssize_t tpacpi_driver_interface_version_show( 570 struct device_driver *drv, 571 char *buf) 572{ 573 return snprintf(buf, PAGE_SIZE, "0x%08x\n", TPACPI_SYSFS_VERSION); 574} 575 576static DRIVER_ATTR(interface_version, S_IRUGO, 577 tpacpi_driver_interface_version_show, NULL); 578 579/* debug_level --------------------------------------------------------- */ 580static ssize_t tpacpi_driver_debug_show(struct device_driver *drv, 581 char *buf) 582{ 583 return snprintf(buf, PAGE_SIZE, "0x%04x\n", dbg_level); 584} 585 586static ssize_t tpacpi_driver_debug_store(struct device_driver *drv, 587 const char *buf, size_t count) 588{ 589 unsigned long t; 590 591 if (parse_strtoul(buf, 0xffff, &t)) 592 return -EINVAL; 593 594 dbg_level = t; 595 596 return count; 597} 598 599static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, 600 tpacpi_driver_debug_show, tpacpi_driver_debug_store); 601 602/* version ------------------------------------------------------------- */ 603static ssize_t tpacpi_driver_version_show(struct device_driver *drv, 604 char *buf) 605{ 606 return snprintf(buf, PAGE_SIZE, "%s v%s\n", IBM_DESC, IBM_VERSION); 607} 608 609static DRIVER_ATTR(version, S_IRUGO, 610 tpacpi_driver_version_show, NULL); 611 612/* --------------------------------------------------------------------- */ 613 614static struct driver_attribute* tpacpi_driver_attributes[] = { 615 &driver_attr_debug_level, &driver_attr_version, 616 &driver_attr_interface_version, 617}; 618 619static int __init tpacpi_create_driver_attributes(struct device_driver *drv) 620{ 621 int i, res; 622 623 i = 0; 624 res = 0; 625 while (!res && i < ARRAY_SIZE(tpacpi_driver_attributes)) { 626 res = driver_create_file(drv, tpacpi_driver_attributes[i]); 627 i++; 628 } 629 630 return res; 631} 632 633static void tpacpi_remove_driver_attributes(struct device_driver *drv) 634{ 635 int i; 636 637 for(i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++) 638 driver_remove_file(drv, tpacpi_driver_attributes[i]); 639} 640 641/************************************************************************* 642 * sysfs support helpers 643 */ 644 645struct attribute_set_obj { 646 struct attribute_set s; 647 struct attribute *a; 648} __attribute__((packed)); 649 650static struct attribute_set *create_attr_set(unsigned int max_members, 651 const char* name) 652{ 653 struct attribute_set_obj *sobj; 654 655 if (max_members == 0) 656 return NULL; 657 658 /* Allocates space for implicit NULL at the end too */ 659 sobj = kzalloc(sizeof(struct attribute_set_obj) + 660 max_members * sizeof(struct attribute *), 661 GFP_KERNEL); 662 if (!sobj) 663 return NULL; 664 sobj->s.max_members = max_members; 665 sobj->s.group.attrs = &sobj->a; 666 sobj->s.group.name = name; 667 668 return &sobj->s; 669} 670 671/* not multi-threaded safe, use it in a single thread per set */ 672static int add_to_attr_set(struct attribute_set* s, struct attribute *attr) 673{ 674 if (!s || !attr) 675 return -EINVAL; 676 677 if (s->members >= s->max_members) 678 return -ENOMEM; 679 680 s->group.attrs[s->members] = attr; 681 s->members++; 682 683 return 0; 684} 685 686static int add_many_to_attr_set(struct attribute_set* s, 687 struct attribute **attr, 688 unsigned int count) 689{ 690 int i, res; 691 692 for (i = 0; i < count; i++) { 693 res = add_to_attr_set(s, attr[i]); 694 if (res) 695 return res; 696 } 697 698 return 0; 699} 700 701static void delete_attr_set(struct attribute_set* s, struct kobject *kobj) 702{ 703 sysfs_remove_group(kobj, &s->group); 704 destroy_attr_set(s); 705} 706 707static int parse_strtoul(const char *buf, 708 unsigned long max, unsigned long *value) 709{ 710 char *endp; 711 712 while (*buf && isspace(*buf)) 713 buf++; 714 *value = simple_strtoul(buf, &endp, 0); 715 while (*endp && isspace(*endp)) 716 endp++; 717 if (*endp || *value > max) 718 return -EINVAL; 719 720 return 0; 721} 722 723/**************************************************************************** 724 **************************************************************************** 725 * 726 * Subdrivers 727 * 728 **************************************************************************** 729 ****************************************************************************/ 730 731/************************************************************************* 732 * thinkpad-acpi init subdriver 733 */ 734 735static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm) 736{ 737 printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION); 738 printk(IBM_INFO "%s\n", IBM_URL); 739 740 printk(IBM_INFO "ThinkPad BIOS %s, EC %s\n", 741 (thinkpad_id.bios_version_str) ? 742 thinkpad_id.bios_version_str : "unknown", 743 (thinkpad_id.ec_version_str) ? 744 thinkpad_id.ec_version_str : "unknown"); 745 746 if (thinkpad_id.vendor && thinkpad_id.model_str) 747 printk(IBM_INFO "%s %s\n", 748 (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? 749 "IBM" : ((thinkpad_id.vendor == 750 PCI_VENDOR_ID_LENOVO) ? 751 "Lenovo" : "Unknown vendor"), 752 thinkpad_id.model_str); 753 754 return 0; 755} 756 757static int thinkpad_acpi_driver_read(char *p) 758{ 759 int len = 0; 760 761 len += sprintf(p + len, "driver:\t\t%s\n", IBM_DESC); 762 len += sprintf(p + len, "version:\t%s\n", IBM_VERSION); 763 764 return len; 765} 766 767static struct ibm_struct thinkpad_acpi_driver_data = { 768 .name = "driver", 769 .read = thinkpad_acpi_driver_read, 770}; 771 772/************************************************************************* 773 * Hotkey subdriver 774 */ 775 776static int hotkey_orig_status; 777static u32 hotkey_orig_mask; 778static u32 hotkey_all_mask; 779static u32 hotkey_reserved_mask; 780 781static u16 *hotkey_keycode_map; 782 783static struct attribute_set *hotkey_dev_attributes; 784 785static int hotkey_get_wlsw(int *status) 786{ 787 if (!acpi_evalf(hkey_handle, status, "WLSW", "d")) 788 return -EIO; 789 return 0; 790} 791 792/* sysfs hotkey enable ------------------------------------------------- */ 793static ssize_t hotkey_enable_show(struct device *dev, 794 struct device_attribute *attr, 795 char *buf) 796{ 797 int res, status; 798 u32 mask; 799 800 res = hotkey_get(&status, &mask); 801 if (res) 802 return res; 803 804 return snprintf(buf, PAGE_SIZE, "%d\n", status); 805} 806 807static ssize_t hotkey_enable_store(struct device *dev, 808 struct device_attribute *attr, 809 const char *buf, size_t count) 810{ 811 unsigned long t; 812 int res, status; 813 u32 mask; 814 815 if (parse_strtoul(buf, 1, &t)) 816 return -EINVAL; 817 818 res = hotkey_get(&status, &mask); 819 if (!res) 820 res = hotkey_set(t, mask); 821 822 return (res) ? res : count; 823} 824 825static struct device_attribute dev_attr_hotkey_enable = 826 __ATTR(hotkey_enable, S_IWUSR | S_IRUGO, 827 hotkey_enable_show, hotkey_enable_store); 828 829/* sysfs hotkey mask --------------------------------------------------- */ 830static ssize_t hotkey_mask_show(struct device *dev, 831 struct device_attribute *attr, 832 char *buf) 833{ 834 int res, status; 835 u32 mask; 836 837 res = hotkey_get(&status, &mask); 838 if (res) 839 return res; 840 841 return snprintf(buf, PAGE_SIZE, "0x%08x\n", mask); 842} 843 844static ssize_t hotkey_mask_store(struct device *dev, 845 struct device_attribute *attr, 846 const char *buf, size_t count) 847{ 848 unsigned long t; 849 int res, status; 850 u32 mask; 851 852 if (parse_strtoul(buf, 0xffffffffUL, &t)) 853 return -EINVAL; 854 855 res = hotkey_get(&status, &mask); 856 if (!res) 857 hotkey_set(status, t); 858 859 return (res) ? res : count; 860} 861 862static struct device_attribute dev_attr_hotkey_mask = 863 __ATTR(hotkey_mask, S_IWUSR | S_IRUGO, 864 hotkey_mask_show, hotkey_mask_store); 865 866/* sysfs hotkey bios_enabled ------------------------------------------- */ 867static ssize_t hotkey_bios_enabled_show(struct device *dev, 868 struct device_attribute *attr, 869 char *buf) 870{ 871 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status); 872} 873 874static struct device_attribute dev_attr_hotkey_bios_enabled = 875 __ATTR(hotkey_bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL); 876 877/* sysfs hotkey bios_mask ---------------------------------------------- */ 878static ssize_t hotkey_bios_mask_show(struct device *dev, 879 struct device_attribute *attr, 880 char *buf) 881{ 882 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask); 883} 884 885static struct device_attribute dev_attr_hotkey_bios_mask = 886 __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL); 887 888/* sysfs hotkey all_mask ----------------------------------------------- */ 889static ssize_t hotkey_all_mask_show(struct device *dev, 890 struct device_attribute *attr, 891 char *buf) 892{ 893 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_all_mask); 894} 895 896static struct device_attribute dev_attr_hotkey_all_mask = 897 __ATTR(hotkey_all_mask, S_IRUGO, hotkey_all_mask_show, NULL); 898 899/* sysfs hotkey recommended_mask --------------------------------------- */ 900static ssize_t hotkey_recommended_mask_show(struct device *dev, 901 struct device_attribute *attr, 902 char *buf) 903{ 904 return snprintf(buf, PAGE_SIZE, "0x%08x\n", 905 hotkey_all_mask & ~hotkey_reserved_mask); 906} 907 908static struct device_attribute dev_attr_hotkey_recommended_mask = 909 __ATTR(hotkey_recommended_mask, S_IRUGO, 910 hotkey_recommended_mask_show, NULL); 911 912/* sysfs hotkey radio_sw ----------------------------------------------- */ 913static ssize_t hotkey_radio_sw_show(struct device *dev, 914 struct device_attribute *attr, 915 char *buf) 916{ 917 int res, s; 918 res = hotkey_get_wlsw(&s); 919 if (res < 0) 920 return res; 921 922 return snprintf(buf, PAGE_SIZE, "%d\n", !!s); 923} 924 925static struct device_attribute dev_attr_hotkey_radio_sw = 926 __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL); 927 928/* sysfs hotkey report_mode -------------------------------------------- */ 929static ssize_t hotkey_report_mode_show(struct device *dev, 930 struct device_attribute *attr, 931 char *buf) 932{ 933 return snprintf(buf, PAGE_SIZE, "%d\n", 934 (hotkey_report_mode != 0) ? hotkey_report_mode : 1); 935} 936 937static struct device_attribute dev_attr_hotkey_report_mode = 938 __ATTR(hotkey_report_mode, S_IRUGO, hotkey_report_mode_show, NULL); 939 940/* --------------------------------------------------------------------- */ 941 942static struct attribute *hotkey_attributes[] __initdata = { 943 &dev_attr_hotkey_enable.attr, 944 &dev_attr_hotkey_report_mode.attr, 945}; 946 947static struct attribute *hotkey_mask_attributes[] __initdata = { 948 &dev_attr_hotkey_mask.attr, 949 &dev_attr_hotkey_bios_enabled.attr, 950 &dev_attr_hotkey_bios_mask.attr, 951 &dev_attr_hotkey_all_mask.attr, 952 &dev_attr_hotkey_recommended_mask.attr, 953}; 954 955static int __init hotkey_init(struct ibm_init_struct *iibm) 956{ 957 958 static u16 ibm_keycode_map[] __initdata = { 959 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ 960 KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP, 961 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, 962 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, 963 /* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */ 964 KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ 965 KEY_UNKNOWN, /* 0x0D: FN+INSERT */ 966 KEY_UNKNOWN, /* 0x0E: FN+DELETE */ 967 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ 968 /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */ 969 KEY_RESERVED, /* 0x10: FN+END (brightness down) */ 970 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ 971 KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ 972 KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ 973 KEY_RESERVED, /* 0x14: VOLUME UP */ 974 KEY_RESERVED, /* 0x15: VOLUME DOWN */ 975 KEY_RESERVED, /* 0x16: MUTE */ 976 KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ 977 /* (assignments unknown, please report if found) */ 978 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 979 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 980 }; 981 static u16 lenovo_keycode_map[] __initdata = { 982 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ 983 KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP, 984 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, 985 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, 986 /* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */ 987 KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ 988 KEY_UNKNOWN, /* 0x0D: FN+INSERT */ 989 KEY_UNKNOWN, /* 0x0E: FN+DELETE */ 990 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ 991 /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */ 992 KEY_RESERVED, /* 0x10: FN+END (brightness down) */ 993 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ 994 KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ 995 KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ 996 KEY_RESERVED, /* 0x14: VOLUME UP */ 997 KEY_RESERVED, /* 0x15: VOLUME DOWN */ 998 KEY_RESERVED, /* 0x16: MUTE */ 999 KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ 1000 /* (assignments unknown, please report if found) */ 1001 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 1002 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 1003 }; 1004 1005#define TPACPI_HOTKEY_MAP_LEN ARRAY_SIZE(ibm_keycode_map) 1006#define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map) 1007#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0]) 1008 1009 int res, i; 1010 int status; 1011 int hkeyv; 1012 1013 vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n"); 1014 1015 BUG_ON(!tpacpi_inputdev); 1016 1017 IBM_ACPIHANDLE_INIT(hkey); 1018 mutex_init(&hotkey_mutex); 1019 1020 /* hotkey not supported on 570 */ 1021 tp_features.hotkey = hkey_handle != NULL; 1022 1023 vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n", 1024 str_supported(tp_features.hotkey)); 1025 1026 if (tp_features.hotkey) { 1027 hotkey_dev_attributes = create_attr_set(8, NULL); 1028 if (!hotkey_dev_attributes) 1029 return -ENOMEM; 1030 res = add_many_to_attr_set(hotkey_dev_attributes, 1031 hotkey_attributes, 1032 ARRAY_SIZE(hotkey_attributes)); 1033 if (res) 1034 return res; 1035 1036 /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 1037 A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking 1038 for HKEY interface version 0x100 */ 1039 if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { 1040 if ((hkeyv >> 8) != 1) { 1041 printk(IBM_ERR "unknown version of the " 1042 "HKEY interface: 0x%x\n", hkeyv); 1043 printk(IBM_ERR "please report this to %s\n", 1044 IBM_MAIL); 1045 } else { 1046 /* 1047 * MHKV 0x100 in A31, R40, R40e, 1048 * T4x, X31, and later 1049 * */ 1050 tp_features.hotkey_mask = 1; 1051 } 1052 } 1053 1054 vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", 1055 str_supported(tp_features.hotkey_mask)); 1056 1057 if (tp_features.hotkey_mask) { 1058 if (!acpi_evalf(hkey_handle, &hotkey_all_mask, 1059 "MHKA", "qd")) { 1060 printk(IBM_ERR 1061 "missing MHKA handler, " 1062 "please report this to %s\n", 1063 IBM_MAIL); 1064 hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */ 1065 } 1066 } 1067 1068 res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask); 1069 if (!res && tp_features.hotkey_mask) { 1070 res = add_many_to_attr_set(hotkey_dev_attributes, 1071 hotkey_mask_attributes, 1072 ARRAY_SIZE(hotkey_mask_attributes)); 1073 } 1074 1075 /* Not all thinkpads have a hardware radio switch */ 1076 if (!res && acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { 1077 tp_features.hotkey_wlsw = 1; 1078 printk(IBM_INFO 1079 "radio switch found; radios are %s\n", 1080 enabled(status, 0)); 1081 res = add_to_attr_set(hotkey_dev_attributes, 1082 &dev_attr_hotkey_radio_sw.attr); 1083 } 1084 1085 if (!res) 1086 res = register_attr_set_with_sysfs( 1087 hotkey_dev_attributes, 1088 &tpacpi_pdev->dev.kobj); 1089 if (res) 1090 return res; 1091 1092 /* Set up key map */ 1093 1094 hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, 1095 GFP_KERNEL); 1096 if (!hotkey_keycode_map) { 1097 printk(IBM_ERR "failed to allocate memory for key map\n"); 1098 return -ENOMEM; 1099 } 1100 1101 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { 1102 dbg_printk(TPACPI_DBG_INIT, 1103 "using Lenovo default hot key map\n"); 1104 memcpy(hotkey_keycode_map, &lenovo_keycode_map, 1105 TPACPI_HOTKEY_MAP_SIZE); 1106 } else { 1107 dbg_printk(TPACPI_DBG_INIT, 1108 "using IBM default hot key map\n"); 1109 memcpy(hotkey_keycode_map, &ibm_keycode_map, 1110 TPACPI_HOTKEY_MAP_SIZE); 1111 } 1112 1113 set_bit(EV_KEY, tpacpi_inputdev->evbit); 1114 set_bit(EV_MSC, tpacpi_inputdev->evbit); 1115 set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); 1116 tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; 1117 tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; 1118 tpacpi_inputdev->keycode = hotkey_keycode_map; 1119 for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { 1120 if (hotkey_keycode_map[i] != KEY_RESERVED) { 1121 set_bit(hotkey_keycode_map[i], 1122 tpacpi_inputdev->keybit); 1123 } else { 1124 if (i < sizeof(hotkey_reserved_mask)*8) 1125 hotkey_reserved_mask |= 1 << i; 1126 } 1127 } 1128 1129 if (tp_features.hotkey_wlsw) { 1130 set_bit(EV_SW, tpacpi_inputdev->evbit); 1131 set_bit(SW_RADIO, tpacpi_inputdev->swbit); 1132 } 1133 1134 dbg_printk(TPACPI_DBG_INIT, 1135 "enabling hot key handling\n"); 1136 res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask) 1137 | hotkey_orig_mask); 1138 if (res) 1139 return res; 1140 1141 dbg_printk(TPACPI_DBG_INIT, 1142 "legacy hot key reporting over procfs %s\n", 1143 (hotkey_report_mode < 2) ? 1144 "enabled" : "disabled"); 1145 } 1146 1147 return (tp_features.hotkey)? 0 : 1; 1148} 1149 1150static void hotkey_exit(void) 1151{ 1152 int res; 1153 1154 if (tp_features.hotkey) { 1155 dbg_printk(TPACPI_DBG_EXIT, "restoring original hotkey mask\n"); 1156 res = hotkey_set(hotkey_orig_status, hotkey_orig_mask); 1157 if (res) 1158 printk(IBM_ERR "failed to restore hotkey to BIOS defaults\n"); 1159 } 1160 1161 if (hotkey_dev_attributes) { 1162 delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); 1163 hotkey_dev_attributes = NULL; 1164 } 1165} 1166 1167static void tpacpi_input_send_key(unsigned int scancode, 1168 unsigned int keycode) 1169{ 1170 if (keycode != KEY_RESERVED) { 1171 mutex_lock(&tpacpi_inputdev_send_mutex); 1172 1173 input_report_key(tpacpi_inputdev, keycode, 1); 1174 if (keycode == KEY_UNKNOWN) 1175 input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, 1176 scancode); 1177 input_sync(tpacpi_inputdev); 1178 1179 input_report_key(tpacpi_inputdev, keycode, 0); 1180 if (keycode == KEY_UNKNOWN) 1181 input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, 1182 scancode); 1183 input_sync(tpacpi_inputdev); 1184 1185 mutex_unlock(&tpacpi_inputdev_send_mutex); 1186 } 1187} 1188 1189static void tpacpi_input_send_radiosw(void) 1190{ 1191 int wlsw; 1192 1193 mutex_lock(&tpacpi_inputdev_send_mutex); 1194 1195 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) { 1196 input_report_switch(tpacpi_inputdev, 1197 SW_RADIO, !!wlsw); 1198 input_sync(tpacpi_inputdev); 1199 } 1200 1201 mutex_unlock(&tpacpi_inputdev_send_mutex); 1202} 1203 1204static void hotkey_notify(struct ibm_struct *ibm, u32 event) 1205{ 1206 u32 hkey; 1207 unsigned int keycode, scancode; 1208 int send_acpi_ev; 1209 int ignore_acpi_ev; 1210 1211 if (event != 0x80) { 1212 printk(IBM_ERR "unknown HKEY notification event %d\n", event); 1213 /* forward it to userspace, maybe it knows how to handle it */ 1214 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, 1215 ibm->acpi->device->dev.bus_id, 1216 event, 0); 1217 return; 1218 } 1219 1220 while (1) { 1221 if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { 1222 printk(IBM_ERR "failed to retrieve HKEY event\n"); 1223 return; 1224 } 1225 1226 if (hkey == 0) { 1227 /* queue empty */ 1228 return; 1229 } 1230 1231 send_acpi_ev = 0; 1232 ignore_acpi_ev = 0; 1233 1234 switch (hkey >> 12) { 1235 case 1: 1236 /* 0x1000-0x1FFF: key presses */ 1237 scancode = hkey & 0xfff; 1238 if (scancode > 0 && scancode < 0x21) { 1239 scancode--; 1240 keycode = hotkey_keycode_map[scancode]; 1241 tpacpi_input_send_key(scancode, keycode); 1242 } else { 1243 printk(IBM_ERR 1244 "hotkey 0x%04x out of range for keyboard map\n", 1245 hkey); 1246 send_acpi_ev = 1; 1247 } 1248 break; 1249 case 5: 1250 /* 0x5000-0x5FFF: LID */ 1251 /* we don't handle it through this path, just 1252 * eat up known LID events */ 1253 if (hkey != 0x5001 && hkey != 0x5002) { 1254 printk(IBM_ERR 1255 "unknown LID-related HKEY event: 0x%04x\n", 1256 hkey); 1257 send_acpi_ev = 1; 1258 } else { 1259 ignore_acpi_ev = 1; 1260 } 1261 break; 1262 case 7: 1263 /* 0x7000-0x7FFF: misc */ 1264 if (tp_features.hotkey_wlsw && hkey == 0x7000) { 1265 tpacpi_input_send_radiosw(); 1266 break; 1267 } 1268 /* fallthrough to default */ 1269 default: 1270 /* case 2: dock-related */ 1271 /* 0x2305 - T43 waking up due to bay lever eject while aslept */ 1272 /* case 3: ultra-bay related. maybe bay in dock? */ 1273 /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */ 1274 printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey); 1275 send_acpi_ev = 1; 1276 } 1277 1278 /* Legacy events */ 1279 if (!ignore_acpi_ev && (send_acpi_ev || hotkey_report_mode < 2)) { 1280 acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey); 1281 } 1282 1283 /* netlink events */ 1284 if (!ignore_acpi_ev && send_acpi_ev) { 1285 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, 1286 ibm->acpi->device->dev.bus_id, 1287 event, hkey); 1288 } 1289 } 1290} 1291 1292static void hotkey_resume(void) 1293{ 1294 tpacpi_input_send_radiosw(); 1295} 1296 1297/* 1298 * Call with hotkey_mutex held 1299 */ 1300static int hotkey_get(int *status, u32 *mask) 1301{ 1302 if (!acpi_evalf(hkey_handle, status, "DHKC", "d")) 1303 return -EIO; 1304 1305 if (tp_features.hotkey_mask) 1306 if (!acpi_evalf(hkey_handle, mask, "DHKN", "d")) 1307 return -EIO; 1308 1309 return 0; 1310} 1311 1312/* 1313 * Call with hotkey_mutex held 1314 */ 1315static int hotkey_set(int status, u32 mask) 1316{ 1317 int i; 1318 1319 if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status)) 1320 return -EIO; 1321 1322 if (tp_features.hotkey_mask) 1323 for (i = 0; i < 32; i++) { 1324 int bit = ((1 << i) & mask) != 0; 1325 if (!acpi_evalf(hkey_handle, 1326 NULL, "MHKM", "vdd", i + 1, bit)) 1327 return -EIO; 1328 } 1329 1330 return 0; 1331} 1332 1333/* procfs -------------------------------------------------------------- */ 1334static int hotkey_read(char *p) 1335{ 1336 int res, status; 1337 u32 mask; 1338 int len = 0; 1339 1340 if (!tp_features.hotkey) { 1341 len += sprintf(p + len, "status:\t\tnot supported\n"); 1342 return len; 1343 } 1344 1345 if (mutex_lock_interruptible(&hotkey_mutex)) 1346 return -ERESTARTSYS; 1347 res = hotkey_get(&status, &mask); 1348 mutex_unlock(&hotkey_mutex); 1349 if (res) 1350 return res; 1351 1352 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); 1353 if (tp_features.hotkey_mask) { 1354 len += sprintf(p + len, "mask:\t\t0x%08x\n", mask); 1355 len += sprintf(p + len, 1356 "commands:\tenable, disable, reset, <mask>\n"); 1357 } else { 1358 len += sprintf(p + len, "mask:\t\tnot supported\n"); 1359 len += sprintf(p + len, "commands:\tenable, disable, reset\n"); 1360 } 1361 1362 return len; 1363} 1364 1365static int hotkey_write(char *buf) 1366{ 1367 int res, status; 1368 u32 mask; 1369 char *cmd; 1370 int do_cmd = 0; 1371 1372 if (!tp_features.hotkey) 1373 return -ENODEV; 1374 1375 if (mutex_lock_interruptible(&hotkey_mutex)) 1376 return -ERESTARTSYS; 1377 1378 res = hotkey_get(&status, &mask); 1379 if (res) 1380 goto errexit; 1381 1382 res = 0; 1383 while ((cmd = next_cmd(&buf))) { 1384 if (strlencmp(cmd, "enable") == 0) { 1385 status = 1; 1386 } else if (strlencmp(cmd, "disable") == 0) { 1387 status = 0; 1388 } else if (strlencmp(cmd, "reset") == 0) { 1389 status = hotkey_orig_status; 1390 mask = hotkey_orig_mask; 1391 } else if (sscanf(cmd, "0x%x", &mask) == 1) { 1392 /* mask set */ 1393 } else if (sscanf(cmd, "%x", &mask) == 1) { 1394 /* mask set */ 1395 } else { 1396 res = -EINVAL; 1397 goto errexit; 1398 } 1399 do_cmd = 1; 1400 } 1401 1402 if (do_cmd) 1403 res = hotkey_set(status, mask); 1404 1405errexit: 1406 mutex_unlock(&hotkey_mutex); 1407 return res; 1408} 1409 1410static const struct acpi_device_id ibm_htk_device_ids[] = { 1411 {IBM_HKEY_HID, 0}, 1412 {"", 0}, 1413}; 1414 1415static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = { 1416 .hid = ibm_htk_device_ids, 1417 .notify = hotkey_notify, 1418 .handle = &hkey_handle, 1419 .type = ACPI_DEVICE_NOTIFY, 1420}; 1421 1422static struct ibm_struct hotkey_driver_data = { 1423 .name = "hotkey", 1424 .read = hotkey_read, 1425 .write = hotkey_write, 1426 .exit = hotkey_exit, 1427 .resume = hotkey_resume, 1428 .acpi = &ibm_hotkey_acpidriver, 1429}; 1430 1431/************************************************************************* 1432 * Bluetooth subdriver 1433 */ 1434 1435/* sysfs bluetooth enable ---------------------------------------------- */ 1436static ssize_t bluetooth_enable_show(struct device *dev, 1437 struct device_attribute *attr, 1438 char *buf) 1439{ 1440 int status; 1441 1442 status = bluetooth_get_radiosw(); 1443 if (status < 0) 1444 return status; 1445 1446 return snprintf(buf, PAGE_SIZE, "%d\n", status ? 1 : 0); 1447} 1448 1449static ssize_t bluetooth_enable_store(struct device *dev, 1450 struct device_attribute *attr, 1451 const char *buf, size_t count) 1452{ 1453 unsigned long t; 1454 int res; 1455 1456 if (parse_strtoul(buf, 1, &t)) 1457 return -EINVAL; 1458 1459 res = bluetooth_set_radiosw(t); 1460 1461 return (res) ? res : count; 1462} 1463 1464static struct device_attribute dev_attr_bluetooth_enable = 1465 __ATTR(bluetooth_enable, S_IWUSR | S_IRUGO, 1466 bluetooth_enable_show, bluetooth_enable_store); 1467 1468/* --------------------------------------------------------------------- */ 1469 1470static struct attribute *bluetooth_attributes[] = { 1471 &dev_attr_bluetooth_enable.attr, 1472 NULL 1473}; 1474 1475static const struct attribute_group bluetooth_attr_group = { 1476 .attrs = bluetooth_attributes, 1477}; 1478 1479static int __init bluetooth_init(struct ibm_init_struct *iibm) 1480{ 1481 int res; 1482 int status = 0; 1483 1484 vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n"); 1485 1486 IBM_ACPIHANDLE_INIT(hkey); 1487 1488 /* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 1489 G4x, R30, R31, R40e, R50e, T20-22, X20-21 */ 1490 tp_features.bluetooth = hkey_handle && 1491 acpi_evalf(hkey_handle, &status, "GBDC", "qd"); 1492 1493 vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n", 1494 str_supported(tp_features.bluetooth), 1495 status); 1496 1497 if (tp_features.bluetooth) { 1498 if (!(status & TP_ACPI_BLUETOOTH_HWPRESENT)) { 1499 /* no bluetooth hardware present in system */ 1500 tp_features.bluetooth = 0; 1501 dbg_printk(TPACPI_DBG_INIT, 1502 "bluetooth hardware not installed\n"); 1503 } else { 1504 res = sysfs_create_group(&tpacpi_pdev->dev.kobj, 1505 &bluetooth_attr_group); 1506 if (res) 1507 return res; 1508 } 1509 } 1510 1511 return (tp_features.bluetooth)? 0 : 1; 1512} 1513 1514static void bluetooth_exit(void) 1515{ 1516 sysfs_remove_group(&tpacpi_pdev->dev.kobj, 1517 &bluetooth_attr_group); 1518} 1519 1520static int bluetooth_get_radiosw(void) 1521{ 1522 int status; 1523 1524 if (!tp_features.bluetooth) 1525 return -ENODEV; 1526 1527 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) 1528 return -EIO; 1529 1530 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0); 1531} 1532 1533static int bluetooth_set_radiosw(int radio_on) 1534{ 1535 int status; 1536 1537 if (!tp_features.bluetooth) 1538 return -ENODEV; 1539 1540 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) 1541 return -EIO; 1542 if (radio_on) 1543 status |= TP_ACPI_BLUETOOTH_RADIOSSW; 1544 else 1545 status &= ~TP_ACPI_BLUETOOTH_RADIOSSW; 1546 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) 1547 return -EIO; 1548 1549 return 0; 1550} 1551 1552/* procfs -------------------------------------------------------------- */ 1553static int bluetooth_read(char *p) 1554{ 1555 int len = 0; 1556 int status = bluetooth_get_radiosw(); 1557 1558 if (!tp_features.bluetooth) 1559 len += sprintf(p + len, "status:\t\tnot supported\n"); 1560 else { 1561 len += sprintf(p + len, "status:\t\t%s\n", 1562 (status)? "enabled" : "disabled"); 1563 len += sprintf(p + len, "commands:\tenable, disable\n"); 1564 } 1565 1566 return len; 1567} 1568 1569static int bluetooth_write(char *buf) 1570{ 1571 char *cmd; 1572 1573 if (!tp_features.bluetooth) 1574 return -ENODEV; 1575 1576 while ((cmd = next_cmd(&buf))) { 1577 if (strlencmp(cmd, "enable") == 0) { 1578 bluetooth_set_radiosw(1); 1579 } else if (strlencmp(cmd, "disable") == 0) { 1580 bluetooth_set_radiosw(0); 1581 } else 1582 return -EINVAL; 1583 } 1584 1585 return 0; 1586} 1587 1588static struct ibm_struct bluetooth_driver_data = { 1589 .name = "bluetooth", 1590 .read = bluetooth_read, 1591 .write = bluetooth_write, 1592 .exit = bluetooth_exit, 1593}; 1594 1595/************************************************************************* 1596 * Wan subdriver 1597 */ 1598 1599/* sysfs wan enable ---------------------------------------------------- */ 1600static ssize_t wan_enable_show(struct device *dev, 1601 struct device_attribute *attr, 1602 char *buf) 1603{ 1604 int status; 1605 1606 status = wan_get_radiosw(); 1607 if (status < 0) 1608 return status; 1609 1610 return snprintf(buf, PAGE_SIZE, "%d\n", status ? 1 : 0); 1611} 1612 1613static ssize_t wan_enable_store(struct device *dev, 1614 struct device_attribute *attr, 1615 const char *buf, size_t count) 1616{ 1617 unsigned long t; 1618 int res; 1619 1620 if (parse_strtoul(buf, 1, &t)) 1621 return -EINVAL; 1622 1623 res = wan_set_radiosw(t); 1624 1625 return (res) ? res : count; 1626} 1627 1628static struct device_attribute dev_attr_wan_enable = 1629 __ATTR(wwan_enable, S_IWUSR | S_IRUGO, 1630 wan_enable_show, wan_enable_store); 1631 1632/* --------------------------------------------------------------------- */ 1633 1634static struct attribute *wan_attributes[] = { 1635 &dev_attr_wan_enable.attr, 1636 NULL 1637}; 1638 1639static const struct attribute_group wan_attr_group = { 1640 .attrs = wan_attributes, 1641}; 1642 1643static int __init wan_init(struct ibm_init_struct *iibm) 1644{ 1645 int res; 1646 int status = 0; 1647 1648 vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n"); 1649 1650 IBM_ACPIHANDLE_INIT(hkey); 1651 1652 tp_features.wan = hkey_handle && 1653 acpi_evalf(hkey_handle, &status, "GWAN", "qd"); 1654 1655 vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n", 1656 str_supported(tp_features.wan), 1657 status); 1658 1659 if (tp_features.wan) { 1660 if (!(status & TP_ACPI_WANCARD_HWPRESENT)) { 1661 /* no wan hardware present in system */ 1662 tp_features.wan = 0; 1663 dbg_printk(TPACPI_DBG_INIT, 1664 "wan hardware not installed\n"); 1665 } else { 1666 res = sysfs_create_group(&tpacpi_pdev->dev.kobj, 1667 &wan_attr_group); 1668 if (res) 1669 return res; 1670 } 1671 } 1672 1673 return (tp_features.wan)? 0 : 1; 1674} 1675 1676static void wan_exit(void) 1677{ 1678 sysfs_remove_group(&tpacpi_pdev->dev.kobj, 1679 &wan_attr_group); 1680} 1681 1682static int wan_get_radiosw(void) 1683{ 1684 int status; 1685 1686 if (!tp_features.wan) 1687 return -ENODEV; 1688 1689 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) 1690 return -EIO; 1691 1692 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0); 1693} 1694 1695static int wan_set_radiosw(int radio_on) 1696{ 1697 int status; 1698 1699 if (!tp_features.wan) 1700 return -ENODEV; 1701 1702 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) 1703 return -EIO; 1704 if (radio_on) 1705 status |= TP_ACPI_WANCARD_RADIOSSW; 1706 else 1707 status &= ~TP_ACPI_WANCARD_RADIOSSW; 1708 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) 1709 return -EIO; 1710 1711 return 0; 1712} 1713 1714/* procfs -------------------------------------------------------------- */ 1715static int wan_read(char *p) 1716{ 1717 int len = 0; 1718 int status = wan_get_radiosw(); 1719 1720 if (!tp_features.wan) 1721 len += sprintf(p + len, "status:\t\tnot supported\n"); 1722 else { 1723 len += sprintf(p + len, "status:\t\t%s\n", 1724 (status)? "enabled" : "disabled"); 1725 len += sprintf(p + len, "commands:\tenable, disable\n"); 1726 } 1727 1728 return len; 1729} 1730 1731static int wan_write(char *buf) 1732{ 1733 char *cmd; 1734 1735 if (!tp_features.wan) 1736 return -ENODEV; 1737 1738 while ((cmd = next_cmd(&buf))) { 1739 if (strlencmp(cmd, "enable") == 0) { 1740 wan_set_radiosw(1); 1741 } else if (strlencmp(cmd, "disable") == 0) { 1742 wan_set_radiosw(0); 1743 } else 1744 return -EINVAL; 1745 } 1746 1747 return 0; 1748} 1749 1750static struct ibm_struct wan_driver_data = { 1751 .name = "wan", 1752 .read = wan_read, 1753 .write = wan_write, 1754 .exit = wan_exit, 1755 .flags.experimental = 1, 1756}; 1757 1758/************************************************************************* 1759 * Video subdriver 1760 */ 1761 1762static enum video_access_mode video_supported; 1763static int video_orig_autosw; 1764 1765IBM_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */ 1766 "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */ 1767 "\\_SB.PCI0.VID0", /* 770e */ 1768 "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */ 1769 "\\_SB.PCI0.AGP.VID", /* all others */ 1770 ); /* R30, R31 */ 1771 1772IBM_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID"); /* G41 */ 1773 1774static int __init video_init(struct ibm_init_struct *iibm) 1775{ 1776 int ivga; 1777 1778 vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n"); 1779 1780 IBM_ACPIHANDLE_INIT(vid); 1781 IBM_ACPIHANDLE_INIT(vid2); 1782 1783 if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga) 1784 /* G41, assume IVGA doesn't change */ 1785 vid_handle = vid2_handle; 1786 1787 if (!vid_handle) 1788 /* video switching not supported on R30, R31 */ 1789 video_supported = TPACPI_VIDEO_NONE; 1790 else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd")) 1791 /* 570 */ 1792 video_supported = TPACPI_VIDEO_570; 1793 else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd")) 1794 /* 600e/x, 770e, 770x */ 1795 video_supported = TPACPI_VIDEO_770; 1796 else 1797 /* all others */ 1798 video_supported = TPACPI_VIDEO_NEW; 1799 1800 vdbg_printk(TPACPI_DBG_INIT, "video is %s, mode %d\n", 1801 str_supported(video_supported != TPACPI_VIDEO_NONE), 1802 video_supported); 1803 1804 return (video_supported != TPACPI_VIDEO_NONE)? 0 : 1; 1805} 1806 1807static void video_exit(void) 1808{ 1809 dbg_printk(TPACPI_DBG_EXIT, 1810 "restoring original video autoswitch mode\n"); 1811 if (video_autosw_set(video_orig_autosw)) 1812 printk(IBM_ERR "error while trying to restore original " 1813 "video autoswitch mode\n"); 1814} 1815 1816static int video_outputsw_get(void) 1817{ 1818 int status = 0; 1819 int i; 1820 1821 switch (video_supported) { 1822 case TPACPI_VIDEO_570: 1823 if (!acpi_evalf(NULL, &i, "\\_SB.PHS", "dd", 1824 TP_ACPI_VIDEO_570_PHSCMD)) 1825 return -EIO; 1826 status = i & TP_ACPI_VIDEO_570_PHSMASK; 1827 break; 1828 case TPACPI_VIDEO_770: 1829 if (!acpi_evalf(NULL, &i, "\\VCDL", "d")) 1830 return -EIO; 1831 if (i) 1832 status |= TP_ACPI_VIDEO_S_LCD; 1833 if (!acpi_evalf(NULL, &i, "\\VCDC", "d")) 1834 return -EIO; 1835 if (i) 1836 status |= TP_ACPI_VIDEO_S_CRT; 1837 break; 1838 case TPACPI_VIDEO_NEW: 1839 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1) || 1840 !acpi_evalf(NULL, &i, "\\VCDC", "d")) 1841 return -EIO; 1842 if (i) 1843 status |= TP_ACPI_VIDEO_S_CRT; 1844 1845 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0) || 1846 !acpi_evalf(NULL, &i, "\\VCDL", "d")) 1847 return -EIO; 1848 if (i) 1849 status |= TP_ACPI_VIDEO_S_LCD; 1850 if (!acpi_evalf(NULL, &i, "\\VCDD", "d")) 1851 return -EIO; 1852 if (i) 1853 status |= TP_ACPI_VIDEO_S_DVI; 1854 break; 1855 default: 1856 return -ENOSYS; 1857 } 1858 1859 return status; 1860} 1861 1862static int video_outputsw_set(int status) 1863{ 1864 int autosw; 1865 int res = 0; 1866 1867 switch (video_supported) { 1868 case TPACPI_VIDEO_570: 1869 res = acpi_evalf(NULL, NULL, 1870 "\\_SB.PHS2", "vdd", 1871 TP_ACPI_VIDEO_570_PHS2CMD, 1872 status | TP_ACPI_VIDEO_570_PHS2SET); 1873 break; 1874 case TPACPI_VIDEO_770: 1875 autosw = video_autosw_get(); 1876 if (autosw < 0) 1877 return autosw; 1878 1879 res = video_autosw_set(1); 1880 if (res) 1881 return res; 1882 res = acpi_evalf(vid_handle, NULL, 1883 "ASWT", "vdd", status * 0x100, 0); 1884 if (!autosw && video_autosw_set(autosw)) { 1885 printk(IBM_ERR "video auto-switch left enabled due to error\n"); 1886 return -EIO; 1887 } 1888 break; 1889 case TPACPI_VIDEO_NEW: 1890 res = acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80) && 1891 acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1); 1892 break; 1893 default: 1894 return -ENOSYS; 1895 } 1896 1897 return (res)? 0 : -EIO; 1898} 1899 1900static int video_autosw_get(void) 1901{ 1902 int autosw = 0; 1903 1904 switch (video_supported) { 1905 case TPACPI_VIDEO_570: 1906 if (!acpi_evalf(vid_handle, &autosw, "SWIT", "d")) 1907 return -EIO; 1908 break; 1909 case TPACPI_VIDEO_770: 1910 case TPACPI_VIDEO_NEW: 1911 if (!acpi_evalf(vid_handle, &autosw, "^VDEE", "d")) 1912 return -EIO; 1913 break; 1914 default: 1915 return -ENOSYS; 1916 } 1917 1918 return autosw & 1; 1919} 1920 1921static int video_autosw_set(int enable) 1922{ 1923 if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", (enable)? 1 : 0)) 1924 return -EIO; 1925 return 0; 1926} 1927 1928static int video_outputsw_cycle(void) 1929{ 1930 int autosw = video_autosw_get(); 1931 int res; 1932 1933 if (autosw < 0) 1934 return autosw; 1935 1936 switch (video_supported) { 1937 case TPACPI_VIDEO_570: 1938 res = video_autosw_set(1); 1939 if (res) 1940 return res; 1941 res = acpi_evalf(ec_handle, NULL, "_Q16", "v"); 1942 break; 1943 case TPACPI_VIDEO_770: 1944 case TPACPI_VIDEO_NEW: 1945 res = video_autosw_set(1); 1946 if (res) 1947 return res; 1948 res = acpi_evalf(vid_handle, NULL, "VSWT", "v"); 1949 break; 1950 default: 1951 return -ENOSYS; 1952 } 1953 if (!autosw && video_autosw_set(autosw)) { 1954 printk(IBM_ERR "video auto-switch left enabled due to error\n"); 1955 return -EIO; 1956 } 1957 1958 return (res)? 0 : -EIO; 1959} 1960 1961static int video_expand_toggle(void) 1962{ 1963 switch (video_supported) { 1964 case TPACPI_VIDEO_570: 1965 return acpi_evalf(ec_handle, NULL, "_Q17", "v")? 1966 0 : -EIO; 1967 case TPACPI_VIDEO_770: 1968 return acpi_evalf(vid_handle, NULL, "VEXP", "v")? 1969 0 : -EIO; 1970 case TPACPI_VIDEO_NEW: 1971 return acpi_evalf(NULL, NULL, "\\VEXP", "v")? 1972 0 : -EIO; 1973 default: 1974 return -ENOSYS; 1975 } 1976 /* not reached */ 1977} 1978 1979static int video_read(char *p) 1980{ 1981 int status, autosw; 1982 int len = 0; 1983 1984 if (video_supported == TPACPI_VIDEO_NONE) { 1985 len += sprintf(p + len, "status:\t\tnot supported\n"); 1986 return len; 1987 } 1988 1989 status = video_outputsw_get(); 1990 if (status < 0) 1991 return status; 1992 1993 autosw = video_autosw_get(); 1994 if (autosw < 0) 1995 return autosw; 1996 1997 len += sprintf(p + len, "status:\t\tsupported\n"); 1998 len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0)); 1999 len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1)); 2000 if (video_supported == TPACPI_VIDEO_NEW) 2001 len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3)); 2002 len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0)); 2003 len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n"); 2004 len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n"); 2005 if (video_supported == TPACPI_VIDEO_NEW) 2006 len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n"); 2007 len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n"); 2008 len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n"); 2009 2010 return len; 2011} 2012 2013static int video_write(char *buf) 2014{ 2015 char *cmd; 2016 int enable, disable, status; 2017 int res; 2018 2019 if (video_supported == TPACPI_VIDEO_NONE) 2020 return -ENODEV; 2021 2022 enable = 0; 2023 disable = 0; 2024 2025 while ((cmd = next_cmd(&buf))) { 2026 if (strlencmp(cmd, "lcd_enable") == 0) { 2027 enable |= TP_ACPI_VIDEO_S_LCD; 2028 } else if (strlencmp(cmd, "lcd_disable") == 0) { 2029 disable |= TP_ACPI_VIDEO_S_LCD; 2030 } else if (strlencmp(cmd, "crt_enable") == 0) { 2031 enable |= TP_ACPI_VIDEO_S_CRT; 2032 } else if (strlencmp(cmd, "crt_disable") == 0) { 2033 disable |= TP_ACPI_VIDEO_S_CRT; 2034 } else if (video_supported == TPACPI_VIDEO_NEW && 2035 strlencmp(cmd, "dvi_enable") == 0) { 2036 enable |= TP_ACPI_VIDEO_S_DVI; 2037 } else if (video_supported == TPACPI_VIDEO_NEW && 2038 strlencmp(cmd, "dvi_disable") == 0) { 2039 disable |= TP_ACPI_VIDEO_S_DVI; 2040 } else if (strlencmp(cmd, "auto_enable") == 0) { 2041 res = video_autosw_set(1); 2042 if (res) 2043 return res; 2044 } else if (strlencmp(cmd, "auto_disable") == 0) { 2045 res = video_autosw_set(0); 2046 if (res) 2047 return res; 2048 } else if (strlencmp(cmd, "video_switch") == 0) { 2049 res = video_outputsw_cycle(); 2050 if (res) 2051 return res; 2052 } else if (strlencmp(cmd, "expand_toggle") == 0) { 2053 res = video_expand_toggle(); 2054 if (res) 2055 return res; 2056 } else 2057 return -EINVAL; 2058 } 2059 2060 if (enable || disable) { 2061 status = video_outputsw_get(); 2062 if (status < 0) 2063 return status; 2064 res = video_outputsw_set((status & ~disable) | enable); 2065 if (res) 2066 return res; 2067 } 2068 2069 return 0; 2070} 2071 2072static struct ibm_struct video_driver_data = { 2073 .name = "video", 2074 .read = video_read, 2075 .write = video_write, 2076 .exit = video_exit, 2077}; 2078 2079/************************************************************************* 2080 * Light (thinklight) subdriver 2081 */ 2082 2083IBM_HANDLE(lght, root, "\\LGHT"); /* A21e, A2xm/p, T20-22, X20-21 */ 2084IBM_HANDLE(ledb, ec, "LEDB"); /* G4x */ 2085 2086static int __init light_init(struct ibm_init_struct *iibm) 2087{ 2088 vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n"); 2089 2090 IBM_ACPIHANDLE_INIT(ledb); 2091 IBM_ACPIHANDLE_INIT(lght); 2092 IBM_ACPIHANDLE_INIT(cmos); 2093 2094 /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */ 2095 tp_features.light = (cmos_handle || lght_handle) && !ledb_handle; 2096 2097 if (tp_features.light) 2098 /* light status not supported on 2099 570, 600e/x, 770e, 770x, G4x, R30, R31, R32, X20 */ 2100 tp_features.light_status = 2101 acpi_evalf(ec_handle, NULL, "KBLT", "qv"); 2102 2103 vdbg_printk(TPACPI_DBG_INIT, "light is %s\n", 2104 str_supported(tp_features.light)); 2105 2106 return (tp_features.light)? 0 : 1; 2107} 2108 2109static int light_read(char *p) 2110{ 2111 int len = 0; 2112 int status = 0; 2113 2114 if (!tp_features.light) { 2115 len += sprintf(p + len, "status:\t\tnot supported\n"); 2116 } else if (!tp_features.light_status) { 2117 len += sprintf(p + len, "status:\t\tunknown\n"); 2118 len += sprintf(p + len, "commands:\ton, off\n"); 2119 } else { 2120 if (!acpi_evalf(ec_handle, &status, "KBLT", "d")) 2121 return -EIO; 2122 len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0)); 2123 len += sprintf(p + len, "commands:\ton, off\n"); 2124 } 2125 2126 return len; 2127} 2128 2129static int light_write(char *buf) 2130{ 2131 int cmos_cmd, lght_cmd; 2132 char *cmd; 2133 int success; 2134 2135 if (!tp_features.light) 2136 return -ENODEV; 2137 2138 while ((cmd = next_cmd(&buf))) { 2139 if (strlencmp(cmd, "on") == 0) { 2140 cmos_cmd = 0x0c; 2141 lght_cmd = 1; 2142 } else if (strlencmp(cmd, "off") == 0) { 2143 cmos_cmd = 0x0d; 2144 lght_cmd = 0; 2145 } else 2146 return -EINVAL; 2147 2148 success = cmos_handle ? 2149 acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd) : 2150 acpi_evalf(lght_handle, NULL, NULL, "vd", lght_cmd); 2151 if (!success) 2152 return -EIO; 2153 } 2154 2155 return 0; 2156} 2157 2158static struct ibm_struct light_driver_data = { 2159 .name = "light", 2160 .read = light_read, 2161 .write = light_write, 2162}; 2163 2164/************************************************************************* 2165 * Dock subdriver 2166 */ 2167 2168#ifdef CONFIG_THINKPAD_ACPI_DOCK 2169 2170IBM_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */ 2171 "\\_SB.PCI0.DOCK", /* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */ 2172 "\\_SB.PCI0.PCI1.DOCK", /* all others */ 2173 "\\_SB.PCI.ISA.SLCE", /* 570 */ 2174 ); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */ 2175 2176/* don't list other alternatives as we install a notify handler on the 570 */ 2177IBM_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */ 2178 2179static const struct acpi_device_id ibm_pci_device_ids[] = { 2180 {PCI_ROOT_HID_STRING, 0}, 2181 {"", 0}, 2182}; 2183 2184static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = { 2185 { 2186 .notify = dock_notify, 2187 .handle = &dock_handle, 2188 .type = ACPI_SYSTEM_NOTIFY, 2189 }, 2190 { 2191 /* THIS ONE MUST NEVER BE USED FOR DRIVER AUTOLOADING. 2192 * We just use it to get notifications of dock hotplug 2193 * in very old thinkpads */ 2194 .hid = ibm_pci_device_ids, 2195 .notify = dock_notify, 2196 .handle = &pci_handle, 2197 .type = ACPI_SYSTEM_NOTIFY, 2198 }, 2199}; 2200 2201static struct ibm_struct dock_driver_data[2] = { 2202 { 2203 .name = "dock", 2204 .read = dock_read, 2205 .write = dock_write, 2206 .acpi = &ibm_dock_acpidriver[0], 2207 }, 2208 { 2209 .name = "dock", 2210 .acpi = &ibm_dock_acpidriver[1], 2211 }, 2212}; 2213 2214#define dock_docked() (_sta(dock_handle) & 1) 2215 2216static int __init dock_init(struct ibm_init_struct *iibm) 2217{ 2218 vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver\n"); 2219 2220 IBM_ACPIHANDLE_INIT(dock); 2221 2222 vdbg_printk(TPACPI_DBG_INIT, "dock is %s\n", 2223 str_supported(dock_handle != NULL)); 2224 2225 return (dock_handle)? 0 : 1; 2226} 2227 2228static int __init dock_init2(struct ibm_init_struct *iibm) 2229{ 2230 int dock2_needed; 2231 2232 vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver part 2\n"); 2233 2234 if (dock_driver_data[0].flags.acpi_driver_registered && 2235 dock_driver_data[0].flags.acpi_notify_installed) { 2236 IBM_ACPIHANDLE_INIT(pci); 2237 dock2_needed = (pci_handle != NULL); 2238 vdbg_printk(TPACPI_DBG_INIT, 2239 "dock PCI handler for the TP 570 is %s\n", 2240 str_supported(dock2_needed)); 2241 } else { 2242 vdbg_printk(TPACPI_DBG_INIT, 2243 "dock subdriver part 2 not required\n"); 2244 dock2_needed = 0; 2245 } 2246 2247 return (dock2_needed)? 0 : 1; 2248} 2249 2250static void dock_notify(struct ibm_struct *ibm, u32 event) 2251{ 2252 int docked = dock_docked(); 2253 int pci = ibm->acpi->hid && ibm->acpi->device && 2254 acpi_match_device_ids(ibm->acpi->device, ibm_pci_device_ids); 2255 int data; 2256 2257 if (event == 1 && !pci) /* 570 */ 2258 data = 1; /* button */ 2259 else if (event == 1 && pci) /* 570 */ 2260 data = 3; /* dock */ 2261 else if (event == 3 && docked) 2262 data = 1; /* button */ 2263 else if (event == 3 && !docked) 2264 data = 2; /* undock */ 2265 else if (event == 0 && docked) 2266 data = 3; /* dock */ 2267 else { 2268 printk(IBM_ERR "unknown dock event %d, status %d\n", 2269 event, _sta(dock_handle)); 2270 data = 0; /* unknown */ 2271 } 2272 acpi_bus_generate_proc_event(ibm->acpi->device, event, data); 2273 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, 2274 ibm->acpi->device->dev.bus_id, 2275 event, data); 2276} 2277 2278static int dock_read(char *p) 2279{ 2280 int len = 0; 2281 int docked = dock_docked(); 2282 2283 if (!dock_handle) 2284 len += sprintf(p + len, "status:\t\tnot supported\n"); 2285 else if (!docked) 2286 len += sprintf(p + len, "status:\t\tundocked\n"); 2287 else { 2288 len += sprintf(p + len, "status:\t\tdocked\n"); 2289 len += sprintf(p + len, "commands:\tdock, undock\n"); 2290 } 2291 2292 return len; 2293} 2294 2295static int dock_write(char *buf) 2296{ 2297 char *cmd; 2298 2299 if (!dock_docked()) 2300 return -ENODEV; 2301 2302 while ((cmd = next_cmd(&buf))) { 2303 if (strlencmp(cmd, "undock") == 0) { 2304 if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 0) || 2305 !acpi_evalf(dock_handle, NULL, "_EJ0", "vd", 1)) 2306 return -EIO; 2307 } else if (strlencmp(cmd, "dock") == 0) { 2308 if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 1)) 2309 return -EIO; 2310 } else 2311 return -EINVAL; 2312 } 2313 2314 return 0; 2315} 2316 2317#endif /* CONFIG_THINKPAD_ACPI_DOCK */ 2318 2319/************************************************************************* 2320 * Bay subdriver 2321 */ 2322 2323#ifdef CONFIG_THINKPAD_ACPI_BAY 2324IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */ 2325 "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */ 2326 "\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */ 2327 "\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */ 2328 ); /* A21e, R30, R31 */ 2329IBM_HANDLE(bay_ej, bay, "_EJ3", /* 600e/x, A2xm/p, A3x */ 2330 "_EJ0", /* all others */ 2331 ); /* 570,A21e,G4x,R30,R31,R32,R40e,R50e */ 2332IBM_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV", /* A3x, R32 */ 2333 "\\_SB.PCI0.IDE0.IDEP.IDPS", /* 600e/x, 770e, 770x */ 2334 ); /* all others */ 2335IBM_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */ 2336 "_EJ0", /* 770x */ 2337 ); /* all others */ 2338 2339static int __init bay_init(struct ibm_init_struct *iibm) 2340{ 2341 vdbg_printk(TPACPI_DBG_INIT, "initializing bay subdriver\n"); 2342 2343 IBM_ACPIHANDLE_INIT(bay); 2344 if (bay_handle) 2345 IBM_ACPIHANDLE_INIT(bay_ej); 2346 IBM_ACPIHANDLE_INIT(bay2); 2347 if (bay2_handle) 2348 IBM_ACPIHANDLE_INIT(bay2_ej); 2349 2350 tp_features.bay_status = bay_handle && 2351 acpi_evalf(bay_handle, NULL, "_STA", "qv"); 2352 tp_features.bay_status2 = bay2_handle && 2353 acpi_evalf(bay2_handle, NULL, "_STA", "qv"); 2354 2355 tp_features.bay_eject = bay_handle && bay_ej_handle && 2356 (strlencmp(bay_ej_path, "_EJ0") == 0 || experimental); 2357 tp_features.bay_eject2 = bay2_handle && bay2_ej_handle && 2358 (strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental); 2359 2360 vdbg_printk(TPACPI_DBG_INIT, 2361 "bay 1: status %s, eject %s; bay 2: status %s, eject %s\n", 2362 str_supported(tp_features.bay_status), 2363 str_supported(tp_features.bay_eject), 2364 str_supported(tp_features.bay_status2), 2365 str_supported(tp_features.bay_eject2)); 2366 2367 return (tp_features.bay_status || tp_features.bay_eject || 2368 tp_features.bay_status2 || tp_features.bay_eject2)? 0 : 1; 2369} 2370 2371static void bay_notify(struct ibm_struct *ibm, u32 event) 2372{ 2373 acpi_bus_generate_proc_event(ibm->acpi->device, event, 0); 2374 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, 2375 ibm->acpi->device->dev.bus_id, 2376 event, 0); 2377} 2378 2379#define bay_occupied(b) (_sta(b##_handle) & 1) 2380 2381static int bay_read(char *p) 2382{ 2383 int len = 0; 2384 int occupied = bay_occupied(bay); 2385 int occupied2 = bay_occupied(bay2); 2386 int eject, eject2; 2387 2388 len += sprintf(p + len, "status:\t\t%s\n", 2389 tp_features.bay_status ? 2390 (occupied ? "occupied" : "unoccupied") : 2391 "not supported"); 2392 if (tp_features.bay_status2) 2393 len += sprintf(p + len, "status2:\t%s\n", occupied2 ? 2394 "occupied" : "unoccupied"); 2395 2396 eject = tp_features.bay_eject && occupied; 2397 eject2 = tp_features.bay_eject2 && occupied2; 2398 2399 if (eject && eject2) 2400 len += sprintf(p + len, "commands:\teject, eject2\n"); 2401 else if (eject) 2402 len += sprintf(p + len, "commands:\teject\n"); 2403 else if (eject2) 2404 len += sprintf(p + len, "commands:\teject2\n"); 2405 2406 return len; 2407} 2408 2409static int bay_write(char *buf) 2410{ 2411 char *cmd; 2412 2413 if (!tp_features.bay_eject && !tp_features.bay_eject2) 2414 return -ENODEV; 2415 2416 while ((cmd = next_cmd(&buf))) { 2417 if (tp_features.bay_eject && strlencmp(cmd, "eject") == 0) { 2418 if (!acpi_evalf(bay_ej_handle, NULL, NULL, "vd", 1)) 2419 return -EIO; 2420 } else if (tp_features.bay_eject2 && 2421 strlencmp(cmd, "eject2") == 0) { 2422 if (!acpi_evalf(bay2_ej_handle, NULL, NULL, "vd", 1)) 2423 return -EIO; 2424 } else 2425 return -EINVAL; 2426 } 2427 2428 return 0; 2429} 2430 2431static struct tp_acpi_drv_struct ibm_bay_acpidriver = { 2432 .notify = bay_notify, 2433 .handle = &bay_handle, 2434 .type = ACPI_SYSTEM_NOTIFY, 2435}; 2436 2437static struct ibm_struct bay_driver_data = { 2438 .name = "bay", 2439 .read = bay_read, 2440 .write = bay_write, 2441 .acpi = &ibm_bay_acpidriver, 2442}; 2443 2444#endif /* CONFIG_THINKPAD_ACPI_BAY */ 2445 2446/************************************************************************* 2447 * CMOS subdriver 2448 */ 2449 2450/* sysfs cmos_command -------------------------------------------------- */ 2451static ssize_t cmos_command_store(struct device *dev, 2452 struct device_attribute *attr, 2453 const char *buf, size_t count) 2454{ 2455 unsigned long cmos_cmd; 2456 int res; 2457 2458 if (parse_strtoul(buf, 21, &cmos_cmd)) 2459 return -EINVAL; 2460 2461 res = issue_thinkpad_cmos_command(cmos_cmd); 2462 return (res)? res : count; 2463} 2464 2465static struct device_attribute dev_attr_cmos_command = 2466 __ATTR(cmos_command, S_IWUSR, NULL, cmos_command_store); 2467 2468/* --------------------------------------------------------------------- */ 2469 2470static int __init cmos_init(struct ibm_init_struct *iibm) 2471{ 2472 int res; 2473 2474 vdbg_printk(TPACPI_DBG_INIT, 2475 "initializing cmos commands subdriver\n"); 2476 2477 IBM_ACPIHANDLE_INIT(cmos); 2478 2479 vdbg_printk(TPACPI_DBG_INIT, "cmos commands are %s\n", 2480 str_supported(cmos_handle != NULL)); 2481 2482 res = device_create_file(&tpacpi_pdev->dev, &dev_attr_cmos_command); 2483 if (res) 2484 return res; 2485 2486 return (cmos_handle)? 0 : 1; 2487} 2488 2489static void cmos_exit(void) 2490{ 2491 device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command); 2492} 2493 2494static int cmos_read(char *p) 2495{ 2496 int len = 0; 2497 2498 /* cmos not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 2499 R30, R31, T20-22, X20-21 */ 2500 if (!cmos_handle) 2501 len += sprintf(p + len, "status:\t\tnot supported\n"); 2502 else { 2503 len += sprintf(p + len, "status:\t\tsupported\n"); 2504 len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-21)\n"); 2505 } 2506 2507 return len; 2508} 2509 2510static int cmos_write(char *buf) 2511{ 2512 char *cmd; 2513 int cmos_cmd, res; 2514 2515 while ((cmd = next_cmd(&buf))) { 2516 if (sscanf(cmd, "%u", &cmos_cmd) == 1 && 2517 cmos_cmd >= 0 && cmos_cmd <= 21) { 2518 /* cmos_cmd set */ 2519 } else 2520 return -EINVAL; 2521 2522 res = issue_thinkpad_cmos_command(cmos_cmd); 2523 if (res) 2524 return res; 2525 } 2526 2527 return 0; 2528} 2529 2530static struct ibm_struct cmos_driver_data = { 2531 .name = "cmos", 2532 .read = cmos_read, 2533 .write = cmos_write, 2534 .exit = cmos_exit, 2535}; 2536 2537/************************************************************************* 2538 * LED subdriver 2539 */ 2540 2541static enum led_access_mode led_supported; 2542 2543IBM_HANDLE(led, ec, "SLED", /* 570 */ 2544 "SYSL", /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ 2545 "LED", /* all others */ 2546 ); /* R30, R31 */ 2547 2548static int __init led_init(struct ibm_init_struct *iibm) 2549{ 2550 vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n"); 2551 2552 IBM_ACPIHANDLE_INIT(led); 2553 2554 if (!led_handle) 2555 /* led not supported on R30, R31 */ 2556 led_supported = TPACPI_LED_NONE; 2557 else if (strlencmp(led_path, "SLED") == 0) 2558 /* 570 */ 2559 led_supported = TPACPI_LED_570; 2560 else if (strlencmp(led_path, "SYSL") == 0) 2561 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ 2562 led_supported = TPACPI_LED_OLD; 2563 else 2564 /* all others */ 2565 led_supported = TPACPI_LED_NEW; 2566 2567 vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n", 2568 str_supported(led_supported), led_supported); 2569 2570 return (led_supported != TPACPI_LED_NONE)? 0 : 1; 2571} 2572 2573#define led_status(s) ((s) == 0 ? "off" : ((s) == 1 ? "on" : "blinking")) 2574 2575static int led_read(char *p) 2576{ 2577 int len = 0; 2578 2579 if (!led_supported) { 2580 len += sprintf(p + len, "status:\t\tnot supported\n"); 2581 return len; 2582 } 2583 len += sprintf(p + len, "status:\t\tsupported\n"); 2584 2585 if (led_supported == TPACPI_LED_570) { 2586 /* 570 */ 2587 int i, status; 2588 for (i = 0; i < 8; i++) { 2589 if (!acpi_evalf(ec_handle, 2590 &status, "GLED", "dd", 1 << i)) 2591 return -EIO; 2592 len += sprintf(p + len, "%d:\t\t%s\n", 2593 i, led_status(status)); 2594 } 2595 } 2596 2597 len += sprintf(p + len, "commands:\t" 2598 "<led> on, <led> off, <led> blink (<led> is 0-7)\n"); 2599 2600 return len; 2601} 2602 2603/* off, on, blink */ 2604static const int led_sled_arg1[] = { 0, 1, 3 }; 2605static const int led_exp_hlbl[] = { 0, 0, 1 }; /* led# * */ 2606static const int led_exp_hlcl[] = { 0, 1, 1 }; /* led# * */ 2607static const int led_led_arg1[] = { 0, 0x80, 0xc0 }; 2608 2609static int led_write(char *buf) 2610{ 2611 char *cmd; 2612 int led, ind, ret; 2613 2614 if (!led_supported) 2615 return -ENODEV; 2616 2617 while ((cmd = next_cmd(&buf))) { 2618 if (sscanf(cmd, "%d", &led) != 1 || led < 0 || led > 7) 2619 return -EINVAL; 2620 2621 if (strstr(cmd, "off")) { 2622 ind = 0; 2623 } else if (strstr(cmd, "on")) { 2624 ind = 1; 2625 } else if (strstr(cmd, "blink")) { 2626 ind = 2; 2627 } else 2628 return -EINVAL; 2629 2630 if (led_supported == TPACPI_LED_570) { 2631 /* 570 */ 2632 led = 1 << led; 2633 if (!acpi_evalf(led_handle, NULL, NULL, "vdd", 2634 led, led_sled_arg1[ind])) 2635 return -EIO; 2636 } else if (led_supported == TPACPI_LED_OLD) { 2637 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ 2638 led = 1 << led; 2639 ret = ec_write(TPACPI_LED_EC_HLMS, led); 2640 if (ret >= 0) 2641 ret = 2642 ec_write(TPACPI_LED_EC_HLBL, 2643 led * led_exp_hlbl[ind]); 2644 if (ret >= 0) 2645 ret = 2646 ec_write(TPACPI_LED_EC_HLCL, 2647 led * led_exp_hlcl[ind]); 2648 if (ret < 0) 2649 return ret; 2650 } else { 2651 /* all others */ 2652 if (!acpi_evalf(led_handle, NULL, NULL, "vdd", 2653 led, led_led_arg1[ind])) 2654 return -EIO; 2655 } 2656 } 2657 2658 return 0; 2659} 2660 2661static struct ibm_struct led_driver_data = { 2662 .name = "led", 2663 .read = led_read, 2664 .write = led_write, 2665}; 2666 2667/************************************************************************* 2668 * Beep subdriver 2669 */ 2670 2671IBM_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */ 2672 2673static int __init beep_init(struct ibm_init_struct *iibm) 2674{ 2675 vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n"); 2676 2677 IBM_ACPIHANDLE_INIT(beep); 2678 2679 vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n", 2680 str_supported(beep_handle != NULL)); 2681 2682 return (beep_handle)? 0 : 1; 2683} 2684 2685static int beep_read(char *p) 2686{ 2687 int len = 0; 2688 2689 if (!beep_handle) 2690 len += sprintf(p + len, "status:\t\tnot supported\n"); 2691 else { 2692 len += sprintf(p + len, "status:\t\tsupported\n"); 2693 len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-17)\n"); 2694 } 2695 2696 return len; 2697} 2698 2699static int beep_write(char *buf) 2700{ 2701 char *cmd; 2702 int beep_cmd; 2703 2704 if (!beep_handle) 2705 return -ENODEV; 2706 2707 while ((cmd = next_cmd(&buf))) { 2708 if (sscanf(cmd, "%u", &beep_cmd) == 1 && 2709 beep_cmd >= 0 && beep_cmd <= 17) { 2710 /* beep_cmd set */ 2711 } else 2712 return -EINVAL; 2713 if (!acpi_evalf(beep_handle, NULL, NULL, "vdd", beep_cmd, 0)) 2714 return -EIO; 2715 } 2716 2717 return 0; 2718} 2719 2720static struct ibm_struct beep_driver_data = { 2721 .name = "beep", 2722 .read = beep_read, 2723 .write = beep_write, 2724}; 2725 2726/************************************************************************* 2727 * Thermal subdriver 2728 */ 2729 2730static enum thermal_access_mode thermal_read_mode; 2731 2732/* sysfs temp##_input -------------------------------------------------- */ 2733 2734static ssize_t thermal_temp_input_show(struct device *dev, 2735 struct device_attribute *attr, 2736 char *buf) 2737{ 2738 struct sensor_device_attribute *sensor_attr = 2739 to_sensor_dev_attr(attr); 2740 int idx = sensor_attr->index; 2741 s32 value; 2742 int res; 2743 2744 res = thermal_get_sensor(idx, &value); 2745 if (res) 2746 return res; 2747 if (value == TP_EC_THERMAL_TMP_NA * 1000) 2748 return -ENXIO; 2749 2750 return snprintf(buf, PAGE_SIZE, "%d\n", value); 2751} 2752 2753#define THERMAL_SENSOR_ATTR_TEMP(_idxA, _idxB) \ 2754 SENSOR_ATTR(temp##_idxA##_input, S_IRUGO, thermal_temp_input_show, NULL, _idxB) 2755 2756static struct sensor_device_attribute sensor_dev_attr_thermal_temp_input[] = { 2757 THERMAL_SENSOR_ATTR_TEMP(1, 0), 2758 THERMAL_SENSOR_ATTR_TEMP(2, 1), 2759 THERMAL_SENSOR_ATTR_TEMP(3, 2), 2760 THERMAL_SENSOR_ATTR_TEMP(4, 3), 2761 THERMAL_SENSOR_ATTR_TEMP(5, 4), 2762 THERMAL_SENSOR_ATTR_TEMP(6, 5), 2763 THERMAL_SENSOR_ATTR_TEMP(7, 6), 2764 THERMAL_SENSOR_ATTR_TEMP(8, 7), 2765 THERMAL_SENSOR_ATTR_TEMP(9, 8), 2766 THERMAL_SENSOR_ATTR_TEMP(10, 9), 2767 THERMAL_SENSOR_ATTR_TEMP(11, 10), 2768 THERMAL_SENSOR_ATTR_TEMP(12, 11), 2769 THERMAL_SENSOR_ATTR_TEMP(13, 12), 2770 THERMAL_SENSOR_ATTR_TEMP(14, 13), 2771 THERMAL_SENSOR_ATTR_TEMP(15, 14), 2772 THERMAL_SENSOR_ATTR_TEMP(16, 15), 2773}; 2774 2775#define THERMAL_ATTRS(X) \ 2776 &sensor_dev_attr_thermal_temp_input[X].dev_attr.attr 2777 2778static struct attribute *thermal_temp_input_attr[] = { 2779 THERMAL_ATTRS(8), 2780 THERMAL_ATTRS(9), 2781 THERMAL_ATTRS(10), 2782 THERMAL_ATTRS(11), 2783 THERMAL_ATTRS(12), 2784 THERMAL_ATTRS(13), 2785 THERMAL_ATTRS(14), 2786 THERMAL_ATTRS(15), 2787 THERMAL_ATTRS(0), 2788 THERMAL_ATTRS(1), 2789 THERMAL_ATTRS(2), 2790 THERMAL_ATTRS(3), 2791 THERMAL_ATTRS(4), 2792 THERMAL_ATTRS(5), 2793 THERMAL_ATTRS(6), 2794 THERMAL_ATTRS(7), 2795 NULL 2796}; 2797 2798static const struct attribute_group thermal_temp_input16_group = { 2799 .attrs = thermal_temp_input_attr 2800}; 2801 2802static const struct attribute_group thermal_temp_input8_group = { 2803 .attrs = &thermal_temp_input_attr[8] 2804}; 2805 2806#undef THERMAL_SENSOR_ATTR_TEMP 2807#undef THERMAL_ATTRS 2808 2809/* --------------------------------------------------------------------- */ 2810 2811static int __init thermal_init(struct ibm_init_struct *iibm) 2812{ 2813 u8 t, ta1, ta2; 2814 int i; 2815 int acpi_tmp7; 2816 int res; 2817 2818 vdbg_printk(TPACPI_DBG_INIT, "initializing thermal subdriver\n"); 2819 2820 acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); 2821 2822 if (thinkpad_id.ec_model) { 2823 /* 2824 * Direct EC access mode: sensors at registers 2825 * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for 2826 * non-implemented, thermal sensors return 0x80 when 2827 * not available 2828 */ 2829 2830 ta1 = ta2 = 0; 2831 for (i = 0; i < 8; i++) { 2832 if (acpi_ec_read(TP_EC_THERMAL_TMP0 + i, &t)) { 2833 ta1 |= t; 2834 } else { 2835 ta1 = 0; 2836 break; 2837 } 2838 if (acpi_ec_read(TP_EC_THERMAL_TMP8 + i, &t)) { 2839 ta2 |= t; 2840 } else { 2841 ta1 = 0; 2842 break; 2843 } 2844 } 2845 if (ta1 == 0) { 2846 /* This is sheer paranoia, but we handle it anyway */ 2847 if (acpi_tmp7) { 2848 printk(IBM_ERR 2849 "ThinkPad ACPI EC access misbehaving, " 2850 "falling back to ACPI TMPx access mode\n"); 2851 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07; 2852 } else { 2853 printk(IBM_ERR 2854 "ThinkPad ACPI EC access misbehaving, " 2855 "disabling thermal sensors access\n"); 2856 thermal_read_mode = TPACPI_THERMAL_NONE; 2857 } 2858 } else { 2859 thermal_read_mode = 2860 (ta2 != 0) ? 2861 TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8; 2862 } 2863 } else if (acpi_tmp7) { 2864 if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) { 2865 /* 600e/x, 770e, 770x */ 2866 thermal_read_mode = TPACPI_THERMAL_ACPI_UPDT; 2867 } else { 2868 /* Standard ACPI TMPx access, max 8 sensors */ 2869 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07; 2870 } 2871 } else { 2872 /* temperatures not supported on 570, G4x, R30, R31, R32 */ 2873 thermal_read_mode = TPACPI_THERMAL_NONE; 2874 } 2875 2876 vdbg_printk(TPACPI_DBG_INIT, "thermal is %s, mode %d\n", 2877 str_supported(thermal_read_mode != TPACPI_THERMAL_NONE), 2878 thermal_read_mode); 2879 2880 switch(thermal_read_mode) { 2881 case TPACPI_THERMAL_TPEC_16: 2882 res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, 2883 &thermal_temp_input16_group); 2884 if (res) 2885 return res; 2886 break; 2887 case TPACPI_THERMAL_TPEC_8: 2888 case TPACPI_THERMAL_ACPI_TMP07: 2889 case TPACPI_THERMAL_ACPI_UPDT: 2890 res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, 2891 &thermal_temp_input8_group); 2892 if (res) 2893 return res; 2894 break; 2895 case TPACPI_THERMAL_NONE: 2896 default: 2897 return 1; 2898 } 2899 2900 return 0; 2901} 2902 2903static void thermal_exit(void) 2904{ 2905 switch(thermal_read_mode) { 2906 case TPACPI_THERMAL_TPEC_16: 2907 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, 2908 &thermal_temp_input16_group); 2909 break; 2910 case TPACPI_THERMAL_TPEC_8: 2911 case TPACPI_THERMAL_ACPI_TMP07: 2912 case TPACPI_THERMAL_ACPI_UPDT: 2913 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, 2914 &thermal_temp_input16_group); 2915 break; 2916 case TPACPI_THERMAL_NONE: 2917 default: 2918 break; 2919 } 2920} 2921 2922/* idx is zero-based */ 2923static int thermal_get_sensor(int idx, s32 *value) 2924{ 2925 int t; 2926 s8 tmp; 2927 char tmpi[5]; 2928 2929 t = TP_EC_THERMAL_TMP0; 2930 2931 switch (thermal_read_mode) { 2932#if TPACPI_MAX_THERMAL_SENSORS >= 16 2933 case TPACPI_THERMAL_TPEC_16: 2934 if (idx >= 8 && idx <= 15) { 2935 t = TP_EC_THERMAL_TMP8; 2936 idx -= 8; 2937 } 2938 /* fallthrough */ 2939#endif 2940 case TPACPI_THERMAL_TPEC_8: 2941 if (idx <= 7) { 2942 if (!acpi_ec_read(t + idx, &tmp)) 2943 return -EIO; 2944 *value = tmp * 1000; 2945 return 0; 2946 } 2947 break; 2948 2949 case TPACPI_THERMAL_ACPI_UPDT: 2950 if (idx <= 7) { 2951 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx); 2952 if (!acpi_evalf(ec_handle, NULL, "UPDT", "v")) 2953 return -EIO; 2954 if (!acpi_evalf(ec_handle, &t, tmpi, "d")) 2955 return -EIO; 2956 *value = (t - 2732) * 100; 2957 return 0; 2958 } 2959 break; 2960 2961 case TPACPI_THERMAL_ACPI_TMP07: 2962 if (idx <= 7) { 2963 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx); 2964 if (!acpi_evalf(ec_handle, &t, tmpi, "d")) 2965 return -EIO; 2966 if (t > 127 || t < -127) 2967 t = TP_EC_THERMAL_TMP_NA; 2968 *value = t * 1000; 2969 return 0; 2970 } 2971 break; 2972 2973 case TPACPI_THERMAL_NONE: 2974 default: 2975 return -ENOSYS; 2976 } 2977 2978 return -EINVAL; 2979} 2980 2981static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s) 2982{ 2983 int res, i; 2984 int n; 2985 2986 n = 8; 2987 i = 0; 2988 2989 if (!s) 2990 return -EINVAL; 2991 2992 if (thermal_read_mode == TPACPI_THERMAL_TPEC_16) 2993 n = 16; 2994 2995 for(i = 0 ; i < n; i++) { 2996 res = thermal_get_sensor(i, &s->temp[i]); 2997 if (res) 2998 return res; 2999 } 3000 3001 return n; 3002} 3003 3004static int thermal_read(char *p) 3005{ 3006 int len = 0; 3007 int n, i; 3008 struct ibm_thermal_sensors_struct t; 3009 3010 n = thermal_get_sensors(&t); 3011 if (unlikely(n < 0)) 3012 return n; 3013 3014 len += sprintf(p + len, "temperatures:\t"); 3015 3016 if (n > 0) { 3017 for (i = 0; i < (n - 1); i++) 3018 len += sprintf(p + len, "%d ", t.temp[i] / 1000); 3019 len += sprintf(p + len, "%d\n", t.temp[i] / 1000); 3020 } else 3021 len += sprintf(p + len, "not supported\n"); 3022 3023 return len; 3024} 3025 3026static struct ibm_struct thermal_driver_data = { 3027 .name = "thermal", 3028 .read = thermal_read, 3029 .exit = thermal_exit, 3030}; 3031 3032/************************************************************************* 3033 * EC Dump subdriver 3034 */ 3035 3036static u8 ecdump_regs[256]; 3037 3038static int ecdump_read(char *p) 3039{ 3040 int len = 0; 3041 int i, j; 3042 u8 v; 3043 3044 len += sprintf(p + len, "EC " 3045 " +00 +01 +02 +03 +04 +05 +06 +07" 3046 " +08 +09 +0a +0b +0c +0d +0e +0f\n"); 3047 for (i = 0; i < 256; i += 16) { 3048 len += sprintf(p + len, "EC 0x%02x:", i); 3049 for (j = 0; j < 16; j++) { 3050 if (!acpi_ec_read(i + j, &v)) 3051 break; 3052 if (v != ecdump_regs[i + j]) 3053 len += sprintf(p + len, " *%02x", v); 3054 else 3055 len += sprintf(p + len, " %02x", v); 3056 ecdump_regs[i + j] = v; 3057 } 3058 len += sprintf(p + len, "\n"); 3059 if (j != 16) 3060 break; 3061 } 3062 3063 /* These are way too dangerous to advertise openly... */ 3064#if 0 3065 len += sprintf(p + len, "commands:\t0x<offset> 0x<value>" 3066 " (<offset> is 00-ff, <value> is 00-ff)\n"); 3067 len += sprintf(p + len, "commands:\t0x<offset> <value> " 3068 " (<offset> is 00-ff, <value> is 0-255)\n"); 3069#endif 3070 return len; 3071} 3072 3073static int ecdump_write(char *buf) 3074{ 3075 char *cmd; 3076 int i, v; 3077 3078 while ((cmd = next_cmd(&buf))) { 3079 if (sscanf(cmd, "0x%x 0x%x", &i, &v) == 2) { 3080 /* i and v set */ 3081 } else if (sscanf(cmd, "0x%x %u", &i, &v) == 2) { 3082 /* i and v set */ 3083 } else 3084 return -EINVAL; 3085 if (i >= 0 && i < 256 && v >= 0 && v < 256) { 3086 if (!acpi_ec_write(i, v)) 3087 return -EIO; 3088 } else 3089 return -EINVAL; 3090 } 3091 3092 return 0; 3093} 3094 3095static struct ibm_struct ecdump_driver_data = { 3096 .name = "ecdump", 3097 .read = ecdump_read, 3098 .write = ecdump_write, 3099 .flags.experimental = 1, 3100}; 3101 3102/************************************************************************* 3103 * Backlight/brightness subdriver 3104 */ 3105 3106static struct backlight_device *ibm_backlight_device; 3107 3108static struct backlight_ops ibm_backlight_data = { 3109 .get_brightness = brightness_get, 3110 .update_status = brightness_update_status, 3111}; 3112 3113static struct mutex brightness_mutex; 3114 3115static int __init tpacpi_query_bcll_levels(acpi_handle handle) 3116{ 3117 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 3118 union acpi_object *obj; 3119 int rc; 3120 3121 if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) { 3122 obj = (union acpi_object *)buffer.pointer; 3123 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { 3124 printk(IBM_ERR "Unknown BCLL data, " 3125 "please report this to %s\n", IBM_MAIL); 3126 rc = 0; 3127 } else { 3128 rc = obj->package.count; 3129 } 3130 } else { 3131 return 0; 3132 } 3133 3134 kfree(buffer.pointer); 3135 return rc; 3136} 3137 3138static acpi_status __init brightness_find_bcll(acpi_handle handle, u32 lvl, 3139 void *context, void **rv) 3140{ 3141 char name[ACPI_PATH_SEGMENT_LENGTH]; 3142 struct acpi_buffer buffer = { sizeof(name), &name }; 3143 3144 if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && 3145 !strncmp("BCLL", name, sizeof(name) - 1)) { 3146 if (tpacpi_query_bcll_levels(handle) == 16) { 3147 *rv = handle; 3148 return AE_CTRL_TERMINATE; 3149 } else { 3150 return AE_OK; 3151 } 3152 } else { 3153 return AE_OK; 3154 } 3155} 3156 3157static int __init brightness_check_levels(void) 3158{ 3159 int status; 3160 void *found_node = NULL; 3161 3162 if (!vid_handle) { 3163 IBM_ACPIHANDLE_INIT(vid); 3164 } 3165 if (!vid_handle) 3166 return 0; 3167 3168 /* Search for a BCLL package with 16 levels */ 3169 status = acpi_walk_namespace(ACPI_TYPE_PACKAGE, vid_handle, 3, 3170 brightness_find_bcll, NULL, &found_node); 3171 3172 return (ACPI_SUCCESS(status) && found_node != NULL); 3173} 3174 3175static acpi_status __init brightness_find_bcl(acpi_handle handle, u32 lvl, 3176 void *context, void **rv) 3177{ 3178 char name[ACPI_PATH_SEGMENT_LENGTH]; 3179 struct acpi_buffer buffer = { sizeof(name), &name }; 3180 3181 if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && 3182 !strncmp("_BCL", name, sizeof(name) - 1)) { 3183 *rv = handle; 3184 return AE_CTRL_TERMINATE; 3185 } else { 3186 return AE_OK; 3187 } 3188} 3189 3190static int __init brightness_check_std_acpi_support(void) 3191{ 3192 int status; 3193 void *found_node = NULL; 3194 3195 if (!vid_handle) { 3196 IBM_ACPIHANDLE_INIT(vid); 3197 } 3198 if (!vid_handle) 3199 return 0; 3200 3201 /* Search for a _BCL method, but don't execute it */ 3202 status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, 3203 brightness_find_bcl, NULL, &found_node); 3204 3205 return (ACPI_SUCCESS(status) && found_node != NULL); 3206} 3207 3208static int __init brightness_init(struct ibm_init_struct *iibm) 3209{ 3210 int b; 3211 3212 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n"); 3213 3214 mutex_init(&brightness_mutex); 3215 3216 if (!brightness_enable) { 3217 dbg_printk(TPACPI_DBG_INIT, 3218 "brightness support disabled by module parameter\n"); 3219 return 1; 3220 } else if (brightness_enable > 1) { 3221 if (brightness_check_std_acpi_support()) { 3222 printk(IBM_NOTICE 3223 "standard ACPI backlight interface available, not loading native one...\n"); 3224 return 1; 3225 } 3226 } 3227 3228 if (!brightness_mode) { 3229 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) 3230 brightness_mode = 2; 3231 else 3232 brightness_mode = 3; 3233 3234 dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n", 3235 brightness_mode); 3236 } 3237 3238 if (brightness_mode > 3) 3239 return -EINVAL; 3240 3241 tp_features.bright_16levels = 3242 thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO && 3243 brightness_check_levels(); 3244 3245 b = brightness_get(NULL); 3246 if (b < 0) 3247 return 1; 3248 3249 if (tp_features.bright_16levels) 3250 printk(IBM_INFO "detected a 16-level brightness capable ThinkPad\n"); 3251 3252 ibm_backlight_device = backlight_device_register( 3253 TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, 3254 &ibm_backlight_data); 3255 if (IS_ERR(ibm_backlight_device)) { 3256 printk(IBM_ERR "Could not register backlight device\n"); 3257 return PTR_ERR(ibm_backlight_device); 3258 } 3259 vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n"); 3260 3261 ibm_backlight_device->props.max_brightness = 3262 (tp_features.bright_16levels)? 15 : 7; 3263 ibm_backlight_device->props.brightness = b; 3264 backlight_update_status(ibm_backlight_device); 3265 3266 return 0; 3267} 3268 3269static void brightness_exit(void) 3270{ 3271 if (ibm_backlight_device) { 3272 vdbg_printk(TPACPI_DBG_EXIT, 3273 "calling backlight_device_unregister()\n"); 3274 backlight_device_unregister(ibm_backlight_device); 3275 ibm_backlight_device = NULL; 3276 } 3277} 3278 3279static int brightness_update_status(struct backlight_device *bd) 3280{ 3281 /* it is the backlight class's job (caller) to handle 3282 * EINTR and other errors properly */ 3283 return brightness_set( 3284 (bd->props.fb_blank == FB_BLANK_UNBLANK && 3285 bd->props.power == FB_BLANK_UNBLANK) ? 3286 bd->props.brightness : 0); 3287} 3288 3289/* 3290 * ThinkPads can read brightness from two places: EC 0x31, or 3291 * CMOS NVRAM byte 0x5E, bits 0-3. 3292 */ 3293static int brightness_get(struct backlight_device *bd) 3294{ 3295 u8 lec = 0, lcmos = 0, level = 0; 3296 3297 if (brightness_mode & 1) { 3298 if (!acpi_ec_read(brightness_offset, &lec)) 3299 return -EIO; 3300 lec &= (tp_features.bright_16levels)? 0x0f : 0x07; 3301 level = lec; 3302 }; 3303 if (brightness_mode & 2) { 3304 lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) 3305 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) 3306 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; 3307 lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07; 3308 level = lcmos; 3309 } 3310 3311 if (brightness_mode == 3 && lec != lcmos) { 3312 printk(IBM_ERR 3313 "CMOS NVRAM (%u) and EC (%u) do not agree " 3314 "on display brightness level\n", 3315 (unsigned int) lcmos, 3316 (unsigned int) lec); 3317 return -EIO; 3318 } 3319 3320 return level; 3321} 3322 3323/* May return EINTR which can always be mapped to ERESTARTSYS */ 3324static int brightness_set(int value) 3325{ 3326 int cmos_cmd, inc, i, res; 3327 int current_value; 3328 3329 if (value > ((tp_features.bright_16levels)? 15 : 7)) 3330 return -EINVAL; 3331 3332 res = mutex_lock_interruptible(&brightness_mutex); 3333 if (res < 0) 3334 return res; 3335 3336 current_value = brightness_get(NULL); 3337 if (current_value < 0) { 3338 res = current_value; 3339 goto errout; 3340 } 3341 3342 cmos_cmd = value > current_value ? 3343 TP_CMOS_BRIGHTNESS_UP : 3344 TP_CMOS_BRIGHTNESS_DOWN; 3345 inc = (value > current_value)? 1 : -1; 3346 3347 res = 0; 3348 for (i = current_value; i != value; i += inc) { 3349 if ((brightness_mode & 2) && 3350 issue_thinkpad_cmos_command(cmos_cmd)) { 3351 res = -EIO; 3352 goto errout; 3353 } 3354 if ((brightness_mode & 1) && 3355 !acpi_ec_write(brightness_offset, i + inc)) { 3356 res = -EIO; 3357 goto errout;; 3358 } 3359 } 3360 3361errout: 3362 mutex_unlock(&brightness_mutex); 3363 return res; 3364} 3365 3366static int brightness_read(char *p) 3367{ 3368 int len = 0; 3369 int level; 3370 3371 if ((level = brightness_get(NULL)) < 0) { 3372 len += sprintf(p + len, "level:\t\tunreadable\n"); 3373 } else { 3374 len += sprintf(p + len, "level:\t\t%d\n", level); 3375 len += sprintf(p + len, "commands:\tup, down\n"); 3376 len += sprintf(p + len, "commands:\tlevel <level>" 3377 " (<level> is 0-%d)\n", 3378 (tp_features.bright_16levels) ? 15 : 7); 3379 } 3380 3381 return len; 3382} 3383 3384static int brightness_write(char *buf) 3385{ 3386 int level; 3387 int rc; 3388 char *cmd; 3389 int max_level = (tp_features.bright_16levels) ? 15 : 7; 3390 3391 level = brightness_get(NULL); 3392 if (level < 0) 3393 return level; 3394 3395 while ((cmd = next_cmd(&buf))) { 3396 if (strlencmp(cmd, "up") == 0) { 3397 if (level < max_level) 3398 level++; 3399 } else if (strlencmp(cmd, "down") == 0) { 3400 if (level > 0) 3401 level--; 3402 } else if (sscanf(cmd, "level %d", &level) == 1 && 3403 level >= 0 && level <= max_level) { 3404 /* new level set */ 3405 } else 3406 return -EINVAL; 3407 } 3408 3409 /* 3410 * Now we know what the final level should be, so we try to set it. 3411 * Doing it this way makes the syscall restartable in case of EINTR 3412 */ 3413 rc = brightness_set(level); 3414 return (rc == -EINTR)? ERESTARTSYS : rc; 3415} 3416 3417static struct ibm_struct brightness_driver_data = { 3418 .name = "brightness", 3419 .read = brightness_read, 3420 .write = brightness_write, 3421 .exit = brightness_exit, 3422}; 3423 3424/************************************************************************* 3425 * Volume subdriver 3426 */ 3427 3428static int volume_read(char *p) 3429{ 3430 int len = 0; 3431 u8 level; 3432 3433 if (!acpi_ec_read(volume_offset, &level)) { 3434 len += sprintf(p + len, "level:\t\tunreadable\n"); 3435 } else { 3436 len += sprintf(p + len, "level:\t\t%d\n", level & 0xf); 3437 len += sprintf(p + len, "mute:\t\t%s\n", onoff(level, 6)); 3438 len += sprintf(p + len, "commands:\tup, down, mute\n"); 3439 len += sprintf(p + len, "commands:\tlevel <level>" 3440 " (<level> is 0-15)\n"); 3441 } 3442 3443 return len; 3444} 3445 3446static int volume_write(char *buf) 3447{ 3448 int cmos_cmd, inc, i; 3449 u8 level, mute; 3450 int new_level, new_mute; 3451 char *cmd; 3452 3453 while ((cmd = next_cmd(&buf))) { 3454 if (!acpi_ec_read(volume_offset, &level)) 3455 return -EIO; 3456 new_mute = mute = level & 0x40; 3457 new_level = level = level & 0xf; 3458 3459 if (strlencmp(cmd, "up") == 0) { 3460 if (mute) 3461 new_mute = 0; 3462 else 3463 new_level = level == 15 ? 15 : level + 1; 3464 } else if (strlencmp(cmd, "down") == 0) { 3465 if (mute) 3466 new_mute = 0; 3467 else 3468 new_level = level == 0 ? 0 : level - 1; 3469 } else if (sscanf(cmd, "level %d", &new_level) == 1 && 3470 new_level >= 0 && new_level <= 15) { 3471 /* new_level set */ 3472 } else if (strlencmp(cmd, "mute") == 0) { 3473 new_mute = 0x40; 3474 } else 3475 return -EINVAL; 3476 3477 if (new_level != level) { /* mute doesn't change */ 3478 cmos_cmd = new_level > level ? TP_CMOS_VOLUME_UP : TP_CMOS_VOLUME_DOWN; 3479 inc = new_level > level ? 1 : -1; 3480 3481 if (mute && (issue_thinkpad_cmos_command(cmos_cmd) || 3482 !acpi_ec_write(volume_offset, level))) 3483 return -EIO; 3484 3485 for (i = level; i != new_level; i += inc) 3486 if (issue_thinkpad_cmos_command(cmos_cmd) || 3487 !acpi_ec_write(volume_offset, i + inc)) 3488 return -EIO; 3489 3490 if (mute && (issue_thinkpad_cmos_command(TP_CMOS_VOLUME_MUTE) || 3491 !acpi_ec_write(volume_offset, 3492 new_level + mute))) 3493 return -EIO; 3494 } 3495 3496 if (new_mute != mute) { /* level doesn't change */ 3497 cmos_cmd = new_mute ? TP_CMOS_VOLUME_MUTE : TP_CMOS_VOLUME_UP; 3498 3499 if (issue_thinkpad_cmos_command(cmos_cmd) || 3500 !acpi_ec_write(volume_offset, level + new_mute)) 3501 return -EIO; 3502 } 3503 } 3504 3505 return 0; 3506} 3507 3508static struct ibm_struct volume_driver_data = { 3509 .name = "volume", 3510 .read = volume_read, 3511 .write = volume_write, 3512}; 3513 3514/************************************************************************* 3515 * Fan subdriver 3516 */ 3517 3518/* 3519 * FAN ACCESS MODES 3520 * 3521 * TPACPI_FAN_RD_ACPI_GFAN: 3522 * ACPI GFAN method: returns fan level 3523 * 3524 * see TPACPI_FAN_WR_ACPI_SFAN 3525 * EC 0x2f (HFSP) not available if GFAN exists 3526 * 3527 * TPACPI_FAN_WR_ACPI_SFAN: 3528 * ACPI SFAN method: sets fan level, 0 (stop) to 7 (max) 3529 * 3530 * EC 0x2f (HFSP) might be available *for reading*, but do not use 3531 * it for writing. 3532 * 3533 * TPACPI_FAN_WR_TPEC: 3534 * ThinkPad EC register 0x2f (HFSP): fan control loop mode 3535 * Supported on almost all ThinkPads 3536 * 3537 * Fan speed changes of any sort (including those caused by the 3538 * disengaged mode) are usually done slowly by the firmware as the 3539 * maximum ammount of fan duty cycle change per second seems to be 3540 * limited. 3541 * 3542 * Reading is not available if GFAN exists. 3543 * Writing is not available if SFAN exists. 3544 * 3545 * Bits 3546 * 7 automatic mode engaged; 3547 * (default operation mode of the ThinkPad) 3548 * fan level is ignored in this mode. 3549 * 6 full speed mode (takes precedence over bit 7); 3550 * not available on all thinkpads. May disable 3551 * the tachometer while the fan controller ramps up 3552 * the speed (which can take up to a few *minutes*). 3553 * Speeds up fan to 100% duty-cycle, which is far above 3554 * the standard RPM levels. It is not impossible that 3555 * it could cause hardware damage. 3556 * 5-3 unused in some models. Extra bits for fan level 3557 * in others, but still useless as all values above 3558 * 7 map to the same speed as level 7 in these models. 3559 * 2-0 fan level (0..7 usually) 3560 * 0x00 = stop 3561 * 0x07 = max (set when temperatures critical) 3562 * Some ThinkPads may have other levels, see 3563 * TPACPI_FAN_WR_ACPI_FANS (X31/X40/X41) 3564 * 3565 * FIRMWARE BUG: on some models, EC 0x2f might not be initialized at 3566 * boot. Apparently the EC does not intialize it, so unless ACPI DSDT 3567 * does so, its initial value is meaningless (0x07). 3568 * 3569 * For firmware bugs, refer to: 3570 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues 3571 * 3572 * ---- 3573 * 3574 * ThinkPad EC register 0x84 (LSB), 0x85 (MSB): 3575 * Main fan tachometer reading (in RPM) 3576 * 3577 * This register is present on all ThinkPads with a new-style EC, and 3578 * it is known not to be present on the A21m/e, and T22, as there is 3579 * something else in offset 0x84 according to the ACPI DSDT. Other 3580 * ThinkPads from this same time period (and earlier) probably lack the 3581 * tachometer as well. 3582 * 3583 * Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare 3584 * was never fixed by IBM to report the EC firmware version string 3585 * probably support the tachometer (like the early X models), so 3586 * detecting it is quite hard. We need more data to know for sure. 3587 * 3588 * FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings 3589 * might result. 3590 * 3591 * FIRMWARE BUG: may go stale while the EC is switching to full speed 3592 * mode. 3593 * 3594 * For firmware bugs, refer to: 3595 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues 3596 * 3597 * TPACPI_FAN_WR_ACPI_FANS: 3598 * ThinkPad X31, X40, X41. Not available in the X60. 3599 * 3600 * FANS ACPI handle: takes three arguments: low speed, medium speed, 3601 * high speed. ACPI DSDT seems to map these three speeds to levels 3602 * as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH 3603 * (this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3") 3604 * 3605 * The speeds are stored on handles 3606 * (FANA:FAN9), (FANC:FANB), (FANE:FAND). 3607 * 3608 * There are three default speed sets, acessible as handles: 3609 * FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H 3610 * 3611 * ACPI DSDT switches which set is in use depending on various 3612 * factors. 3613 * 3614 * TPACPI_FAN_WR_TPEC is also available and should be used to 3615 * command the fan. The X31/X40/X41 seems to have 8 fan levels, 3616 * but the ACPI tables just mention level 7. 3617 */ 3618 3619static enum fan_status_access_mode fan_status_access_mode; 3620static enum fan_control_access_mode fan_control_access_mode; 3621static enum fan_control_commands fan_control_commands; 3622 3623static u8 fan_control_initial_status; 3624static u8 fan_control_desired_level; 3625 3626static void fan_watchdog_fire(struct work_struct *ignored); 3627static int fan_watchdog_maxinterval; 3628static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire); 3629 3630IBM_HANDLE(fans, ec, "FANS"); /* X31, X40, X41 */ 3631IBM_HANDLE(gfan, ec, "GFAN", /* 570 */ 3632 "\\FSPD", /* 600e/x, 770e, 770x */ 3633 ); /* all others */ 3634IBM_HANDLE(sfan, ec, "SFAN", /* 570 */ 3635 "JFNS", /* 770x-JL */ 3636 ); /* all others */ 3637 3638/* 3639 * SYSFS fan layout: hwmon compatible (device) 3640 * 3641 * pwm*_enable: 3642 * 0: "disengaged" mode 3643 * 1: manual mode 3644 * 2: native EC "auto" mode (recommended, hardware default) 3645 * 3646 * pwm*: set speed in manual mode, ignored otherwise. 3647 * 0 is level 0; 255 is level 7. Intermediate points done with linear 3648 * interpolation. 3649 * 3650 * fan*_input: tachometer reading, RPM 3651 * 3652 * 3653 * SYSFS fan layout: extensions 3654 * 3655 * fan_watchdog (driver): 3656 * fan watchdog interval in seconds, 0 disables (default), max 120 3657 */ 3658 3659/* sysfs fan pwm1_enable ----------------------------------------------- */ 3660static ssize_t fan_pwm1_enable_show(struct device *dev, 3661 struct device_attribute *attr, 3662 char *buf) 3663{ 3664 int res, mode; 3665 u8 status; 3666 3667 res = fan_get_status_safe(&status); 3668 if (res) 3669 return res; 3670 3671 if (unlikely(tp_features.fan_ctrl_status_undef)) { 3672 if (status != fan_control_initial_status) { 3673 tp_features.fan_ctrl_status_undef = 0; 3674 } else { 3675 /* Return most likely status. In fact, it 3676 * might be the only possible status */ 3677 status = TP_EC_FAN_AUTO; 3678 } 3679 } 3680 3681 if (status & TP_EC_FAN_FULLSPEED) { 3682 mode = 0; 3683 } else if (status & TP_EC_FAN_AUTO) { 3684 mode = 2; 3685 } else 3686 mode = 1; 3687 3688 return snprintf(buf, PAGE_SIZE, "%d\n", mode); 3689} 3690 3691static ssize_t fan_pwm1_enable_store(struct device *dev, 3692 struct device_attribute *attr, 3693 const char *buf, size_t count) 3694{ 3695 unsigned long t; 3696 int res, level; 3697 3698 if (parse_strtoul(buf, 2, &t)) 3699 return -EINVAL; 3700 3701 switch (t) { 3702 case 0: 3703 level = TP_EC_FAN_FULLSPEED; 3704 break; 3705 case 1: 3706 level = TPACPI_FAN_LAST_LEVEL; 3707 break; 3708 case 2: 3709 level = TP_EC_FAN_AUTO; 3710 break; 3711 case 3: 3712 /* reserved for software-controlled auto mode */ 3713 return -ENOSYS; 3714 default: 3715 return -EINVAL; 3716 } 3717 3718 res = fan_set_level_safe(level); 3719 if (res == -ENXIO) 3720 return -EINVAL; 3721 else if (res < 0) 3722 return res; 3723 3724 fan_watchdog_reset(); 3725 3726 return count; 3727} 3728 3729static struct device_attribute dev_attr_fan_pwm1_enable = 3730 __ATTR(pwm1_enable, S_IWUSR | S_IRUGO, 3731 fan_pwm1_enable_show, fan_pwm1_enable_store); 3732 3733/* sysfs fan pwm1 ------------------------------------------------------ */ 3734static ssize_t fan_pwm1_show(struct device *dev, 3735 struct device_attribute *attr, 3736 char *buf) 3737{ 3738 int res; 3739 u8 status; 3740 3741 res = fan_get_status_safe(&status); 3742 if (res) 3743 return res; 3744 3745 if (unlikely(tp_features.fan_ctrl_status_undef)) { 3746 if (status != fan_control_initial_status) { 3747 tp_features.fan_ctrl_status_undef = 0; 3748 } else { 3749 status = TP_EC_FAN_AUTO; 3750 } 3751 } 3752 3753 if ((status & 3754 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0) 3755 status = fan_control_desired_level; 3756 3757 if (status > 7) 3758 status = 7; 3759 3760 return snprintf(buf, PAGE_SIZE, "%u\n", (status * 255) / 7); 3761} 3762 3763static ssize_t fan_pwm1_store(struct device *dev, 3764 struct device_attribute *attr, 3765 const char *buf, size_t count) 3766{ 3767 unsigned long s; 3768 int rc; 3769 u8 status, newlevel; 3770 3771 if (parse_strtoul(buf, 255, &s)) 3772 return -EINVAL; 3773 3774 /* scale down from 0-255 to 0-7 */ 3775 newlevel = (s >> 5) & 0x07; 3776 3777 if (mutex_lock_interruptible(&fan_mutex)) 3778 return -ERESTARTSYS; 3779 3780 rc = fan_get_status(&status); 3781 if (!rc && (status & 3782 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) { 3783 rc = fan_set_level(newlevel); 3784 if (rc == -ENXIO) 3785 rc = -EINVAL; 3786 else if (!rc) { 3787 fan_update_desired_level(newlevel); 3788 fan_watchdog_reset(); 3789 } 3790 } 3791 3792 mutex_unlock(&fan_mutex); 3793 return (rc)? rc : count; 3794} 3795 3796static struct device_attribute dev_attr_fan_pwm1 = 3797 __ATTR(pwm1, S_IWUSR | S_IRUGO, 3798 fan_pwm1_show, fan_pwm1_store); 3799 3800/* sysfs fan fan1_input ------------------------------------------------ */ 3801static ssize_t fan_fan1_input_show(struct device *dev, 3802 struct device_attribute *attr, 3803 char *buf) 3804{ 3805 int res; 3806 unsigned int speed; 3807 3808 res = fan_get_speed(&speed); 3809 if (res < 0) 3810 return res; 3811 3812 return snprintf(buf, PAGE_SIZE, "%u\n", speed); 3813} 3814 3815static struct device_attribute dev_attr_fan_fan1_input = 3816 __ATTR(fan1_input, S_IRUGO, 3817 fan_fan1_input_show, NULL); 3818 3819/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */ 3820static ssize_t fan_fan_watchdog_show(struct device_driver *drv, 3821 char *buf) 3822{ 3823 return snprintf(buf, PAGE_SIZE, "%u\n", fan_watchdog_maxinterval); 3824} 3825 3826static ssize_t fan_fan_watchdog_store(struct device_driver *drv, 3827 const char *buf, size_t count) 3828{ 3829 unsigned long t; 3830 3831 if (parse_strtoul(buf, 120, &t)) 3832 return -EINVAL; 3833 3834 if (!fan_control_allowed) 3835 return -EPERM; 3836 3837 fan_watchdog_maxinterval = t; 3838 fan_watchdog_reset(); 3839 3840 return count; 3841} 3842 3843static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO, 3844 fan_fan_watchdog_show, fan_fan_watchdog_store); 3845 3846/* --------------------------------------------------------------------- */ 3847static struct attribute *fan_attributes[] = { 3848 &dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr, 3849 &dev_attr_fan_fan1_input.attr, 3850 NULL 3851}; 3852 3853static const struct attribute_group fan_attr_group = { 3854 .attrs = fan_attributes, 3855}; 3856 3857static int __init fan_init(struct ibm_init_struct *iibm) 3858{ 3859 int rc; 3860 3861 vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n"); 3862 3863 mutex_init(&fan_mutex); 3864 fan_status_access_mode = TPACPI_FAN_NONE; 3865 fan_control_access_mode = TPACPI_FAN_WR_NONE; 3866 fan_control_commands = 0; 3867 fan_watchdog_maxinterval = 0; 3868 tp_features.fan_ctrl_status_undef = 0; 3869 fan_control_desired_level = 7; 3870 3871 IBM_ACPIHANDLE_INIT(fans); 3872 IBM_ACPIHANDLE_INIT(gfan); 3873 IBM_ACPIHANDLE_INIT(sfan); 3874 3875 if (gfan_handle) { 3876 /* 570, 600e/x, 770e, 770x */ 3877 fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN; 3878 } else { 3879 /* all other ThinkPads: note that even old-style 3880 * ThinkPad ECs supports the fan control register */ 3881 if (likely(acpi_ec_read(fan_status_offset, 3882 &fan_control_initial_status))) { 3883 fan_status_access_mode = TPACPI_FAN_RD_TPEC; 3884 3885 /* In some ThinkPads, neither the EC nor the ACPI 3886 * DSDT initialize the fan status, and it ends up 3887 * being set to 0x07 when it *could* be either 3888 * 0x07 or 0x80. 3889 * 3890 * Enable for TP-1Y (T43), TP-78 (R51e), 3891 * TP-76 (R52), TP-70 (T43, R52), which are known 3892 * to be buggy. */ 3893 if (fan_control_initial_status == 0x07) { 3894 switch (thinkpad_id.ec_model) { 3895 case 0x5931: /* TP-1Y */ 3896 case 0x3837: /* TP-78 */ 3897 case 0x3637: /* TP-76 */ 3898 case 0x3037: /* TP-70 */ 3899 printk(IBM_NOTICE 3900 "fan_init: initial fan status is " 3901 "unknown, assuming it is in auto " 3902 "mode\n"); 3903 tp_features.fan_ctrl_status_undef = 1; 3904 ;; 3905 } 3906 } 3907 } else { 3908 printk(IBM_ERR 3909 "ThinkPad ACPI EC access misbehaving, " 3910 "fan status and control unavailable\n"); 3911 return 1; 3912 } 3913 } 3914 3915 if (sfan_handle) { 3916 /* 570, 770x-JL */ 3917 fan_control_access_mode = TPACPI_FAN_WR_ACPI_SFAN; 3918 fan_control_commands |= 3919 TPACPI_FAN_CMD_LEVEL | TPACPI_FAN_CMD_ENABLE; 3920 } else { 3921 if (!gfan_handle) { 3922 /* gfan without sfan means no fan control */ 3923 /* all other models implement TP EC 0x2f control */ 3924 3925 if (fans_handle) { 3926 /* X31, X40, X41 */ 3927 fan_control_access_mode = 3928 TPACPI_FAN_WR_ACPI_FANS; 3929 fan_control_commands |= 3930 TPACPI_FAN_CMD_SPEED | 3931 TPACPI_FAN_CMD_LEVEL | 3932 TPACPI_FAN_CMD_ENABLE; 3933 } else { 3934 fan_control_access_mode = TPACPI_FAN_WR_TPEC; 3935 fan_control_commands |= 3936 TPACPI_FAN_CMD_LEVEL | 3937 TPACPI_FAN_CMD_ENABLE; 3938 } 3939 } 3940 } 3941 3942 vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n", 3943 str_supported(fan_status_access_mode != TPACPI_FAN_NONE || 3944 fan_control_access_mode != TPACPI_FAN_WR_NONE), 3945 fan_status_access_mode, fan_control_access_mode); 3946 3947 /* fan control master switch */ 3948 if (!fan_control_allowed) { 3949 fan_control_access_mode = TPACPI_FAN_WR_NONE; 3950 fan_control_commands = 0; 3951 dbg_printk(TPACPI_DBG_INIT, 3952 "fan control features disabled by parameter\n"); 3953 } 3954 3955 /* update fan_control_desired_level */ 3956 if (fan_status_access_mode != TPACPI_FAN_NONE) 3957 fan_get_status_safe(NULL); 3958 3959 if (fan_status_access_mode != TPACPI_FAN_NONE || 3960 fan_control_access_mode != TPACPI_FAN_WR_NONE) { 3961 rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, 3962 &fan_attr_group); 3963 if (!(rc < 0)) 3964 rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, 3965 &driver_attr_fan_watchdog); 3966 if (rc < 0) 3967 return rc; 3968 return 0; 3969 } else 3970 return 1; 3971} 3972 3973/* 3974 * Call with fan_mutex held 3975 */ 3976static void fan_update_desired_level(u8 status) 3977{ 3978 if ((status & 3979 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) { 3980 if (status > 7) 3981 fan_control_desired_level = 7; 3982 else 3983 fan_control_desired_level = status; 3984 } 3985} 3986 3987static int fan_get_status(u8 *status) 3988{ 3989 u8 s; 3990 3991 /* TODO: 3992 * Add TPACPI_FAN_RD_ACPI_FANS ? */ 3993 3994 switch (fan_status_access_mode) { 3995 case TPACPI_FAN_RD_ACPI_GFAN: 3996 /* 570, 600e/x, 770e, 770x */ 3997 3998 if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d"))) 3999 return -EIO; 4000 4001 if (likely(status)) 4002 *status = s & 0x07; 4003 4004 break; 4005 4006 case TPACPI_FAN_RD_TPEC: 4007 /* all except 570, 600e/x, 770e, 770x */ 4008 if (unlikely(!acpi_ec_read(fan_status_offset, &s))) 4009 return -EIO; 4010 4011 if (likely(status)) 4012 *status = s; 4013 4014 break; 4015 4016 default: 4017 return -ENXIO; 4018 } 4019 4020 return 0; 4021} 4022 4023static int fan_get_status_safe(u8 *status) 4024{ 4025 int rc; 4026 u8 s; 4027 4028 if (mutex_lock_interruptible(&fan_mutex)) 4029 return -ERESTARTSYS; 4030 rc = fan_get_status(&s); 4031 if (!rc) 4032 fan_update_desired_level(s); 4033 mutex_unlock(&fan_mutex); 4034 4035 if (status) 4036 *status = s; 4037 4038 return rc; 4039} 4040 4041static void fan_exit(void) 4042{ 4043 vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending fan watchdog tasks\n"); 4044 4045 /* FIXME: can we really do this unconditionally? */ 4046 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group); 4047 driver_remove_file(&tpacpi_hwmon_pdriver.driver, &driver_attr_fan_watchdog); 4048 4049 cancel_delayed_work(&fan_watchdog_task); 4050 flush_scheduled_work(); 4051} 4052 4053static int fan_get_speed(unsigned int *speed) 4054{ 4055 u8 hi, lo; 4056 4057 switch (fan_status_access_mode) { 4058 case TPACPI_FAN_RD_TPEC: 4059 /* all except 570, 600e/x, 770e, 770x */ 4060 if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) || 4061 !acpi_ec_read(fan_rpm_offset + 1, &hi))) 4062 return -EIO; 4063 4064 if (likely(speed)) 4065 *speed = (hi << 8) | lo; 4066 4067 break; 4068 4069 default: 4070 return -ENXIO; 4071 } 4072 4073 return 0; 4074} 4075 4076static void fan_watchdog_fire(struct work_struct *ignored) 4077{ 4078 int rc; 4079 4080 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING) 4081 return; 4082 4083 printk(IBM_NOTICE "fan watchdog: enabling fan\n"); 4084 rc = fan_set_enable(); 4085 if (rc < 0) { 4086 printk(IBM_ERR "fan watchdog: error %d while enabling fan, " 4087 "will try again later...\n", -rc); 4088 /* reschedule for later */ 4089 fan_watchdog_reset(); 4090 } 4091} 4092 4093static void fan_watchdog_reset(void) 4094{ 4095 static int fan_watchdog_active; 4096 4097 if (fan_control_access_mode == TPACPI_FAN_WR_NONE) 4098 return; 4099 4100 if (fan_watchdog_active) 4101 cancel_delayed_work(&fan_watchdog_task); 4102 4103 if (fan_watchdog_maxinterval > 0 && 4104 tpacpi_lifecycle != TPACPI_LIFE_EXITING) { 4105 fan_watchdog_active = 1; 4106 if (!schedule_delayed_work(&fan_watchdog_task, 4107 msecs_to_jiffies(fan_watchdog_maxinterval 4108 * 1000))) { 4109 printk(IBM_ERR "failed to schedule the fan watchdog, " 4110 "watchdog will not trigger\n"); 4111 } 4112 } else 4113 fan_watchdog_active = 0; 4114} 4115 4116static int fan_set_level(int level) 4117{ 4118 if (!fan_control_allowed) 4119 return -EPERM; 4120 4121 switch (fan_control_access_mode) { 4122 case TPACPI_FAN_WR_ACPI_SFAN: 4123 if (level >= 0 && level <= 7) { 4124 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level)) 4125 return -EIO; 4126 } else 4127 return -EINVAL; 4128 break; 4129 4130 case TPACPI_FAN_WR_ACPI_FANS: 4131 case TPACPI_FAN_WR_TPEC: 4132 if ((level != TP_EC_FAN_AUTO) && 4133 (level != TP_EC_FAN_FULLSPEED) && 4134 ((level < 0) || (level > 7))) 4135 return -EINVAL; 4136 4137 /* safety net should the EC not support AUTO 4138 * or FULLSPEED mode bits and just ignore them */ 4139 if (level & TP_EC_FAN_FULLSPEED) 4140 level |= 7; /* safety min speed 7 */ 4141 else if (level & TP_EC_FAN_FULLSPEED) 4142 level |= 4; /* safety min speed 4 */ 4143 4144 if (!acpi_ec_write(fan_status_offset, level)) 4145 return -EIO; 4146 else 4147 tp_features.fan_ctrl_status_undef = 0; 4148 break; 4149 4150 default: 4151 return -ENXIO; 4152 } 4153 return 0; 4154} 4155 4156static int fan_set_level_safe(int level) 4157{ 4158 int rc; 4159 4160 if (!fan_control_allowed) 4161 return -EPERM; 4162 4163 if (mutex_lock_interruptible(&fan_mutex)) 4164 return -ERESTARTSYS; 4165 4166 if (level == TPACPI_FAN_LAST_LEVEL) 4167 level = fan_control_desired_level; 4168 4169 rc = fan_set_level(level); 4170 if (!rc) 4171 fan_update_desired_level(level); 4172 4173 mutex_unlock(&fan_mutex); 4174 return rc; 4175} 4176 4177static int fan_set_enable(void) 4178{ 4179 u8 s; 4180 int rc; 4181 4182 if (!fan_control_allowed) 4183 return -EPERM; 4184 4185 if (mutex_lock_interruptible(&fan_mutex)) 4186 return -ERESTARTSYS; 4187 4188 switch (fan_control_access_mode) { 4189 case TPACPI_FAN_WR_ACPI_FANS: 4190 case TPACPI_FAN_WR_TPEC: 4191 rc = fan_get_status(&s); 4192 if (rc < 0) 4193 break; 4194 4195 /* Don't go out of emergency fan mode */ 4196 if (s != 7) { 4197 s &= 0x07; 4198 s |= TP_EC_FAN_AUTO | 4; /* min fan speed 4 */ 4199 } 4200 4201 if (!acpi_ec_write(fan_status_offset, s)) 4202 rc = -EIO; 4203 else { 4204 tp_features.fan_ctrl_status_undef = 0; 4205 rc = 0; 4206 } 4207 break; 4208 4209 case TPACPI_FAN_WR_ACPI_SFAN: 4210 rc = fan_get_status(&s); 4211 if (rc < 0) 4212 break; 4213 4214 s &= 0x07; 4215 4216 /* Set fan to at least level 4 */ 4217 s |= 4; 4218 4219 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s)) 4220 rc= -EIO; 4221 else 4222 rc = 0; 4223 break; 4224 4225 default: 4226 rc = -ENXIO; 4227 } 4228 4229 mutex_unlock(&fan_mutex); 4230 return rc; 4231} 4232 4233static int fan_set_disable(void) 4234{ 4235 int rc; 4236 4237 if (!fan_control_allowed) 4238 return -EPERM; 4239 4240 if (mutex_lock_interruptible(&fan_mutex)) 4241 return -ERESTARTSYS; 4242 4243 rc = 0; 4244 switch (fan_control_access_mode) { 4245 case TPACPI_FAN_WR_ACPI_FANS: 4246 case TPACPI_FAN_WR_TPEC: 4247 if (!acpi_ec_write(fan_status_offset, 0x00)) 4248 rc = -EIO; 4249 else { 4250 fan_control_desired_level = 0; 4251 tp_features.fan_ctrl_status_undef = 0; 4252 } 4253 break; 4254 4255 case TPACPI_FAN_WR_ACPI_SFAN: 4256 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00)) 4257 rc = -EIO; 4258 else 4259 fan_control_desired_level = 0; 4260 break; 4261 4262 default: 4263 rc = -ENXIO; 4264 } 4265 4266 4267 mutex_unlock(&fan_mutex); 4268 return rc; 4269} 4270 4271static int fan_set_speed(int speed) 4272{ 4273 int rc; 4274 4275 if (!fan_control_allowed) 4276 return -EPERM; 4277 4278 if (mutex_lock_interruptible(&fan_mutex)) 4279 return -ERESTARTSYS; 4280 4281 rc = 0; 4282 switch (fan_control_access_mode) { 4283 case TPACPI_FAN_WR_ACPI_FANS: 4284 if (speed >= 0 && speed <= 65535) { 4285 if (!acpi_evalf(fans_handle, NULL, NULL, "vddd", 4286 speed, speed, speed)) 4287 rc = -EIO; 4288 } else 4289 rc = -EINVAL; 4290 break; 4291 4292 default: 4293 rc = -ENXIO; 4294 } 4295 4296 mutex_unlock(&fan_mutex); 4297 return rc; 4298} 4299 4300static int fan_read(char *p) 4301{ 4302 int len = 0; 4303 int rc; 4304 u8 status; 4305 unsigned int speed = 0; 4306 4307 switch (fan_status_access_mode) { 4308 case TPACPI_FAN_RD_ACPI_GFAN: 4309 /* 570, 600e/x, 770e, 770x */ 4310 if ((rc = fan_get_status_safe(&status)) < 0) 4311 return rc; 4312 4313 len += sprintf(p + len, "status:\t\t%s\n" 4314 "level:\t\t%d\n", 4315 (status != 0) ? "enabled" : "disabled", status); 4316 break; 4317 4318 case TPACPI_FAN_RD_TPEC: 4319 /* all except 570, 600e/x, 770e, 770x */ 4320 if ((rc = fan_get_status_safe(&status)) < 0) 4321 return rc; 4322 4323 if (unlikely(tp_features.fan_ctrl_status_undef)) { 4324 if (status != fan_control_initial_status) 4325 tp_features.fan_ctrl_status_undef = 0; 4326 else 4327 /* Return most likely status. In fact, it 4328 * might be the only possible status */ 4329 status = TP_EC_FAN_AUTO; 4330 } 4331 4332 len += sprintf(p + len, "status:\t\t%s\n", 4333 (status != 0) ? "enabled" : "disabled"); 4334 4335 if ((rc = fan_get_speed(&speed)) < 0) 4336 return rc; 4337 4338 len += sprintf(p + len, "speed:\t\t%d\n", speed); 4339 4340 if (status & TP_EC_FAN_FULLSPEED) 4341 /* Disengaged mode takes precedence */ 4342 len += sprintf(p + len, "level:\t\tdisengaged\n"); 4343 else if (status & TP_EC_FAN_AUTO) 4344 len += sprintf(p + len, "level:\t\tauto\n"); 4345 else 4346 len += sprintf(p + len, "level:\t\t%d\n", status); 4347 break; 4348 4349 case TPACPI_FAN_NONE: 4350 default: 4351 len += sprintf(p + len, "status:\t\tnot supported\n"); 4352 } 4353 4354 if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) { 4355 len += sprintf(p + len, "commands:\tlevel <level>"); 4356 4357 switch (fan_control_access_mode) { 4358 case TPACPI_FAN_WR_ACPI_SFAN: 4359 len += sprintf(p + len, " (<level> is 0-7)\n"); 4360 break; 4361 4362 default: 4363 len += sprintf(p + len, " (<level> is 0-7, " 4364 "auto, disengaged, full-speed)\n"); 4365 break; 4366 } 4367 } 4368 4369 if (fan_control_commands & TPACPI_FAN_CMD_ENABLE) 4370 len += sprintf(p + len, "commands:\tenable, disable\n" 4371 "commands:\twatchdog <timeout> (<timeout> is 0 (off), " 4372 "1-120 (seconds))\n"); 4373 4374 if (fan_control_commands & TPACPI_FAN_CMD_SPEED) 4375 len += sprintf(p + len, "commands:\tspeed <speed>" 4376 " (<speed> is 0-65535)\n"); 4377 4378 return len; 4379} 4380 4381static int fan_write_cmd_level(const char *cmd, int *rc) 4382{ 4383 int level; 4384 4385 if (strlencmp(cmd, "level auto") == 0) 4386 level = TP_EC_FAN_AUTO; 4387 else if ((strlencmp(cmd, "level disengaged") == 0) | 4388 (strlencmp(cmd, "level full-speed") == 0)) 4389 level = TP_EC_FAN_FULLSPEED; 4390 else if (sscanf(cmd, "level %d", &level) != 1) 4391 return 0; 4392 4393 if ((*rc = fan_set_level_safe(level)) == -ENXIO) 4394 printk(IBM_ERR "level command accepted for unsupported " 4395 "access mode %d", fan_control_access_mode); 4396 4397 return 1; 4398} 4399 4400static int fan_write_cmd_enable(const char *cmd, int *rc) 4401{ 4402 if (strlencmp(cmd, "enable") != 0) 4403 return 0; 4404 4405 if ((*rc = fan_set_enable()) == -ENXIO) 4406 printk(IBM_ERR "enable command accepted for unsupported " 4407 "access mode %d", fan_control_access_mode); 4408 4409 return 1; 4410} 4411 4412static int fan_write_cmd_disable(const char *cmd, int *rc) 4413{ 4414 if (strlencmp(cmd, "disable") != 0) 4415 return 0; 4416 4417 if ((*rc = fan_set_disable()) == -ENXIO) 4418 printk(IBM_ERR "disable command accepted for unsupported " 4419 "access mode %d", fan_control_access_mode); 4420 4421 return 1; 4422} 4423 4424static int fan_write_cmd_speed(const char *cmd, int *rc) 4425{ 4426 int speed; 4427 4428 /* TODO: 4429 * Support speed <low> <medium> <high> ? */ 4430 4431 if (sscanf(cmd, "speed %d", &speed) != 1) 4432 return 0; 4433 4434 if ((*rc = fan_set_speed(speed)) == -ENXIO) 4435 printk(IBM_ERR "speed command accepted for unsupported " 4436 "access mode %d", fan_control_access_mode); 4437 4438 return 1; 4439} 4440 4441static int fan_write_cmd_watchdog(const char *cmd, int *rc) 4442{ 4443 int interval; 4444 4445 if (sscanf(cmd, "watchdog %d", &interval) != 1) 4446 return 0; 4447 4448 if (interval < 0 || interval > 120) 4449 *rc = -EINVAL; 4450 else 4451 fan_watchdog_maxinterval = interval; 4452 4453 return 1; 4454} 4455 4456static int fan_write(char *buf) 4457{ 4458 char *cmd; 4459 int rc = 0; 4460 4461 while (!rc && (cmd = next_cmd(&buf))) { 4462 if (!((fan_control_commands & TPACPI_FAN_CMD_LEVEL) && 4463 fan_write_cmd_level(cmd, &rc)) && 4464 !((fan_control_commands & TPACPI_FAN_CMD_ENABLE) && 4465 (fan_write_cmd_enable(cmd, &rc) || 4466 fan_write_cmd_disable(cmd, &rc) || 4467 fan_write_cmd_watchdog(cmd, &rc))) && 4468 !((fan_control_commands & TPACPI_FAN_CMD_SPEED) && 4469 fan_write_cmd_speed(cmd, &rc)) 4470 ) 4471 rc = -EINVAL; 4472 else if (!rc) 4473 fan_watchdog_reset(); 4474 } 4475 4476 return rc; 4477} 4478 4479static struct ibm_struct fan_driver_data = { 4480 .name = "fan", 4481 .read = fan_read, 4482 .write = fan_write, 4483 .exit = fan_exit, 4484}; 4485 4486/**************************************************************************** 4487 **************************************************************************** 4488 * 4489 * Infrastructure 4490 * 4491 **************************************************************************** 4492 ****************************************************************************/ 4493 4494/* sysfs name ---------------------------------------------------------- */ 4495static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev, 4496 struct device_attribute *attr, 4497 char *buf) 4498{ 4499 return snprintf(buf, PAGE_SIZE, "%s\n", IBM_NAME); 4500} 4501 4502static struct device_attribute dev_attr_thinkpad_acpi_pdev_name = 4503 __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL); 4504 4505/* --------------------------------------------------------------------- */ 4506 4507/* /proc support */ 4508static struct proc_dir_entry *proc_dir; 4509 4510/* Subdriver registry */ 4511static LIST_HEAD(tpacpi_all_drivers); 4512 4513 4514/* 4515 * Module and infrastructure proble, init and exit handling 4516 */ 4517 4518#ifdef CONFIG_THINKPAD_ACPI_DEBUG 4519static const char * __init str_supported(int is_supported) 4520{ 4521 static char text_unsupported[] __initdata = "not supported"; 4522 4523 return (is_supported)? &text_unsupported[4] : &text_unsupported[0]; 4524} 4525#endif /* CONFIG_THINKPAD_ACPI_DEBUG */ 4526 4527static int __init ibm_init(struct ibm_init_struct *iibm) 4528{ 4529 int ret; 4530 struct ibm_struct *ibm = iibm->data; 4531 struct proc_dir_entry *entry; 4532 4533 BUG_ON(ibm == NULL); 4534 4535 INIT_LIST_HEAD(&ibm->all_drivers); 4536 4537 if (ibm->flags.experimental && !experimental) 4538 return 0; 4539 4540 dbg_printk(TPACPI_DBG_INIT, 4541 "probing for %s\n", ibm->name); 4542 4543 if (iibm->init) { 4544 ret = iibm->init(iibm); 4545 if (ret > 0) 4546 return 0; /* probe failed */ 4547 if (ret) 4548 return ret; 4549 4550 ibm->flags.init_called = 1; 4551 } 4552 4553 if (ibm->acpi) { 4554 if (ibm->acpi->hid) { 4555 ret = register_tpacpi_subdriver(ibm); 4556 if (ret) 4557 goto err_out; 4558 } 4559 4560 if (ibm->acpi->notify) { 4561 ret = setup_acpi_notify(ibm); 4562 if (ret == -ENODEV) { 4563 printk(IBM_NOTICE "disabling subdriver %s\n", 4564 ibm->name); 4565 ret = 0; 4566 goto err_out; 4567 } 4568 if (ret < 0) 4569 goto err_out; 4570 } 4571 } 4572 4573 dbg_printk(TPACPI_DBG_INIT, 4574 "%s installed\n", ibm->name); 4575 4576 if (ibm->read) { 4577 entry = create_proc_entry(ibm->name, 4578 S_IFREG | S_IRUGO | S_IWUSR, 4579 proc_dir); 4580 if (!entry) { 4581 printk(IBM_ERR "unable to create proc entry %s\n", 4582 ibm->name); 4583 ret = -ENODEV; 4584 goto err_out; 4585 } 4586 entry->owner = THIS_MODULE; 4587 entry->data = ibm; 4588 entry->read_proc = &dispatch_procfs_read; 4589 if (ibm->write) 4590 entry->write_proc = &dispatch_procfs_write; 4591 ibm->flags.proc_created = 1; 4592 } 4593 4594 list_add_tail(&ibm->all_drivers, &tpacpi_all_drivers); 4595 4596 return 0; 4597 4598err_out: 4599 dbg_printk(TPACPI_DBG_INIT, 4600 "%s: at error exit path with result %d\n", 4601 ibm->name, ret); 4602 4603 ibm_exit(ibm); 4604 return (ret < 0)? ret : 0; 4605} 4606 4607static void ibm_exit(struct ibm_struct *ibm) 4608{ 4609 dbg_printk(TPACPI_DBG_EXIT, "removing %s\n", ibm->name); 4610 4611 list_del_init(&ibm->all_drivers); 4612 4613 if (ibm->flags.acpi_notify_installed) { 4614 dbg_printk(TPACPI_DBG_EXIT, 4615 "%s: acpi_remove_notify_handler\n", ibm->name); 4616 BUG_ON(!ibm->acpi); 4617 acpi_remove_notify_handler(*ibm->acpi->handle, 4618 ibm->acpi->type, 4619 dispatch_acpi_notify); 4620 ibm->flags.acpi_notify_installed = 0; 4621 ibm->flags.acpi_notify_installed = 0; 4622 } 4623 4624 if (ibm->flags.proc_created) { 4625 dbg_printk(TPACPI_DBG_EXIT, 4626 "%s: remove_proc_entry\n", ibm->name); 4627 remove_proc_entry(ibm->name, proc_dir); 4628 ibm->flags.proc_created = 0; 4629 } 4630 4631 if (ibm->flags.acpi_driver_registered) { 4632 dbg_printk(TPACPI_DBG_EXIT, 4633 "%s: acpi_bus_unregister_driver\n", ibm->name); 4634 BUG_ON(!ibm->acpi); 4635 acpi_bus_unregister_driver(ibm->acpi->driver); 4636 kfree(ibm->acpi->driver); 4637 ibm->acpi->driver = NULL; 4638 ibm->flags.acpi_driver_registered = 0; 4639 } 4640 4641 if (ibm->flags.init_called && ibm->exit) { 4642 ibm->exit(); 4643 ibm->flags.init_called = 0; 4644 } 4645 4646 dbg_printk(TPACPI_DBG_INIT, "finished removing %s\n", ibm->name); 4647} 4648 4649/* Probing */ 4650 4651static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp) 4652{ 4653 const struct dmi_device *dev = NULL; 4654 char ec_fw_string[18]; 4655 4656 if (!tp) 4657 return; 4658 4659 memset(tp, 0, sizeof(*tp)); 4660 4661 if (dmi_name_in_vendors("IBM")) 4662 tp->vendor = PCI_VENDOR_ID_IBM; 4663 else if (dmi_name_in_vendors("LENOVO")) 4664 tp->vendor = PCI_VENDOR_ID_LENOVO; 4665 else 4666 return; 4667 4668 tp->bios_version_str = kstrdup(dmi_get_system_info(DMI_BIOS_VERSION), 4669 GFP_KERNEL); 4670 if (!tp->bios_version_str) 4671 return; 4672 tp->bios_model = tp->bios_version_str[0] 4673 | (tp->bios_version_str[1] << 8); 4674 4675 /* 4676 * ThinkPad T23 or newer, A31 or newer, R50e or newer, 4677 * X32 or newer, all Z series; Some models must have an 4678 * up-to-date BIOS or they will not be detected. 4679 * 4680 * See http://thinkwiki.org/wiki/List_of_DMI_IDs 4681 */ 4682 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { 4683 if (sscanf(dev->name, 4684 "IBM ThinkPad Embedded Controller -[%17c", 4685 ec_fw_string) == 1) { 4686 ec_fw_string[sizeof(ec_fw_string) - 1] = 0; 4687 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0; 4688 4689 tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL); 4690 tp->ec_model = ec_fw_string[0] 4691 | (ec_fw_string[1] << 8); 4692 break; 4693 } 4694 } 4695 4696 tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION), 4697 GFP_KERNEL); 4698 if (strnicmp(tp->model_str, "ThinkPad", 8) != 0) { 4699 kfree(tp->model_str); 4700 tp->model_str = NULL; 4701 } 4702} 4703 4704static int __init probe_for_thinkpad(void) 4705{ 4706 int is_thinkpad; 4707 4708 if (acpi_disabled) 4709 return -ENODEV; 4710 4711 /* 4712 * Non-ancient models have better DMI tagging, but very old models 4713 * don't. 4714 */ 4715 is_thinkpad = (thinkpad_id.model_str != NULL); 4716 4717 /* ec is required because many other handles are relative to it */ 4718 IBM_ACPIHANDLE_INIT(ec); 4719 if (!ec_handle) { 4720 if (is_thinkpad) 4721 printk(IBM_ERR 4722 "Not yet supported ThinkPad detected!\n"); 4723 return -ENODEV; 4724 } 4725 4726 /* 4727 * Risks a regression on very old machines, but reduces potential 4728 * false positives a damn great deal 4729 */ 4730 if (!is_thinkpad) 4731 is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM); 4732 4733 if (!is_thinkpad && !force_load) 4734 return -ENODEV; 4735 4736 return 0; 4737} 4738 4739 4740/* Module init, exit, parameters */ 4741 4742static struct ibm_init_struct ibms_init[] __initdata = { 4743 { 4744 .init = thinkpad_acpi_driver_init, 4745 .data = &thinkpad_acpi_driver_data, 4746 }, 4747 { 4748 .init = hotkey_init, 4749 .data = &hotkey_driver_data, 4750 }, 4751 { 4752 .init = bluetooth_init, 4753 .data = &bluetooth_driver_data, 4754 }, 4755 { 4756 .init = wan_init, 4757 .data = &wan_driver_data, 4758 }, 4759 { 4760 .init = video_init, 4761 .data = &video_driver_data, 4762 }, 4763 { 4764 .init = light_init, 4765 .data = &light_driver_data, 4766 }, 4767#ifdef CONFIG_THINKPAD_ACPI_DOCK 4768 { 4769 .init = dock_init, 4770 .data = &dock_driver_data[0], 4771 }, 4772 { 4773 .init = dock_init2, 4774 .data = &dock_driver_data[1], 4775 }, 4776#endif 4777#ifdef CONFIG_THINKPAD_ACPI_BAY 4778 { 4779 .init = bay_init, 4780 .data = &bay_driver_data, 4781 }, 4782#endif 4783 { 4784 .init = cmos_init, 4785 .data = &cmos_driver_data, 4786 }, 4787 { 4788 .init = led_init, 4789 .data = &led_driver_data, 4790 }, 4791 { 4792 .init = beep_init, 4793 .data = &beep_driver_data, 4794 }, 4795 { 4796 .init = thermal_init, 4797 .data = &thermal_driver_data, 4798 }, 4799 { 4800 .data = &ecdump_driver_data, 4801 }, 4802 { 4803 .init = brightness_init, 4804 .data = &brightness_driver_data, 4805 }, 4806 { 4807 .data = &volume_driver_data, 4808 }, 4809 { 4810 .init = fan_init, 4811 .data = &fan_driver_data, 4812 }, 4813}; 4814 4815static int __init set_ibm_param(const char *val, struct kernel_param *kp) 4816{ 4817 unsigned int i; 4818 struct ibm_struct *ibm; 4819 4820 if (!kp || !kp->name || !val) 4821 return -EINVAL; 4822 4823 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { 4824 ibm = ibms_init[i].data; 4825 WARN_ON(ibm == NULL); 4826 4827 if (!ibm || !ibm->name) 4828 continue; 4829 4830 if (strcmp(ibm->name, kp->name) == 0 && ibm->write) { 4831 if (strlen(val) > sizeof(ibms_init[i].param) - 2) 4832 return -ENOSPC; 4833 strcpy(ibms_init[i].param, val); 4834 strcat(ibms_init[i].param, ","); 4835 return 0; 4836 } 4837 } 4838 4839 return -EINVAL; 4840} 4841 4842static int experimental; 4843module_param(experimental, int, 0); 4844 4845static u32 dbg_level; 4846module_param_named(debug, dbg_level, uint, 0); 4847 4848static int force_load; 4849module_param(force_load, bool, 0); 4850 4851static int fan_control_allowed; 4852module_param_named(fan_control, fan_control_allowed, bool, 0); 4853 4854static int brightness_mode; 4855module_param_named(brightness_mode, brightness_mode, int, 0); 4856 4857static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */ 4858module_param(brightness_enable, uint, 0); 4859 4860static unsigned int hotkey_report_mode; 4861module_param(hotkey_report_mode, uint, 0); 4862 4863#define IBM_PARAM(feature) \ 4864 module_param_call(feature, set_ibm_param, NULL, NULL, 0) 4865 4866IBM_PARAM(hotkey); 4867IBM_PARAM(bluetooth); 4868IBM_PARAM(video); 4869IBM_PARAM(light); 4870#ifdef CONFIG_THINKPAD_ACPI_DOCK 4871IBM_PARAM(dock); 4872#endif 4873#ifdef CONFIG_THINKPAD_ACPI_BAY 4874IBM_PARAM(bay); 4875#endif /* CONFIG_THINKPAD_ACPI_BAY */ 4876IBM_PARAM(cmos); 4877IBM_PARAM(led); 4878IBM_PARAM(beep); 4879IBM_PARAM(ecdump); 4880IBM_PARAM(brightness); 4881IBM_PARAM(volume); 4882IBM_PARAM(fan); 4883 4884static int __init thinkpad_acpi_module_init(void) 4885{ 4886 int ret, i; 4887 4888 tpacpi_lifecycle = TPACPI_LIFE_INIT; 4889 4890 /* Parameter checking */ 4891 if (hotkey_report_mode > 2) 4892 return -EINVAL; 4893 4894 /* Driver-level probe */ 4895 4896 get_thinkpad_model_data(&thinkpad_id); 4897 ret = probe_for_thinkpad(); 4898 if (ret) { 4899 thinkpad_acpi_module_exit(); 4900 return ret; 4901 } 4902 4903 /* Driver initialization */ 4904 4905 IBM_ACPIHANDLE_INIT(ecrd); 4906 IBM_ACPIHANDLE_INIT(ecwr); 4907 4908 proc_dir = proc_mkdir(IBM_PROC_DIR, acpi_root_dir); 4909 if (!proc_dir) { 4910 printk(IBM_ERR "unable to create proc dir " IBM_PROC_DIR); 4911 thinkpad_acpi_module_exit(); 4912 return -ENODEV; 4913 } 4914 proc_dir->owner = THIS_MODULE; 4915 4916 ret = platform_driver_register(&tpacpi_pdriver); 4917 if (ret) { 4918 printk(IBM_ERR "unable to register main platform driver\n"); 4919 thinkpad_acpi_module_exit(); 4920 return ret; 4921 } 4922 tp_features.platform_drv_registered = 1; 4923 4924 ret = platform_driver_register(&tpacpi_hwmon_pdriver); 4925 if (ret) { 4926 printk(IBM_ERR "unable to register hwmon platform driver\n"); 4927 thinkpad_acpi_module_exit(); 4928 return ret; 4929 } 4930 tp_features.sensors_pdrv_registered = 1; 4931 4932 ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver); 4933 if (!ret) { 4934 tp_features.platform_drv_attrs_registered = 1; 4935 ret = tpacpi_create_driver_attributes(&tpacpi_hwmon_pdriver.driver); 4936 } 4937 if (ret) { 4938 printk(IBM_ERR "unable to create sysfs driver attributes\n"); 4939 thinkpad_acpi_module_exit(); 4940 return ret; 4941 } 4942 tp_features.sensors_pdrv_attrs_registered = 1; 4943 4944 4945 /* Device initialization */ 4946 tpacpi_pdev = platform_device_register_simple(IBM_DRVR_NAME, -1, 4947 NULL, 0); 4948 if (IS_ERR(tpacpi_pdev)) { 4949 ret = PTR_ERR(tpacpi_pdev); 4950 tpacpi_pdev = NULL; 4951 printk(IBM_ERR "unable to register platform device\n"); 4952 thinkpad_acpi_module_exit(); 4953 return ret; 4954 } 4955 tpacpi_sensors_pdev = platform_device_register_simple( 4956 IBM_HWMON_DRVR_NAME, 4957 -1, NULL, 0); 4958 if (IS_ERR(tpacpi_sensors_pdev)) { 4959 ret = PTR_ERR(tpacpi_sensors_pdev); 4960 tpacpi_sensors_pdev = NULL; 4961 printk(IBM_ERR "unable to register hwmon platform device\n"); 4962 thinkpad_acpi_module_exit(); 4963 return ret; 4964 } 4965 ret = device_create_file(&tpacpi_sensors_pdev->dev, 4966 &dev_attr_thinkpad_acpi_pdev_name); 4967 if (ret) { 4968 printk(IBM_ERR 4969 "unable to create sysfs hwmon device attributes\n"); 4970 thinkpad_acpi_module_exit(); 4971 return ret; 4972 } 4973 tp_features.sensors_pdev_attrs_registered = 1; 4974 tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev); 4975 if (IS_ERR(tpacpi_hwmon)) { 4976 ret = PTR_ERR(tpacpi_hwmon); 4977 tpacpi_hwmon = NULL; 4978 printk(IBM_ERR "unable to register hwmon device\n"); 4979 thinkpad_acpi_module_exit(); 4980 return ret; 4981 } 4982 mutex_init(&tpacpi_inputdev_send_mutex); 4983 tpacpi_inputdev = input_allocate_device(); 4984 if (!tpacpi_inputdev) { 4985 printk(IBM_ERR "unable to allocate input device\n"); 4986 thinkpad_acpi_module_exit(); 4987 return -ENOMEM; 4988 } else { 4989 /* Prepare input device, but don't register */ 4990 tpacpi_inputdev->name = "ThinkPad Extra Buttons"; 4991 tpacpi_inputdev->phys = IBM_DRVR_NAME "/input0"; 4992 tpacpi_inputdev->id.bustype = BUS_HOST; 4993 tpacpi_inputdev->id.vendor = (thinkpad_id.vendor) ? 4994 thinkpad_id.vendor : 4995 PCI_VENDOR_ID_IBM; 4996 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT; 4997 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION; 4998 } 4999 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { 5000 ret = ibm_init(&ibms_init[i]); 5001 if (ret >= 0 && *ibms_init[i].param) 5002 ret = ibms_init[i].data->write(ibms_init[i].param); 5003 if (ret < 0) { 5004 thinkpad_acpi_module_exit(); 5005 return ret; 5006 } 5007 } 5008 ret = input_register_device(tpacpi_inputdev); 5009 if (ret < 0) { 5010 printk(IBM_ERR "unable to register input device\n"); 5011 thinkpad_acpi_module_exit(); 5012 return ret; 5013 } else { 5014 tp_features.input_device_registered = 1; 5015 } 5016 5017 tpacpi_lifecycle = TPACPI_LIFE_RUNNING; 5018 return 0; 5019} 5020 5021static void thinkpad_acpi_module_exit(void) 5022{ 5023 struct ibm_struct *ibm, *itmp; 5024 5025 tpacpi_lifecycle = TPACPI_LIFE_EXITING; 5026 5027 list_for_each_entry_safe_reverse(ibm, itmp, 5028 &tpacpi_all_drivers, 5029 all_drivers) { 5030 ibm_exit(ibm); 5031 } 5032 5033 dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n"); 5034 5035 if (tpacpi_inputdev) { 5036 if (tp_features.input_device_registered) 5037 input_unregister_device(tpacpi_inputdev); 5038 else 5039 input_free_device(tpacpi_inputdev); 5040 } 5041 5042 if (tpacpi_hwmon) 5043 hwmon_device_unregister(tpacpi_hwmon); 5044 5045 if (tp_features.sensors_pdev_attrs_registered) 5046 device_remove_file(&tpacpi_sensors_pdev->dev, 5047 &dev_attr_thinkpad_acpi_pdev_name); 5048 if (tpacpi_sensors_pdev) 5049 platform_device_unregister(tpacpi_sensors_pdev); 5050 if (tpacpi_pdev) 5051 platform_device_unregister(tpacpi_pdev); 5052 5053 if (tp_features.sensors_pdrv_attrs_registered) 5054 tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver); 5055 if (tp_features.platform_drv_attrs_registered) 5056 tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver); 5057 5058 if (tp_features.sensors_pdrv_registered) 5059 platform_driver_unregister(&tpacpi_hwmon_pdriver); 5060 5061 if (tp_features.platform_drv_registered) 5062 platform_driver_unregister(&tpacpi_pdriver); 5063 5064 if (proc_dir) 5065 remove_proc_entry(IBM_PROC_DIR, acpi_root_dir); 5066 5067 kfree(thinkpad_id.bios_version_str); 5068 kfree(thinkpad_id.ec_version_str); 5069 kfree(thinkpad_id.model_str); 5070} 5071 5072module_init(thinkpad_acpi_module_init); 5073module_exit(thinkpad_acpi_module_exit);