linux/drivers/misc/thinkpad_acpi.c
<<
>>
Prefs
   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);
5074