ACPI: thinkpad-acpi: prepare for NVRAM polling support
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / misc / thinkpad_acpi.c
blobe7ac1c8a5541cf2a8bb4b1c25cd72051857346f2
1 /*
2 * thinkpad_acpi.c - ThinkPad ACPI Extras
5 * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
6 * Copyright (C) 2006-2007 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
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.
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.
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.
24 #define IBM_VERSION "0.17"
25 #define TPACPI_SYSFS_VERSION 0x020000
28 * Changelog:
29 * 2007-03-27 0.14 renamed to thinkpad_acpi and moved to
30 * drivers/misc.
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.
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
85 #include "thinkpad_acpi.h"
87 MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh");
88 MODULE_DESCRIPTION(IBM_DESC);
89 MODULE_VERSION(IBM_VERSION);
90 MODULE_LICENSE("GPL");
92 /* Please remove this in year 2009 */
93 MODULE_ALIAS("ibm_acpi");
96 * DMI matching for module autoloading
98 * See http://thinkwiki.org/wiki/List_of_DMI_IDs
99 * See http://thinkwiki.org/wiki/BIOS_Upgrade_Downloads
101 * Only models listed in thinkwiki will be supported, so add yours
102 * if it is not there yet.
104 #define IBM_BIOS_MODULE_ALIAS(__type) \
105 MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW")
107 /* Non-ancient thinkpads */
108 MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*");
109 MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*");
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... */
114 IBM_BIOS_MODULE_ALIAS("I[B,D,H,I,M,N,O,T,W,V,Y,Z]");
115 IBM_BIOS_MODULE_ALIAS("1[0,3,6,8,A-G,I,K,M-P,S,T]");
116 IBM_BIOS_MODULE_ALIAS("K[U,X-Z]");
118 #define __unused __attribute__ ((unused))
120 static enum {
121 TPACPI_LIFE_INIT = 0,
122 TPACPI_LIFE_RUNNING,
123 TPACPI_LIFE_EXITING,
124 } tpacpi_lifecycle;
126 /****************************************************************************
127 ****************************************************************************
129 * ACPI Helpers and device model
131 ****************************************************************************
132 ****************************************************************************/
134 /*************************************************************************
135 * ACPI basic handles
138 static acpi_handle root_handle;
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 }
146 IBM_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 */
155 IBM_HANDLE(ecrd, ec, "ECRD"); /* 570 */
156 IBM_HANDLE(ecwr, ec, "ECWR"); /* 570 */
159 /*************************************************************************
160 * Misc ACPI handles
163 IBM_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 */
168 IBM_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */
169 "^HKEY", /* R30, R31 */
170 "HKEY", /* all others */
171 ); /* 570 */
174 /*************************************************************************
175 * ACPI helpers
178 static int acpi_evalf(acpi_handle handle,
179 void *res, char *method, char *fmt, ...)
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;
192 if (!*fmt) {
193 printk(IBM_ERR "acpi_evalf() called with empty format\n");
194 return 0;
197 if (*fmt == 'q') {
198 quiet = 1;
199 fmt++;
200 } else
201 quiet = 0;
203 res_type = *(fmt++);
205 params.count = 0;
206 params.pointer = &in_objs[0];
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;
223 va_end(ap);
225 if (res_type != 'v') {
226 result.length = sizeof(out_obj);
227 result.pointer = &out_obj;
228 resultp = &result;
229 } else
230 resultp = NULL;
232 status = acpi_evaluate_object(handle, method, &params, resultp);
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;
250 if (!success && !quiet)
251 printk(IBM_ERR "acpi_evalf(%s, %s, ...) failed: %d\n",
252 method, fmt0, status);
254 return success;
257 static void __unused acpi_print_int(acpi_handle handle, char *method)
259 int i;
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);
267 static int acpi_ec_read(int i, u8 * p)
269 int v;
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;
280 return 1;
283 static int acpi_ec_write(int i, u8 v)
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;
293 return 1;
296 static int _sta(acpi_handle handle)
298 int status;
300 if (!handle || !acpi_evalf(handle, &status, "_STA", "d"))
301 status = 0;
303 return status;
306 static int issue_thinkpad_cmos_command(int cmos_cmd)
308 if (!cmos_handle)
309 return -ENXIO;
311 if (!acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd))
312 return -EIO;
314 return 0;
317 /*************************************************************************
318 * ACPI device model
321 static void drv_acpi_handle_init(char *name,
322 acpi_handle *handle, acpi_handle parent,
323 char **paths, int num_paths, char **path)
325 int i;
326 acpi_status status;
328 vdbg_printk(TPACPI_DBG_INIT, "trying to locate ACPI handle for %s\n",
329 name);
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;
342 vdbg_printk(TPACPI_DBG_INIT, "ACPI handle for %s not found\n",
343 name);
344 *handle = NULL;
347 static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data)
349 struct ibm_struct *ibm = data;
351 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
352 return;
354 if (!ibm || !ibm->acpi || !ibm->acpi->notify)
355 return;
357 ibm->acpi->notify(ibm, event);
360 static int __init setup_acpi_notify(struct ibm_struct *ibm)
362 acpi_status status;
363 int rc;
365 BUG_ON(!ibm->acpi);
367 if (!*ibm->acpi->handle)
368 return 0;
370 vdbg_printk(TPACPI_DBG_INIT,
371 "setting up ACPI notify for %s\n", ibm->name);
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;
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);
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);
395 return -ENODEV;
397 ibm->flags.acpi_notify_installed = 1;
398 return 0;
401 static int __init tpacpi_device_add(struct acpi_device *device)
403 return 0;
406 static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
408 int rc;
410 dbg_printk(TPACPI_DBG_INIT,
411 "registering %s as an ACPI driver\n", ibm->name);
413 BUG_ON(!ibm->acpi);
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;
421 sprintf(ibm->acpi->driver->name, "%s_%s", IBM_NAME, ibm->name);
422 ibm->acpi->driver->ids = ibm->acpi->hid;
424 ibm->acpi->driver->ops.add = &tpacpi_device_add;
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;
435 return rc;
439 /****************************************************************************
440 ****************************************************************************
442 * Procfs Helpers
444 ****************************************************************************
445 ****************************************************************************/
447 static int dispatch_procfs_read(char *page, char **start, off_t off,
448 int count, int *eof, void *data)
450 struct ibm_struct *ibm = data;
451 int len;
453 if (!ibm || !ibm->read)
454 return -EINVAL;
456 len = ibm->read(page);
457 if (len < 0)
458 return len;
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;
469 return len;
472 static int dispatch_procfs_write(struct file *file,
473 const char __user * userbuf,
474 unsigned long count, void *data)
476 struct ibm_struct *ibm = data;
477 char *kernbuf;
478 int ret;
480 if (!ibm || !ibm->write)
481 return -EINVAL;
483 kernbuf = kmalloc(count + 2, GFP_KERNEL);
484 if (!kernbuf)
485 return -ENOMEM;
487 if (copy_from_user(kernbuf, userbuf, count)) {
488 kfree(kernbuf);
489 return -EFAULT;
492 kernbuf[count] = 0;
493 strcat(kernbuf, ",");
494 ret = ibm->write(kernbuf);
495 if (ret == 0)
496 ret = count;
498 kfree(kernbuf);
500 return ret;
503 static char *next_cmd(char **cmds)
505 char *start = *cmds;
506 char *end;
508 while ((end = strchr(start, ',')) && end == start)
509 start = end + 1;
511 if (!end)
512 return NULL;
514 *end = 0;
515 *cmds = end + 1;
516 return start;
520 /****************************************************************************
521 ****************************************************************************
523 * Device model: input, hwmon and platform
525 ****************************************************************************
526 ****************************************************************************/
528 static struct platform_device *tpacpi_pdev;
529 static struct platform_device *tpacpi_sensors_pdev;
530 static struct device *tpacpi_hwmon;
531 static struct input_dev *tpacpi_inputdev;
532 static struct mutex tpacpi_inputdev_send_mutex;
535 static int tpacpi_resume_handler(struct platform_device *pdev)
537 struct ibm_struct *ibm, *itmp;
539 list_for_each_entry_safe(ibm, itmp,
540 &tpacpi_all_drivers,
541 all_drivers) {
542 if (ibm->resume)
543 (ibm->resume)();
546 return 0;
549 static struct platform_driver tpacpi_pdriver = {
550 .driver = {
551 .name = IBM_DRVR_NAME,
552 .owner = THIS_MODULE,
554 .resume = tpacpi_resume_handler,
557 static struct platform_driver tpacpi_hwmon_pdriver = {
558 .driver = {
559 .name = IBM_HWMON_DRVR_NAME,
560 .owner = THIS_MODULE,
564 /*************************************************************************
565 * thinkpad-acpi driver attributes
568 /* interface_version --------------------------------------------------- */
569 static ssize_t tpacpi_driver_interface_version_show(
570 struct device_driver *drv,
571 char *buf)
573 return snprintf(buf, PAGE_SIZE, "0x%08x\n", TPACPI_SYSFS_VERSION);
576 static DRIVER_ATTR(interface_version, S_IRUGO,
577 tpacpi_driver_interface_version_show, NULL);
579 /* debug_level --------------------------------------------------------- */
580 static ssize_t tpacpi_driver_debug_show(struct device_driver *drv,
581 char *buf)
583 return snprintf(buf, PAGE_SIZE, "0x%04x\n", dbg_level);
586 static ssize_t tpacpi_driver_debug_store(struct device_driver *drv,
587 const char *buf, size_t count)
589 unsigned long t;
591 if (parse_strtoul(buf, 0xffff, &t))
592 return -EINVAL;
594 dbg_level = t;
596 return count;
599 static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
600 tpacpi_driver_debug_show, tpacpi_driver_debug_store);
602 /* version ------------------------------------------------------------- */
603 static ssize_t tpacpi_driver_version_show(struct device_driver *drv,
604 char *buf)
606 return snprintf(buf, PAGE_SIZE, "%s v%s\n", IBM_DESC, IBM_VERSION);
609 static DRIVER_ATTR(version, S_IRUGO,
610 tpacpi_driver_version_show, NULL);
612 /* --------------------------------------------------------------------- */
614 static struct driver_attribute* tpacpi_driver_attributes[] = {
615 &driver_attr_debug_level, &driver_attr_version,
616 &driver_attr_interface_version,
619 static int __init tpacpi_create_driver_attributes(struct device_driver *drv)
621 int i, res;
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++;
630 return res;
633 static void tpacpi_remove_driver_attributes(struct device_driver *drv)
635 int i;
637 for(i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++)
638 driver_remove_file(drv, tpacpi_driver_attributes[i]);
641 /*************************************************************************
642 * sysfs support helpers
645 struct attribute_set_obj {
646 struct attribute_set s;
647 struct attribute *a;
648 } __attribute__((packed));
650 static struct attribute_set *create_attr_set(unsigned int max_members,
651 const char* name)
653 struct attribute_set_obj *sobj;
655 if (max_members == 0)
656 return NULL;
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;
668 return &sobj->s;
671 /* not multi-threaded safe, use it in a single thread per set */
672 static int add_to_attr_set(struct attribute_set* s, struct attribute *attr)
674 if (!s || !attr)
675 return -EINVAL;
677 if (s->members >= s->max_members)
678 return -ENOMEM;
680 s->group.attrs[s->members] = attr;
681 s->members++;
683 return 0;
686 static int add_many_to_attr_set(struct attribute_set* s,
687 struct attribute **attr,
688 unsigned int count)
690 int i, res;
692 for (i = 0; i < count; i++) {
693 res = add_to_attr_set(s, attr[i]);
694 if (res)
695 return res;
698 return 0;
701 static void delete_attr_set(struct attribute_set* s, struct kobject *kobj)
703 sysfs_remove_group(kobj, &s->group);
704 destroy_attr_set(s);
707 static int parse_strtoul(const char *buf,
708 unsigned long max, unsigned long *value)
710 char *endp;
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;
720 return 0;
723 /****************************************************************************
724 ****************************************************************************
726 * Subdrivers
728 ****************************************************************************
729 ****************************************************************************/
731 /*************************************************************************
732 * thinkpad-acpi init subdriver
735 static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
737 printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
738 printk(IBM_INFO "%s\n", IBM_URL);
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");
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);
754 return 0;
757 static int thinkpad_acpi_driver_read(char *p)
759 int len = 0;
761 len += sprintf(p + len, "driver:\t\t%s\n", IBM_DESC);
762 len += sprintf(p + len, "version:\t%s\n", IBM_VERSION);
764 return len;
767 static struct ibm_struct thinkpad_acpi_driver_data = {
768 .name = "driver",
769 .read = thinkpad_acpi_driver_read,
772 /*************************************************************************
773 * Hotkey subdriver
776 static int hotkey_orig_status;
777 static u32 hotkey_orig_mask;
778 static u32 hotkey_all_mask;
779 static u32 hotkey_reserved_mask;
780 static u32 hotkey_mask;
782 static u16 *hotkey_keycode_map;
784 static struct attribute_set *hotkey_dev_attributes;
786 static int hotkey_get_wlsw(int *status)
788 if (!acpi_evalf(hkey_handle, status, "WLSW", "d"))
789 return -EIO;
790 return 0;
794 * Call with hotkey_mutex held
796 static int hotkey_mask_get(void)
798 if (tp_features.hotkey_mask) {
799 if (!acpi_evalf(hkey_handle, &hotkey_mask, "DHKN", "d"))
800 return -EIO;
803 return 0;
807 * Call with hotkey_mutex held
809 static int hotkey_mask_set(u32 mask)
811 int i;
812 int rc = 0;
814 if (tp_features.hotkey_mask) {
815 for (i = 0; i < 32; i++) {
816 u32 m = 1 << i;
817 if (!acpi_evalf(hkey_handle,
818 NULL, "MHKM", "vdd", i + 1,
819 !!(mask & m))) {
820 rc = -EIO;
821 break;
822 } else {
823 hotkey_mask = (hotkey_mask & ~m) | (mask & m);
827 /* hotkey_mask_get must be called unconditionally below */
828 if (!hotkey_mask_get() && !rc && hotkey_mask != mask) {
829 printk(IBM_NOTICE
830 "requested hot key mask 0x%08x, but "
831 "firmware forced it to 0x%08x\n",
832 mask, hotkey_mask);
836 return rc;
839 static int hotkey_status_get(int *status)
841 if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
842 return -EIO;
844 return 0;
847 static int hotkey_status_set(int status)
849 if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
850 return -EIO;
852 return 0;
855 static void tpacpi_input_send_radiosw(void)
857 int wlsw;
859 mutex_lock(&tpacpi_inputdev_send_mutex);
861 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) {
862 input_report_switch(tpacpi_inputdev,
863 SW_RADIO, !!wlsw);
864 input_sync(tpacpi_inputdev);
867 mutex_unlock(&tpacpi_inputdev_send_mutex);
870 static void tpacpi_input_send_key(unsigned int scancode)
872 unsigned int keycode;
874 keycode = hotkey_keycode_map[scancode];
876 if (keycode != KEY_RESERVED) {
877 mutex_lock(&tpacpi_inputdev_send_mutex);
879 input_report_key(tpacpi_inputdev, keycode, 1);
880 if (keycode == KEY_UNKNOWN)
881 input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
882 scancode);
883 input_sync(tpacpi_inputdev);
885 input_report_key(tpacpi_inputdev, keycode, 0);
886 if (keycode == KEY_UNKNOWN)
887 input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
888 scancode);
889 input_sync(tpacpi_inputdev);
891 mutex_unlock(&tpacpi_inputdev_send_mutex);
895 /* sysfs hotkey enable ------------------------------------------------- */
896 static ssize_t hotkey_enable_show(struct device *dev,
897 struct device_attribute *attr,
898 char *buf)
900 int res, status;
902 res = hotkey_status_get(&status);
903 if (res)
904 return res;
906 return snprintf(buf, PAGE_SIZE, "%d\n", status);
909 static ssize_t hotkey_enable_store(struct device *dev,
910 struct device_attribute *attr,
911 const char *buf, size_t count)
913 unsigned long t;
914 int res;
916 if (parse_strtoul(buf, 1, &t))
917 return -EINVAL;
919 res = hotkey_status_set(t);
921 return (res) ? res : count;
924 static struct device_attribute dev_attr_hotkey_enable =
925 __ATTR(hotkey_enable, S_IWUSR | S_IRUGO,
926 hotkey_enable_show, hotkey_enable_store);
928 /* sysfs hotkey mask --------------------------------------------------- */
929 static ssize_t hotkey_mask_show(struct device *dev,
930 struct device_attribute *attr,
931 char *buf)
933 int res;
935 if (mutex_lock_interruptible(&hotkey_mutex))
936 return -ERESTARTSYS;
937 res = hotkey_mask_get();
938 mutex_unlock(&hotkey_mutex);
940 return (res)?
941 res : snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_mask);
944 static ssize_t hotkey_mask_store(struct device *dev,
945 struct device_attribute *attr,
946 const char *buf, size_t count)
948 unsigned long t;
949 int res;
951 if (parse_strtoul(buf, 0xffffffffUL, &t))
952 return -EINVAL;
954 if (mutex_lock_interruptible(&hotkey_mutex))
955 return -ERESTARTSYS;
957 res = hotkey_mask_set(t);
958 mutex_unlock(&hotkey_mutex);
960 return (res) ? res : count;
963 static struct device_attribute dev_attr_hotkey_mask =
964 __ATTR(hotkey_mask, S_IWUSR | S_IRUGO,
965 hotkey_mask_show, hotkey_mask_store);
967 /* sysfs hotkey bios_enabled ------------------------------------------- */
968 static ssize_t hotkey_bios_enabled_show(struct device *dev,
969 struct device_attribute *attr,
970 char *buf)
972 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status);
975 static struct device_attribute dev_attr_hotkey_bios_enabled =
976 __ATTR(hotkey_bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL);
978 /* sysfs hotkey bios_mask ---------------------------------------------- */
979 static ssize_t hotkey_bios_mask_show(struct device *dev,
980 struct device_attribute *attr,
981 char *buf)
983 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask);
986 static struct device_attribute dev_attr_hotkey_bios_mask =
987 __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL);
989 /* sysfs hotkey all_mask ----------------------------------------------- */
990 static ssize_t hotkey_all_mask_show(struct device *dev,
991 struct device_attribute *attr,
992 char *buf)
994 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_all_mask);
997 static struct device_attribute dev_attr_hotkey_all_mask =
998 __ATTR(hotkey_all_mask, S_IRUGO, hotkey_all_mask_show, NULL);
1000 /* sysfs hotkey recommended_mask --------------------------------------- */
1001 static ssize_t hotkey_recommended_mask_show(struct device *dev,
1002 struct device_attribute *attr,
1003 char *buf)
1005 return snprintf(buf, PAGE_SIZE, "0x%08x\n",
1006 hotkey_all_mask & ~hotkey_reserved_mask);
1009 static struct device_attribute dev_attr_hotkey_recommended_mask =
1010 __ATTR(hotkey_recommended_mask, S_IRUGO,
1011 hotkey_recommended_mask_show, NULL);
1013 /* sysfs hotkey radio_sw ----------------------------------------------- */
1014 static ssize_t hotkey_radio_sw_show(struct device *dev,
1015 struct device_attribute *attr,
1016 char *buf)
1018 int res, s;
1019 res = hotkey_get_wlsw(&s);
1020 if (res < 0)
1021 return res;
1023 return snprintf(buf, PAGE_SIZE, "%d\n", !!s);
1026 static struct device_attribute dev_attr_hotkey_radio_sw =
1027 __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL);
1029 /* sysfs hotkey report_mode -------------------------------------------- */
1030 static ssize_t hotkey_report_mode_show(struct device *dev,
1031 struct device_attribute *attr,
1032 char *buf)
1034 return snprintf(buf, PAGE_SIZE, "%d\n",
1035 (hotkey_report_mode != 0) ? hotkey_report_mode : 1);
1038 static struct device_attribute dev_attr_hotkey_report_mode =
1039 __ATTR(hotkey_report_mode, S_IRUGO, hotkey_report_mode_show, NULL);
1041 /* --------------------------------------------------------------------- */
1043 static struct attribute *hotkey_attributes[] __initdata = {
1044 &dev_attr_hotkey_enable.attr,
1045 &dev_attr_hotkey_report_mode.attr,
1048 static struct attribute *hotkey_mask_attributes[] __initdata = {
1049 &dev_attr_hotkey_mask.attr,
1050 &dev_attr_hotkey_bios_enabled.attr,
1051 &dev_attr_hotkey_bios_mask.attr,
1052 &dev_attr_hotkey_all_mask.attr,
1053 &dev_attr_hotkey_recommended_mask.attr,
1056 static int __init hotkey_init(struct ibm_init_struct *iibm)
1058 /* Requirements for changing the default keymaps:
1060 * 1. Many of the keys are mapped to KEY_RESERVED for very
1061 * good reasons. Do not change them unless you have deep
1062 * knowledge on the IBM and Lenovo ThinkPad firmware for
1063 * the various ThinkPad models. The driver behaves
1064 * differently for KEY_RESERVED: such keys have their
1065 * hot key mask *unset* in mask_recommended, and also
1066 * in the initial hot key mask programmed into the
1067 * firmware at driver load time, which means the firm-
1068 * ware may react very differently if you change them to
1069 * something else;
1071 * 2. You must be subscribed to the linux-thinkpad and
1072 * ibm-acpi-devel mailing lists, and you should read the
1073 * list archives since 2007 if you want to change the
1074 * keymaps. This requirement exists so that you will
1075 * know the past history of problems with the thinkpad-
1076 * acpi driver keymaps, and also that you will be
1077 * listening to any bug reports;
1079 * 3. Do not send thinkpad-acpi specific patches directly to
1080 * for merging, *ever*. Send them to the linux-acpi
1081 * mailinglist for comments. Merging is to be done only
1082 * through acpi-test and the ACPI maintainer.
1084 * If the above is too much to ask, don't change the keymap.
1085 * Ask the thinkpad-acpi maintainer to do it, instead.
1087 static u16 ibm_keycode_map[] __initdata = {
1088 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
1089 KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP,
1090 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
1091 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
1093 /* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */
1094 KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */
1095 KEY_UNKNOWN, /* 0x0D: FN+INSERT */
1096 KEY_UNKNOWN, /* 0x0E: FN+DELETE */
1098 /* brightness: firmware always reacts to them, unless
1099 * X.org did some tricks in the radeon BIOS scratch
1100 * registers of *some* models */
1101 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
1102 KEY_RESERVED, /* 0x10: FN+END (brightness down) */
1104 /* Thinklight: firmware always react to it */
1105 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
1107 KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
1108 KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
1110 /* Volume: firmware always react to it and reprograms
1111 * the built-in *extra* mixer. Never map it to control
1112 * another mixer by default. */
1113 KEY_RESERVED, /* 0x14: VOLUME UP */
1114 KEY_RESERVED, /* 0x15: VOLUME DOWN */
1115 KEY_RESERVED, /* 0x16: MUTE */
1117 KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
1119 /* (assignments unknown, please report if found) */
1120 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
1121 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
1123 static u16 lenovo_keycode_map[] __initdata = {
1124 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
1125 KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP,
1126 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
1127 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
1129 /* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */
1130 KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */
1131 KEY_UNKNOWN, /* 0x0D: FN+INSERT */
1132 KEY_UNKNOWN, /* 0x0E: FN+DELETE */
1134 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
1135 KEY_RESERVED, /* 0x10: FN+END (brightness down) */
1137 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
1139 KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
1140 KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
1142 /* Volume: z60/z61, T60 (BIOS version?): firmware always
1143 * react to it and reprograms the built-in *extra* mixer.
1144 * Never map it to control another mixer by default.
1146 * T60?, T61, R60?, R61: firmware and EC tries to send
1147 * these over the regular keyboard, so these are no-ops,
1148 * but there are still weird bugs re. MUTE, so do not
1149 * change unless you get test reports from all Lenovo
1150 * models. May cause the BIOS to interfere with the
1151 * HDA mixer.
1153 KEY_RESERVED, /* 0x14: VOLUME UP */
1154 KEY_RESERVED, /* 0x15: VOLUME DOWN */
1155 KEY_RESERVED, /* 0x16: MUTE */
1157 KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
1159 /* (assignments unknown, please report if found) */
1160 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
1161 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
1164 #define TPACPI_HOTKEY_MAP_LEN ARRAY_SIZE(ibm_keycode_map)
1165 #define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map)
1166 #define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0])
1168 int res, i;
1169 int status;
1170 int hkeyv;
1172 vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
1174 BUG_ON(!tpacpi_inputdev);
1176 IBM_ACPIHANDLE_INIT(hkey);
1177 mutex_init(&hotkey_mutex);
1179 /* hotkey not supported on 570 */
1180 tp_features.hotkey = hkey_handle != NULL;
1182 vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n",
1183 str_supported(tp_features.hotkey));
1185 if (tp_features.hotkey) {
1186 hotkey_dev_attributes = create_attr_set(8, NULL);
1187 if (!hotkey_dev_attributes)
1188 return -ENOMEM;
1189 res = add_many_to_attr_set(hotkey_dev_attributes,
1190 hotkey_attributes,
1191 ARRAY_SIZE(hotkey_attributes));
1192 if (res)
1193 return res;
1195 /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
1196 A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking
1197 for HKEY interface version 0x100 */
1198 if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
1199 if ((hkeyv >> 8) != 1) {
1200 printk(IBM_ERR "unknown version of the "
1201 "HKEY interface: 0x%x\n", hkeyv);
1202 printk(IBM_ERR "please report this to %s\n",
1203 IBM_MAIL);
1204 } else {
1206 * MHKV 0x100 in A31, R40, R40e,
1207 * T4x, X31, and later
1208 * */
1209 tp_features.hotkey_mask = 1;
1213 vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
1214 str_supported(tp_features.hotkey_mask));
1216 if (tp_features.hotkey_mask) {
1217 if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
1218 "MHKA", "qd")) {
1219 printk(IBM_ERR
1220 "missing MHKA handler, "
1221 "please report this to %s\n",
1222 IBM_MAIL);
1223 hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */
1227 res = hotkey_status_get(&hotkey_orig_status);
1228 if (!res && tp_features.hotkey_mask) {
1229 res = hotkey_mask_get();
1230 hotkey_orig_mask = hotkey_mask;
1231 if (!res) {
1232 res = add_many_to_attr_set(
1233 hotkey_dev_attributes,
1234 hotkey_mask_attributes,
1235 ARRAY_SIZE(hotkey_mask_attributes));
1239 /* Not all thinkpads have a hardware radio switch */
1240 if (!res && acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
1241 tp_features.hotkey_wlsw = 1;
1242 printk(IBM_INFO
1243 "radio switch found; radios are %s\n",
1244 enabled(status, 0));
1245 res = add_to_attr_set(hotkey_dev_attributes,
1246 &dev_attr_hotkey_radio_sw.attr);
1249 if (!res)
1250 res = register_attr_set_with_sysfs(
1251 hotkey_dev_attributes,
1252 &tpacpi_pdev->dev.kobj);
1253 if (res)
1254 return res;
1256 /* Set up key map */
1258 hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
1259 GFP_KERNEL);
1260 if (!hotkey_keycode_map) {
1261 printk(IBM_ERR "failed to allocate memory for key map\n");
1262 return -ENOMEM;
1265 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
1266 dbg_printk(TPACPI_DBG_INIT,
1267 "using Lenovo default hot key map\n");
1268 memcpy(hotkey_keycode_map, &lenovo_keycode_map,
1269 TPACPI_HOTKEY_MAP_SIZE);
1270 } else {
1271 dbg_printk(TPACPI_DBG_INIT,
1272 "using IBM default hot key map\n");
1273 memcpy(hotkey_keycode_map, &ibm_keycode_map,
1274 TPACPI_HOTKEY_MAP_SIZE);
1277 set_bit(EV_KEY, tpacpi_inputdev->evbit);
1278 set_bit(EV_MSC, tpacpi_inputdev->evbit);
1279 set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
1280 tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
1281 tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN;
1282 tpacpi_inputdev->keycode = hotkey_keycode_map;
1283 for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) {
1284 if (hotkey_keycode_map[i] != KEY_RESERVED) {
1285 set_bit(hotkey_keycode_map[i],
1286 tpacpi_inputdev->keybit);
1287 } else {
1288 if (i < sizeof(hotkey_reserved_mask)*8)
1289 hotkey_reserved_mask |= 1 << i;
1293 if (tp_features.hotkey_wlsw) {
1294 set_bit(EV_SW, tpacpi_inputdev->evbit);
1295 set_bit(SW_RADIO, tpacpi_inputdev->swbit);
1298 dbg_printk(TPACPI_DBG_INIT,
1299 "enabling hot key handling\n");
1300 res = hotkey_status_set(1);
1301 if (res)
1302 return res;
1303 res = hotkey_mask_set((hotkey_all_mask & ~hotkey_reserved_mask)
1304 | hotkey_orig_mask);
1305 if (res)
1306 return res;
1308 dbg_printk(TPACPI_DBG_INIT,
1309 "legacy hot key reporting over procfs %s\n",
1310 (hotkey_report_mode < 2) ?
1311 "enabled" : "disabled");
1314 return (tp_features.hotkey)? 0 : 1;
1317 static void hotkey_exit(void)
1319 if (tp_features.hotkey) {
1320 dbg_printk(TPACPI_DBG_EXIT, "restoring original hot key mask\n");
1321 /* no short-circuit boolean operator below! */
1322 if ((hotkey_mask_set(hotkey_orig_mask) |
1323 hotkey_status_set(hotkey_orig_status)) != 0)
1324 printk(IBM_ERR "failed to restore hot key mask to BIOS defaults\n");
1327 if (hotkey_dev_attributes) {
1328 delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
1329 hotkey_dev_attributes = NULL;
1333 static void hotkey_notify(struct ibm_struct *ibm, u32 event)
1335 u32 hkey;
1336 unsigned int scancode;
1337 int send_acpi_ev;
1338 int ignore_acpi_ev;
1340 if (event != 0x80) {
1341 printk(IBM_ERR "unknown HKEY notification event %d\n", event);
1342 /* forward it to userspace, maybe it knows how to handle it */
1343 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
1344 ibm->acpi->device->dev.bus_id,
1345 event, 0);
1346 return;
1349 while (1) {
1350 if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
1351 printk(IBM_ERR "failed to retrieve HKEY event\n");
1352 return;
1355 if (hkey == 0) {
1356 /* queue empty */
1357 return;
1360 send_acpi_ev = 0;
1361 ignore_acpi_ev = 0;
1363 switch (hkey >> 12) {
1364 case 1:
1365 /* 0x1000-0x1FFF: key presses */
1366 scancode = hkey & 0xfff;
1367 if (scancode > 0 && scancode < 0x21) {
1368 scancode--;
1369 tpacpi_input_send_key(scancode);
1370 } else {
1371 printk(IBM_ERR
1372 "hotkey 0x%04x out of range for keyboard map\n",
1373 hkey);
1374 send_acpi_ev = 1;
1376 break;
1377 case 5:
1378 /* 0x5000-0x5FFF: LID */
1379 /* we don't handle it through this path, just
1380 * eat up known LID events */
1381 if (hkey != 0x5001 && hkey != 0x5002) {
1382 printk(IBM_ERR
1383 "unknown LID-related HKEY event: 0x%04x\n",
1384 hkey);
1385 send_acpi_ev = 1;
1386 } else {
1387 ignore_acpi_ev = 1;
1389 break;
1390 case 7:
1391 /* 0x7000-0x7FFF: misc */
1392 if (tp_features.hotkey_wlsw && hkey == 0x7000) {
1393 tpacpi_input_send_radiosw();
1394 break;
1396 /* fallthrough to default */
1397 default:
1398 /* case 2: dock-related */
1399 /* 0x2305 - T43 waking up due to bay lever eject while aslept */
1400 /* case 3: ultra-bay related. maybe bay in dock? */
1401 /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */
1402 printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey);
1403 send_acpi_ev = 1;
1406 /* Legacy events */
1407 if (!ignore_acpi_ev && (send_acpi_ev || hotkey_report_mode < 2)) {
1408 acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
1411 /* netlink events */
1412 if (!ignore_acpi_ev && send_acpi_ev) {
1413 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
1414 ibm->acpi->device->dev.bus_id,
1415 event, hkey);
1420 static void hotkey_resume(void)
1422 if (hotkey_mask_get())
1423 printk(IBM_ERR "error while trying to read hot key mask from firmware\n");
1424 tpacpi_input_send_radiosw();
1427 /* procfs -------------------------------------------------------------- */
1428 static int hotkey_read(char *p)
1430 int res, status;
1431 int len = 0;
1433 if (!tp_features.hotkey) {
1434 len += sprintf(p + len, "status:\t\tnot supported\n");
1435 return len;
1438 if (mutex_lock_interruptible(&hotkey_mutex))
1439 return -ERESTARTSYS;
1440 res = hotkey_status_get(&status);
1441 if (!res)
1442 res = hotkey_mask_get();
1443 mutex_unlock(&hotkey_mutex);
1444 if (res)
1445 return res;
1447 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
1448 if (tp_features.hotkey_mask) {
1449 len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_mask);
1450 len += sprintf(p + len,
1451 "commands:\tenable, disable, reset, <mask>\n");
1452 } else {
1453 len += sprintf(p + len, "mask:\t\tnot supported\n");
1454 len += sprintf(p + len, "commands:\tenable, disable, reset\n");
1457 return len;
1460 static int hotkey_write(char *buf)
1462 int res, status;
1463 u32 mask;
1464 char *cmd;
1466 if (!tp_features.hotkey)
1467 return -ENODEV;
1469 if (mutex_lock_interruptible(&hotkey_mutex))
1470 return -ERESTARTSYS;
1472 status = -1;
1473 mask = hotkey_mask;
1475 res = 0;
1476 while ((cmd = next_cmd(&buf))) {
1477 if (strlencmp(cmd, "enable") == 0) {
1478 status = 1;
1479 } else if (strlencmp(cmd, "disable") == 0) {
1480 status = 0;
1481 } else if (strlencmp(cmd, "reset") == 0) {
1482 status = hotkey_orig_status;
1483 mask = hotkey_orig_mask;
1484 } else if (sscanf(cmd, "0x%x", &mask) == 1) {
1485 /* mask set */
1486 } else if (sscanf(cmd, "%x", &mask) == 1) {
1487 /* mask set */
1488 } else {
1489 res = -EINVAL;
1490 goto errexit;
1493 if (status != -1)
1494 res = hotkey_status_set(status);
1496 if (!res && mask != hotkey_mask)
1497 res = hotkey_mask_set(mask);
1499 errexit:
1500 mutex_unlock(&hotkey_mutex);
1501 return res;
1504 static const struct acpi_device_id ibm_htk_device_ids[] = {
1505 {IBM_HKEY_HID, 0},
1506 {"", 0},
1509 static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = {
1510 .hid = ibm_htk_device_ids,
1511 .notify = hotkey_notify,
1512 .handle = &hkey_handle,
1513 .type = ACPI_DEVICE_NOTIFY,
1516 static struct ibm_struct hotkey_driver_data = {
1517 .name = "hotkey",
1518 .read = hotkey_read,
1519 .write = hotkey_write,
1520 .exit = hotkey_exit,
1521 .resume = hotkey_resume,
1522 .acpi = &ibm_hotkey_acpidriver,
1525 /*************************************************************************
1526 * Bluetooth subdriver
1529 /* sysfs bluetooth enable ---------------------------------------------- */
1530 static ssize_t bluetooth_enable_show(struct device *dev,
1531 struct device_attribute *attr,
1532 char *buf)
1534 int status;
1536 status = bluetooth_get_radiosw();
1537 if (status < 0)
1538 return status;
1540 return snprintf(buf, PAGE_SIZE, "%d\n", status ? 1 : 0);
1543 static ssize_t bluetooth_enable_store(struct device *dev,
1544 struct device_attribute *attr,
1545 const char *buf, size_t count)
1547 unsigned long t;
1548 int res;
1550 if (parse_strtoul(buf, 1, &t))
1551 return -EINVAL;
1553 res = bluetooth_set_radiosw(t);
1555 return (res) ? res : count;
1558 static struct device_attribute dev_attr_bluetooth_enable =
1559 __ATTR(bluetooth_enable, S_IWUSR | S_IRUGO,
1560 bluetooth_enable_show, bluetooth_enable_store);
1562 /* --------------------------------------------------------------------- */
1564 static struct attribute *bluetooth_attributes[] = {
1565 &dev_attr_bluetooth_enable.attr,
1566 NULL
1569 static const struct attribute_group bluetooth_attr_group = {
1570 .attrs = bluetooth_attributes,
1573 static int __init bluetooth_init(struct ibm_init_struct *iibm)
1575 int res;
1576 int status = 0;
1578 vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
1580 IBM_ACPIHANDLE_INIT(hkey);
1582 /* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
1583 G4x, R30, R31, R40e, R50e, T20-22, X20-21 */
1584 tp_features.bluetooth = hkey_handle &&
1585 acpi_evalf(hkey_handle, &status, "GBDC", "qd");
1587 vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n",
1588 str_supported(tp_features.bluetooth),
1589 status);
1591 if (tp_features.bluetooth) {
1592 if (!(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
1593 /* no bluetooth hardware present in system */
1594 tp_features.bluetooth = 0;
1595 dbg_printk(TPACPI_DBG_INIT,
1596 "bluetooth hardware not installed\n");
1597 } else {
1598 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
1599 &bluetooth_attr_group);
1600 if (res)
1601 return res;
1605 return (tp_features.bluetooth)? 0 : 1;
1608 static void bluetooth_exit(void)
1610 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
1611 &bluetooth_attr_group);
1614 static int bluetooth_get_radiosw(void)
1616 int status;
1618 if (!tp_features.bluetooth)
1619 return -ENODEV;
1621 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
1622 return -EIO;
1624 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0);
1627 static int bluetooth_set_radiosw(int radio_on)
1629 int status;
1631 if (!tp_features.bluetooth)
1632 return -ENODEV;
1634 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
1635 return -EIO;
1636 if (radio_on)
1637 status |= TP_ACPI_BLUETOOTH_RADIOSSW;
1638 else
1639 status &= ~TP_ACPI_BLUETOOTH_RADIOSSW;
1640 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
1641 return -EIO;
1643 return 0;
1646 /* procfs -------------------------------------------------------------- */
1647 static int bluetooth_read(char *p)
1649 int len = 0;
1650 int status = bluetooth_get_radiosw();
1652 if (!tp_features.bluetooth)
1653 len += sprintf(p + len, "status:\t\tnot supported\n");
1654 else {
1655 len += sprintf(p + len, "status:\t\t%s\n",
1656 (status)? "enabled" : "disabled");
1657 len += sprintf(p + len, "commands:\tenable, disable\n");
1660 return len;
1663 static int bluetooth_write(char *buf)
1665 char *cmd;
1667 if (!tp_features.bluetooth)
1668 return -ENODEV;
1670 while ((cmd = next_cmd(&buf))) {
1671 if (strlencmp(cmd, "enable") == 0) {
1672 bluetooth_set_radiosw(1);
1673 } else if (strlencmp(cmd, "disable") == 0) {
1674 bluetooth_set_radiosw(0);
1675 } else
1676 return -EINVAL;
1679 return 0;
1682 static struct ibm_struct bluetooth_driver_data = {
1683 .name = "bluetooth",
1684 .read = bluetooth_read,
1685 .write = bluetooth_write,
1686 .exit = bluetooth_exit,
1689 /*************************************************************************
1690 * Wan subdriver
1693 /* sysfs wan enable ---------------------------------------------------- */
1694 static ssize_t wan_enable_show(struct device *dev,
1695 struct device_attribute *attr,
1696 char *buf)
1698 int status;
1700 status = wan_get_radiosw();
1701 if (status < 0)
1702 return status;
1704 return snprintf(buf, PAGE_SIZE, "%d\n", status ? 1 : 0);
1707 static ssize_t wan_enable_store(struct device *dev,
1708 struct device_attribute *attr,
1709 const char *buf, size_t count)
1711 unsigned long t;
1712 int res;
1714 if (parse_strtoul(buf, 1, &t))
1715 return -EINVAL;
1717 res = wan_set_radiosw(t);
1719 return (res) ? res : count;
1722 static struct device_attribute dev_attr_wan_enable =
1723 __ATTR(wwan_enable, S_IWUSR | S_IRUGO,
1724 wan_enable_show, wan_enable_store);
1726 /* --------------------------------------------------------------------- */
1728 static struct attribute *wan_attributes[] = {
1729 &dev_attr_wan_enable.attr,
1730 NULL
1733 static const struct attribute_group wan_attr_group = {
1734 .attrs = wan_attributes,
1737 static int __init wan_init(struct ibm_init_struct *iibm)
1739 int res;
1740 int status = 0;
1742 vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
1744 IBM_ACPIHANDLE_INIT(hkey);
1746 tp_features.wan = hkey_handle &&
1747 acpi_evalf(hkey_handle, &status, "GWAN", "qd");
1749 vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n",
1750 str_supported(tp_features.wan),
1751 status);
1753 if (tp_features.wan) {
1754 if (!(status & TP_ACPI_WANCARD_HWPRESENT)) {
1755 /* no wan hardware present in system */
1756 tp_features.wan = 0;
1757 dbg_printk(TPACPI_DBG_INIT,
1758 "wan hardware not installed\n");
1759 } else {
1760 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
1761 &wan_attr_group);
1762 if (res)
1763 return res;
1767 return (tp_features.wan)? 0 : 1;
1770 static void wan_exit(void)
1772 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
1773 &wan_attr_group);
1776 static int wan_get_radiosw(void)
1778 int status;
1780 if (!tp_features.wan)
1781 return -ENODEV;
1783 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
1784 return -EIO;
1786 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0);
1789 static int wan_set_radiosw(int radio_on)
1791 int status;
1793 if (!tp_features.wan)
1794 return -ENODEV;
1796 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
1797 return -EIO;
1798 if (radio_on)
1799 status |= TP_ACPI_WANCARD_RADIOSSW;
1800 else
1801 status &= ~TP_ACPI_WANCARD_RADIOSSW;
1802 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
1803 return -EIO;
1805 return 0;
1808 /* procfs -------------------------------------------------------------- */
1809 static int wan_read(char *p)
1811 int len = 0;
1812 int status = wan_get_radiosw();
1814 if (!tp_features.wan)
1815 len += sprintf(p + len, "status:\t\tnot supported\n");
1816 else {
1817 len += sprintf(p + len, "status:\t\t%s\n",
1818 (status)? "enabled" : "disabled");
1819 len += sprintf(p + len, "commands:\tenable, disable\n");
1822 return len;
1825 static int wan_write(char *buf)
1827 char *cmd;
1829 if (!tp_features.wan)
1830 return -ENODEV;
1832 while ((cmd = next_cmd(&buf))) {
1833 if (strlencmp(cmd, "enable") == 0) {
1834 wan_set_radiosw(1);
1835 } else if (strlencmp(cmd, "disable") == 0) {
1836 wan_set_radiosw(0);
1837 } else
1838 return -EINVAL;
1841 return 0;
1844 static struct ibm_struct wan_driver_data = {
1845 .name = "wan",
1846 .read = wan_read,
1847 .write = wan_write,
1848 .exit = wan_exit,
1849 .flags.experimental = 1,
1852 /*************************************************************************
1853 * Video subdriver
1856 static enum video_access_mode video_supported;
1857 static int video_orig_autosw;
1859 IBM_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */
1860 "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */
1861 "\\_SB.PCI0.VID0", /* 770e */
1862 "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */
1863 "\\_SB.PCI0.AGP.VID", /* all others */
1864 ); /* R30, R31 */
1866 IBM_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID"); /* G41 */
1868 static int __init video_init(struct ibm_init_struct *iibm)
1870 int ivga;
1872 vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n");
1874 IBM_ACPIHANDLE_INIT(vid);
1875 IBM_ACPIHANDLE_INIT(vid2);
1877 if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga)
1878 /* G41, assume IVGA doesn't change */
1879 vid_handle = vid2_handle;
1881 if (!vid_handle)
1882 /* video switching not supported on R30, R31 */
1883 video_supported = TPACPI_VIDEO_NONE;
1884 else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd"))
1885 /* 570 */
1886 video_supported = TPACPI_VIDEO_570;
1887 else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd"))
1888 /* 600e/x, 770e, 770x */
1889 video_supported = TPACPI_VIDEO_770;
1890 else
1891 /* all others */
1892 video_supported = TPACPI_VIDEO_NEW;
1894 vdbg_printk(TPACPI_DBG_INIT, "video is %s, mode %d\n",
1895 str_supported(video_supported != TPACPI_VIDEO_NONE),
1896 video_supported);
1898 return (video_supported != TPACPI_VIDEO_NONE)? 0 : 1;
1901 static void video_exit(void)
1903 dbg_printk(TPACPI_DBG_EXIT,
1904 "restoring original video autoswitch mode\n");
1905 if (video_autosw_set(video_orig_autosw))
1906 printk(IBM_ERR "error while trying to restore original "
1907 "video autoswitch mode\n");
1910 static int video_outputsw_get(void)
1912 int status = 0;
1913 int i;
1915 switch (video_supported) {
1916 case TPACPI_VIDEO_570:
1917 if (!acpi_evalf(NULL, &i, "\\_SB.PHS", "dd",
1918 TP_ACPI_VIDEO_570_PHSCMD))
1919 return -EIO;
1920 status = i & TP_ACPI_VIDEO_570_PHSMASK;
1921 break;
1922 case TPACPI_VIDEO_770:
1923 if (!acpi_evalf(NULL, &i, "\\VCDL", "d"))
1924 return -EIO;
1925 if (i)
1926 status |= TP_ACPI_VIDEO_S_LCD;
1927 if (!acpi_evalf(NULL, &i, "\\VCDC", "d"))
1928 return -EIO;
1929 if (i)
1930 status |= TP_ACPI_VIDEO_S_CRT;
1931 break;
1932 case TPACPI_VIDEO_NEW:
1933 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1) ||
1934 !acpi_evalf(NULL, &i, "\\VCDC", "d"))
1935 return -EIO;
1936 if (i)
1937 status |= TP_ACPI_VIDEO_S_CRT;
1939 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0) ||
1940 !acpi_evalf(NULL, &i, "\\VCDL", "d"))
1941 return -EIO;
1942 if (i)
1943 status |= TP_ACPI_VIDEO_S_LCD;
1944 if (!acpi_evalf(NULL, &i, "\\VCDD", "d"))
1945 return -EIO;
1946 if (i)
1947 status |= TP_ACPI_VIDEO_S_DVI;
1948 break;
1949 default:
1950 return -ENOSYS;
1953 return status;
1956 static int video_outputsw_set(int status)
1958 int autosw;
1959 int res = 0;
1961 switch (video_supported) {
1962 case TPACPI_VIDEO_570:
1963 res = acpi_evalf(NULL, NULL,
1964 "\\_SB.PHS2", "vdd",
1965 TP_ACPI_VIDEO_570_PHS2CMD,
1966 status | TP_ACPI_VIDEO_570_PHS2SET);
1967 break;
1968 case TPACPI_VIDEO_770:
1969 autosw = video_autosw_get();
1970 if (autosw < 0)
1971 return autosw;
1973 res = video_autosw_set(1);
1974 if (res)
1975 return res;
1976 res = acpi_evalf(vid_handle, NULL,
1977 "ASWT", "vdd", status * 0x100, 0);
1978 if (!autosw && video_autosw_set(autosw)) {
1979 printk(IBM_ERR "video auto-switch left enabled due to error\n");
1980 return -EIO;
1982 break;
1983 case TPACPI_VIDEO_NEW:
1984 res = acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80) &&
1985 acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1);
1986 break;
1987 default:
1988 return -ENOSYS;
1991 return (res)? 0 : -EIO;
1994 static int video_autosw_get(void)
1996 int autosw = 0;
1998 switch (video_supported) {
1999 case TPACPI_VIDEO_570:
2000 if (!acpi_evalf(vid_handle, &autosw, "SWIT", "d"))
2001 return -EIO;
2002 break;
2003 case TPACPI_VIDEO_770:
2004 case TPACPI_VIDEO_NEW:
2005 if (!acpi_evalf(vid_handle, &autosw, "^VDEE", "d"))
2006 return -EIO;
2007 break;
2008 default:
2009 return -ENOSYS;
2012 return autosw & 1;
2015 static int video_autosw_set(int enable)
2017 if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", (enable)? 1 : 0))
2018 return -EIO;
2019 return 0;
2022 static int video_outputsw_cycle(void)
2024 int autosw = video_autosw_get();
2025 int res;
2027 if (autosw < 0)
2028 return autosw;
2030 switch (video_supported) {
2031 case TPACPI_VIDEO_570:
2032 res = video_autosw_set(1);
2033 if (res)
2034 return res;
2035 res = acpi_evalf(ec_handle, NULL, "_Q16", "v");
2036 break;
2037 case TPACPI_VIDEO_770:
2038 case TPACPI_VIDEO_NEW:
2039 res = video_autosw_set(1);
2040 if (res)
2041 return res;
2042 res = acpi_evalf(vid_handle, NULL, "VSWT", "v");
2043 break;
2044 default:
2045 return -ENOSYS;
2047 if (!autosw && video_autosw_set(autosw)) {
2048 printk(IBM_ERR "video auto-switch left enabled due to error\n");
2049 return -EIO;
2052 return (res)? 0 : -EIO;
2055 static int video_expand_toggle(void)
2057 switch (video_supported) {
2058 case TPACPI_VIDEO_570:
2059 return acpi_evalf(ec_handle, NULL, "_Q17", "v")?
2060 0 : -EIO;
2061 case TPACPI_VIDEO_770:
2062 return acpi_evalf(vid_handle, NULL, "VEXP", "v")?
2063 0 : -EIO;
2064 case TPACPI_VIDEO_NEW:
2065 return acpi_evalf(NULL, NULL, "\\VEXP", "v")?
2066 0 : -EIO;
2067 default:
2068 return -ENOSYS;
2070 /* not reached */
2073 static int video_read(char *p)
2075 int status, autosw;
2076 int len = 0;
2078 if (video_supported == TPACPI_VIDEO_NONE) {
2079 len += sprintf(p + len, "status:\t\tnot supported\n");
2080 return len;
2083 status = video_outputsw_get();
2084 if (status < 0)
2085 return status;
2087 autosw = video_autosw_get();
2088 if (autosw < 0)
2089 return autosw;
2091 len += sprintf(p + len, "status:\t\tsupported\n");
2092 len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0));
2093 len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1));
2094 if (video_supported == TPACPI_VIDEO_NEW)
2095 len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3));
2096 len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0));
2097 len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n");
2098 len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n");
2099 if (video_supported == TPACPI_VIDEO_NEW)
2100 len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n");
2101 len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n");
2102 len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n");
2104 return len;
2107 static int video_write(char *buf)
2109 char *cmd;
2110 int enable, disable, status;
2111 int res;
2113 if (video_supported == TPACPI_VIDEO_NONE)
2114 return -ENODEV;
2116 enable = 0;
2117 disable = 0;
2119 while ((cmd = next_cmd(&buf))) {
2120 if (strlencmp(cmd, "lcd_enable") == 0) {
2121 enable |= TP_ACPI_VIDEO_S_LCD;
2122 } else if (strlencmp(cmd, "lcd_disable") == 0) {
2123 disable |= TP_ACPI_VIDEO_S_LCD;
2124 } else if (strlencmp(cmd, "crt_enable") == 0) {
2125 enable |= TP_ACPI_VIDEO_S_CRT;
2126 } else if (strlencmp(cmd, "crt_disable") == 0) {
2127 disable |= TP_ACPI_VIDEO_S_CRT;
2128 } else if (video_supported == TPACPI_VIDEO_NEW &&
2129 strlencmp(cmd, "dvi_enable") == 0) {
2130 enable |= TP_ACPI_VIDEO_S_DVI;
2131 } else if (video_supported == TPACPI_VIDEO_NEW &&
2132 strlencmp(cmd, "dvi_disable") == 0) {
2133 disable |= TP_ACPI_VIDEO_S_DVI;
2134 } else if (strlencmp(cmd, "auto_enable") == 0) {
2135 res = video_autosw_set(1);
2136 if (res)
2137 return res;
2138 } else if (strlencmp(cmd, "auto_disable") == 0) {
2139 res = video_autosw_set(0);
2140 if (res)
2141 return res;
2142 } else if (strlencmp(cmd, "video_switch") == 0) {
2143 res = video_outputsw_cycle();
2144 if (res)
2145 return res;
2146 } else if (strlencmp(cmd, "expand_toggle") == 0) {
2147 res = video_expand_toggle();
2148 if (res)
2149 return res;
2150 } else
2151 return -EINVAL;
2154 if (enable || disable) {
2155 status = video_outputsw_get();
2156 if (status < 0)
2157 return status;
2158 res = video_outputsw_set((status & ~disable) | enable);
2159 if (res)
2160 return res;
2163 return 0;
2166 static struct ibm_struct video_driver_data = {
2167 .name = "video",
2168 .read = video_read,
2169 .write = video_write,
2170 .exit = video_exit,
2173 /*************************************************************************
2174 * Light (thinklight) subdriver
2177 IBM_HANDLE(lght, root, "\\LGHT"); /* A21e, A2xm/p, T20-22, X20-21 */
2178 IBM_HANDLE(ledb, ec, "LEDB"); /* G4x */
2180 static int __init light_init(struct ibm_init_struct *iibm)
2182 vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
2184 IBM_ACPIHANDLE_INIT(ledb);
2185 IBM_ACPIHANDLE_INIT(lght);
2186 IBM_ACPIHANDLE_INIT(cmos);
2188 /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */
2189 tp_features.light = (cmos_handle || lght_handle) && !ledb_handle;
2191 if (tp_features.light)
2192 /* light status not supported on
2193 570, 600e/x, 770e, 770x, G4x, R30, R31, R32, X20 */
2194 tp_features.light_status =
2195 acpi_evalf(ec_handle, NULL, "KBLT", "qv");
2197 vdbg_printk(TPACPI_DBG_INIT, "light is %s\n",
2198 str_supported(tp_features.light));
2200 return (tp_features.light)? 0 : 1;
2203 static int light_read(char *p)
2205 int len = 0;
2206 int status = 0;
2208 if (!tp_features.light) {
2209 len += sprintf(p + len, "status:\t\tnot supported\n");
2210 } else if (!tp_features.light_status) {
2211 len += sprintf(p + len, "status:\t\tunknown\n");
2212 len += sprintf(p + len, "commands:\ton, off\n");
2213 } else {
2214 if (!acpi_evalf(ec_handle, &status, "KBLT", "d"))
2215 return -EIO;
2216 len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0));
2217 len += sprintf(p + len, "commands:\ton, off\n");
2220 return len;
2223 static int light_write(char *buf)
2225 int cmos_cmd, lght_cmd;
2226 char *cmd;
2227 int success;
2229 if (!tp_features.light)
2230 return -ENODEV;
2232 while ((cmd = next_cmd(&buf))) {
2233 if (strlencmp(cmd, "on") == 0) {
2234 cmos_cmd = 0x0c;
2235 lght_cmd = 1;
2236 } else if (strlencmp(cmd, "off") == 0) {
2237 cmos_cmd = 0x0d;
2238 lght_cmd = 0;
2239 } else
2240 return -EINVAL;
2242 success = cmos_handle ?
2243 acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd) :
2244 acpi_evalf(lght_handle, NULL, NULL, "vd", lght_cmd);
2245 if (!success)
2246 return -EIO;
2249 return 0;
2252 static struct ibm_struct light_driver_data = {
2253 .name = "light",
2254 .read = light_read,
2255 .write = light_write,
2258 /*************************************************************************
2259 * Dock subdriver
2262 #ifdef CONFIG_THINKPAD_ACPI_DOCK
2264 IBM_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */
2265 "\\_SB.PCI0.DOCK", /* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */
2266 "\\_SB.PCI0.PCI1.DOCK", /* all others */
2267 "\\_SB.PCI.ISA.SLCE", /* 570 */
2268 ); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
2270 /* don't list other alternatives as we install a notify handler on the 570 */
2271 IBM_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */
2273 static const struct acpi_device_id ibm_pci_device_ids[] = {
2274 {PCI_ROOT_HID_STRING, 0},
2275 {"", 0},
2278 static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = {
2280 .notify = dock_notify,
2281 .handle = &dock_handle,
2282 .type = ACPI_SYSTEM_NOTIFY,
2285 /* THIS ONE MUST NEVER BE USED FOR DRIVER AUTOLOADING.
2286 * We just use it to get notifications of dock hotplug
2287 * in very old thinkpads */
2288 .hid = ibm_pci_device_ids,
2289 .notify = dock_notify,
2290 .handle = &pci_handle,
2291 .type = ACPI_SYSTEM_NOTIFY,
2295 static struct ibm_struct dock_driver_data[2] = {
2297 .name = "dock",
2298 .read = dock_read,
2299 .write = dock_write,
2300 .acpi = &ibm_dock_acpidriver[0],
2303 .name = "dock",
2304 .acpi = &ibm_dock_acpidriver[1],
2308 #define dock_docked() (_sta(dock_handle) & 1)
2310 static int __init dock_init(struct ibm_init_struct *iibm)
2312 vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver\n");
2314 IBM_ACPIHANDLE_INIT(dock);
2316 vdbg_printk(TPACPI_DBG_INIT, "dock is %s\n",
2317 str_supported(dock_handle != NULL));
2319 return (dock_handle)? 0 : 1;
2322 static int __init dock_init2(struct ibm_init_struct *iibm)
2324 int dock2_needed;
2326 vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver part 2\n");
2328 if (dock_driver_data[0].flags.acpi_driver_registered &&
2329 dock_driver_data[0].flags.acpi_notify_installed) {
2330 IBM_ACPIHANDLE_INIT(pci);
2331 dock2_needed = (pci_handle != NULL);
2332 vdbg_printk(TPACPI_DBG_INIT,
2333 "dock PCI handler for the TP 570 is %s\n",
2334 str_supported(dock2_needed));
2335 } else {
2336 vdbg_printk(TPACPI_DBG_INIT,
2337 "dock subdriver part 2 not required\n");
2338 dock2_needed = 0;
2341 return (dock2_needed)? 0 : 1;
2344 static void dock_notify(struct ibm_struct *ibm, u32 event)
2346 int docked = dock_docked();
2347 int pci = ibm->acpi->hid && ibm->acpi->device &&
2348 acpi_match_device_ids(ibm->acpi->device, ibm_pci_device_ids);
2349 int data;
2351 if (event == 1 && !pci) /* 570 */
2352 data = 1; /* button */
2353 else if (event == 1 && pci) /* 570 */
2354 data = 3; /* dock */
2355 else if (event == 3 && docked)
2356 data = 1; /* button */
2357 else if (event == 3 && !docked)
2358 data = 2; /* undock */
2359 else if (event == 0 && docked)
2360 data = 3; /* dock */
2361 else {
2362 printk(IBM_ERR "unknown dock event %d, status %d\n",
2363 event, _sta(dock_handle));
2364 data = 0; /* unknown */
2366 acpi_bus_generate_proc_event(ibm->acpi->device, event, data);
2367 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
2368 ibm->acpi->device->dev.bus_id,
2369 event, data);
2372 static int dock_read(char *p)
2374 int len = 0;
2375 int docked = dock_docked();
2377 if (!dock_handle)
2378 len += sprintf(p + len, "status:\t\tnot supported\n");
2379 else if (!docked)
2380 len += sprintf(p + len, "status:\t\tundocked\n");
2381 else {
2382 len += sprintf(p + len, "status:\t\tdocked\n");
2383 len += sprintf(p + len, "commands:\tdock, undock\n");
2386 return len;
2389 static int dock_write(char *buf)
2391 char *cmd;
2393 if (!dock_docked())
2394 return -ENODEV;
2396 while ((cmd = next_cmd(&buf))) {
2397 if (strlencmp(cmd, "undock") == 0) {
2398 if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 0) ||
2399 !acpi_evalf(dock_handle, NULL, "_EJ0", "vd", 1))
2400 return -EIO;
2401 } else if (strlencmp(cmd, "dock") == 0) {
2402 if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 1))
2403 return -EIO;
2404 } else
2405 return -EINVAL;
2408 return 0;
2411 #endif /* CONFIG_THINKPAD_ACPI_DOCK */
2413 /*************************************************************************
2414 * Bay subdriver
2417 #ifdef CONFIG_THINKPAD_ACPI_BAY
2418 IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */
2419 "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */
2420 "\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */
2421 "\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */
2422 ); /* A21e, R30, R31 */
2423 IBM_HANDLE(bay_ej, bay, "_EJ3", /* 600e/x, A2xm/p, A3x */
2424 "_EJ0", /* all others */
2425 ); /* 570,A21e,G4x,R30,R31,R32,R40e,R50e */
2426 IBM_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV", /* A3x, R32 */
2427 "\\_SB.PCI0.IDE0.IDEP.IDPS", /* 600e/x, 770e, 770x */
2428 ); /* all others */
2429 IBM_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */
2430 "_EJ0", /* 770x */
2431 ); /* all others */
2433 static int __init bay_init(struct ibm_init_struct *iibm)
2435 vdbg_printk(TPACPI_DBG_INIT, "initializing bay subdriver\n");
2437 IBM_ACPIHANDLE_INIT(bay);
2438 if (bay_handle)
2439 IBM_ACPIHANDLE_INIT(bay_ej);
2440 IBM_ACPIHANDLE_INIT(bay2);
2441 if (bay2_handle)
2442 IBM_ACPIHANDLE_INIT(bay2_ej);
2444 tp_features.bay_status = bay_handle &&
2445 acpi_evalf(bay_handle, NULL, "_STA", "qv");
2446 tp_features.bay_status2 = bay2_handle &&
2447 acpi_evalf(bay2_handle, NULL, "_STA", "qv");
2449 tp_features.bay_eject = bay_handle && bay_ej_handle &&
2450 (strlencmp(bay_ej_path, "_EJ0") == 0 || experimental);
2451 tp_features.bay_eject2 = bay2_handle && bay2_ej_handle &&
2452 (strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental);
2454 vdbg_printk(TPACPI_DBG_INIT,
2455 "bay 1: status %s, eject %s; bay 2: status %s, eject %s\n",
2456 str_supported(tp_features.bay_status),
2457 str_supported(tp_features.bay_eject),
2458 str_supported(tp_features.bay_status2),
2459 str_supported(tp_features.bay_eject2));
2461 return (tp_features.bay_status || tp_features.bay_eject ||
2462 tp_features.bay_status2 || tp_features.bay_eject2)? 0 : 1;
2465 static void bay_notify(struct ibm_struct *ibm, u32 event)
2467 acpi_bus_generate_proc_event(ibm->acpi->device, event, 0);
2468 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
2469 ibm->acpi->device->dev.bus_id,
2470 event, 0);
2473 #define bay_occupied(b) (_sta(b##_handle) & 1)
2475 static int bay_read(char *p)
2477 int len = 0;
2478 int occupied = bay_occupied(bay);
2479 int occupied2 = bay_occupied(bay2);
2480 int eject, eject2;
2482 len += sprintf(p + len, "status:\t\t%s\n",
2483 tp_features.bay_status ?
2484 (occupied ? "occupied" : "unoccupied") :
2485 "not supported");
2486 if (tp_features.bay_status2)
2487 len += sprintf(p + len, "status2:\t%s\n", occupied2 ?
2488 "occupied" : "unoccupied");
2490 eject = tp_features.bay_eject && occupied;
2491 eject2 = tp_features.bay_eject2 && occupied2;
2493 if (eject && eject2)
2494 len += sprintf(p + len, "commands:\teject, eject2\n");
2495 else if (eject)
2496 len += sprintf(p + len, "commands:\teject\n");
2497 else if (eject2)
2498 len += sprintf(p + len, "commands:\teject2\n");
2500 return len;
2503 static int bay_write(char *buf)
2505 char *cmd;
2507 if (!tp_features.bay_eject && !tp_features.bay_eject2)
2508 return -ENODEV;
2510 while ((cmd = next_cmd(&buf))) {
2511 if (tp_features.bay_eject && strlencmp(cmd, "eject") == 0) {
2512 if (!acpi_evalf(bay_ej_handle, NULL, NULL, "vd", 1))
2513 return -EIO;
2514 } else if (tp_features.bay_eject2 &&
2515 strlencmp(cmd, "eject2") == 0) {
2516 if (!acpi_evalf(bay2_ej_handle, NULL, NULL, "vd", 1))
2517 return -EIO;
2518 } else
2519 return -EINVAL;
2522 return 0;
2525 static struct tp_acpi_drv_struct ibm_bay_acpidriver = {
2526 .notify = bay_notify,
2527 .handle = &bay_handle,
2528 .type = ACPI_SYSTEM_NOTIFY,
2531 static struct ibm_struct bay_driver_data = {
2532 .name = "bay",
2533 .read = bay_read,
2534 .write = bay_write,
2535 .acpi = &ibm_bay_acpidriver,
2538 #endif /* CONFIG_THINKPAD_ACPI_BAY */
2540 /*************************************************************************
2541 * CMOS subdriver
2544 /* sysfs cmos_command -------------------------------------------------- */
2545 static ssize_t cmos_command_store(struct device *dev,
2546 struct device_attribute *attr,
2547 const char *buf, size_t count)
2549 unsigned long cmos_cmd;
2550 int res;
2552 if (parse_strtoul(buf, 21, &cmos_cmd))
2553 return -EINVAL;
2555 res = issue_thinkpad_cmos_command(cmos_cmd);
2556 return (res)? res : count;
2559 static struct device_attribute dev_attr_cmos_command =
2560 __ATTR(cmos_command, S_IWUSR, NULL, cmos_command_store);
2562 /* --------------------------------------------------------------------- */
2564 static int __init cmos_init(struct ibm_init_struct *iibm)
2566 int res;
2568 vdbg_printk(TPACPI_DBG_INIT,
2569 "initializing cmos commands subdriver\n");
2571 IBM_ACPIHANDLE_INIT(cmos);
2573 vdbg_printk(TPACPI_DBG_INIT, "cmos commands are %s\n",
2574 str_supported(cmos_handle != NULL));
2576 res = device_create_file(&tpacpi_pdev->dev, &dev_attr_cmos_command);
2577 if (res)
2578 return res;
2580 return (cmos_handle)? 0 : 1;
2583 static void cmos_exit(void)
2585 device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command);
2588 static int cmos_read(char *p)
2590 int len = 0;
2592 /* cmos not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
2593 R30, R31, T20-22, X20-21 */
2594 if (!cmos_handle)
2595 len += sprintf(p + len, "status:\t\tnot supported\n");
2596 else {
2597 len += sprintf(p + len, "status:\t\tsupported\n");
2598 len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-21)\n");
2601 return len;
2604 static int cmos_write(char *buf)
2606 char *cmd;
2607 int cmos_cmd, res;
2609 while ((cmd = next_cmd(&buf))) {
2610 if (sscanf(cmd, "%u", &cmos_cmd) == 1 &&
2611 cmos_cmd >= 0 && cmos_cmd <= 21) {
2612 /* cmos_cmd set */
2613 } else
2614 return -EINVAL;
2616 res = issue_thinkpad_cmos_command(cmos_cmd);
2617 if (res)
2618 return res;
2621 return 0;
2624 static struct ibm_struct cmos_driver_data = {
2625 .name = "cmos",
2626 .read = cmos_read,
2627 .write = cmos_write,
2628 .exit = cmos_exit,
2631 /*************************************************************************
2632 * LED subdriver
2635 static enum led_access_mode led_supported;
2637 IBM_HANDLE(led, ec, "SLED", /* 570 */
2638 "SYSL", /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
2639 "LED", /* all others */
2640 ); /* R30, R31 */
2642 static int __init led_init(struct ibm_init_struct *iibm)
2644 vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
2646 IBM_ACPIHANDLE_INIT(led);
2648 if (!led_handle)
2649 /* led not supported on R30, R31 */
2650 led_supported = TPACPI_LED_NONE;
2651 else if (strlencmp(led_path, "SLED") == 0)
2652 /* 570 */
2653 led_supported = TPACPI_LED_570;
2654 else if (strlencmp(led_path, "SYSL") == 0)
2655 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
2656 led_supported = TPACPI_LED_OLD;
2657 else
2658 /* all others */
2659 led_supported = TPACPI_LED_NEW;
2661 vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n",
2662 str_supported(led_supported), led_supported);
2664 return (led_supported != TPACPI_LED_NONE)? 0 : 1;
2667 #define led_status(s) ((s) == 0 ? "off" : ((s) == 1 ? "on" : "blinking"))
2669 static int led_read(char *p)
2671 int len = 0;
2673 if (!led_supported) {
2674 len += sprintf(p + len, "status:\t\tnot supported\n");
2675 return len;
2677 len += sprintf(p + len, "status:\t\tsupported\n");
2679 if (led_supported == TPACPI_LED_570) {
2680 /* 570 */
2681 int i, status;
2682 for (i = 0; i < 8; i++) {
2683 if (!acpi_evalf(ec_handle,
2684 &status, "GLED", "dd", 1 << i))
2685 return -EIO;
2686 len += sprintf(p + len, "%d:\t\t%s\n",
2687 i, led_status(status));
2691 len += sprintf(p + len, "commands:\t"
2692 "<led> on, <led> off, <led> blink (<led> is 0-7)\n");
2694 return len;
2697 /* off, on, blink */
2698 static const int led_sled_arg1[] = { 0, 1, 3 };
2699 static const int led_exp_hlbl[] = { 0, 0, 1 }; /* led# * */
2700 static const int led_exp_hlcl[] = { 0, 1, 1 }; /* led# * */
2701 static const int led_led_arg1[] = { 0, 0x80, 0xc0 };
2703 static int led_write(char *buf)
2705 char *cmd;
2706 int led, ind, ret;
2708 if (!led_supported)
2709 return -ENODEV;
2711 while ((cmd = next_cmd(&buf))) {
2712 if (sscanf(cmd, "%d", &led) != 1 || led < 0 || led > 7)
2713 return -EINVAL;
2715 if (strstr(cmd, "off")) {
2716 ind = 0;
2717 } else if (strstr(cmd, "on")) {
2718 ind = 1;
2719 } else if (strstr(cmd, "blink")) {
2720 ind = 2;
2721 } else
2722 return -EINVAL;
2724 if (led_supported == TPACPI_LED_570) {
2725 /* 570 */
2726 led = 1 << led;
2727 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
2728 led, led_sled_arg1[ind]))
2729 return -EIO;
2730 } else if (led_supported == TPACPI_LED_OLD) {
2731 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
2732 led = 1 << led;
2733 ret = ec_write(TPACPI_LED_EC_HLMS, led);
2734 if (ret >= 0)
2735 ret =
2736 ec_write(TPACPI_LED_EC_HLBL,
2737 led * led_exp_hlbl[ind]);
2738 if (ret >= 0)
2739 ret =
2740 ec_write(TPACPI_LED_EC_HLCL,
2741 led * led_exp_hlcl[ind]);
2742 if (ret < 0)
2743 return ret;
2744 } else {
2745 /* all others */
2746 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
2747 led, led_led_arg1[ind]))
2748 return -EIO;
2752 return 0;
2755 static struct ibm_struct led_driver_data = {
2756 .name = "led",
2757 .read = led_read,
2758 .write = led_write,
2761 /*************************************************************************
2762 * Beep subdriver
2765 IBM_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */
2767 static int __init beep_init(struct ibm_init_struct *iibm)
2769 vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n");
2771 IBM_ACPIHANDLE_INIT(beep);
2773 vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n",
2774 str_supported(beep_handle != NULL));
2776 return (beep_handle)? 0 : 1;
2779 static int beep_read(char *p)
2781 int len = 0;
2783 if (!beep_handle)
2784 len += sprintf(p + len, "status:\t\tnot supported\n");
2785 else {
2786 len += sprintf(p + len, "status:\t\tsupported\n");
2787 len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-17)\n");
2790 return len;
2793 static int beep_write(char *buf)
2795 char *cmd;
2796 int beep_cmd;
2798 if (!beep_handle)
2799 return -ENODEV;
2801 while ((cmd = next_cmd(&buf))) {
2802 if (sscanf(cmd, "%u", &beep_cmd) == 1 &&
2803 beep_cmd >= 0 && beep_cmd <= 17) {
2804 /* beep_cmd set */
2805 } else
2806 return -EINVAL;
2807 if (!acpi_evalf(beep_handle, NULL, NULL, "vdd", beep_cmd, 0))
2808 return -EIO;
2811 return 0;
2814 static struct ibm_struct beep_driver_data = {
2815 .name = "beep",
2816 .read = beep_read,
2817 .write = beep_write,
2820 /*************************************************************************
2821 * Thermal subdriver
2824 static enum thermal_access_mode thermal_read_mode;
2826 /* sysfs temp##_input -------------------------------------------------- */
2828 static ssize_t thermal_temp_input_show(struct device *dev,
2829 struct device_attribute *attr,
2830 char *buf)
2832 struct sensor_device_attribute *sensor_attr =
2833 to_sensor_dev_attr(attr);
2834 int idx = sensor_attr->index;
2835 s32 value;
2836 int res;
2838 res = thermal_get_sensor(idx, &value);
2839 if (res)
2840 return res;
2841 if (value == TP_EC_THERMAL_TMP_NA * 1000)
2842 return -ENXIO;
2844 return snprintf(buf, PAGE_SIZE, "%d\n", value);
2847 #define THERMAL_SENSOR_ATTR_TEMP(_idxA, _idxB) \
2848 SENSOR_ATTR(temp##_idxA##_input, S_IRUGO, thermal_temp_input_show, NULL, _idxB)
2850 static struct sensor_device_attribute sensor_dev_attr_thermal_temp_input[] = {
2851 THERMAL_SENSOR_ATTR_TEMP(1, 0),
2852 THERMAL_SENSOR_ATTR_TEMP(2, 1),
2853 THERMAL_SENSOR_ATTR_TEMP(3, 2),
2854 THERMAL_SENSOR_ATTR_TEMP(4, 3),
2855 THERMAL_SENSOR_ATTR_TEMP(5, 4),
2856 THERMAL_SENSOR_ATTR_TEMP(6, 5),
2857 THERMAL_SENSOR_ATTR_TEMP(7, 6),
2858 THERMAL_SENSOR_ATTR_TEMP(8, 7),
2859 THERMAL_SENSOR_ATTR_TEMP(9, 8),
2860 THERMAL_SENSOR_ATTR_TEMP(10, 9),
2861 THERMAL_SENSOR_ATTR_TEMP(11, 10),
2862 THERMAL_SENSOR_ATTR_TEMP(12, 11),
2863 THERMAL_SENSOR_ATTR_TEMP(13, 12),
2864 THERMAL_SENSOR_ATTR_TEMP(14, 13),
2865 THERMAL_SENSOR_ATTR_TEMP(15, 14),
2866 THERMAL_SENSOR_ATTR_TEMP(16, 15),
2869 #define THERMAL_ATTRS(X) \
2870 &sensor_dev_attr_thermal_temp_input[X].dev_attr.attr
2872 static struct attribute *thermal_temp_input_attr[] = {
2873 THERMAL_ATTRS(8),
2874 THERMAL_ATTRS(9),
2875 THERMAL_ATTRS(10),
2876 THERMAL_ATTRS(11),
2877 THERMAL_ATTRS(12),
2878 THERMAL_ATTRS(13),
2879 THERMAL_ATTRS(14),
2880 THERMAL_ATTRS(15),
2881 THERMAL_ATTRS(0),
2882 THERMAL_ATTRS(1),
2883 THERMAL_ATTRS(2),
2884 THERMAL_ATTRS(3),
2885 THERMAL_ATTRS(4),
2886 THERMAL_ATTRS(5),
2887 THERMAL_ATTRS(6),
2888 THERMAL_ATTRS(7),
2889 NULL
2892 static const struct attribute_group thermal_temp_input16_group = {
2893 .attrs = thermal_temp_input_attr
2896 static const struct attribute_group thermal_temp_input8_group = {
2897 .attrs = &thermal_temp_input_attr[8]
2900 #undef THERMAL_SENSOR_ATTR_TEMP
2901 #undef THERMAL_ATTRS
2903 /* --------------------------------------------------------------------- */
2905 static int __init thermal_init(struct ibm_init_struct *iibm)
2907 u8 t, ta1, ta2;
2908 int i;
2909 int acpi_tmp7;
2910 int res;
2912 vdbg_printk(TPACPI_DBG_INIT, "initializing thermal subdriver\n");
2914 acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
2916 if (thinkpad_id.ec_model) {
2918 * Direct EC access mode: sensors at registers
2919 * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for
2920 * non-implemented, thermal sensors return 0x80 when
2921 * not available
2924 ta1 = ta2 = 0;
2925 for (i = 0; i < 8; i++) {
2926 if (acpi_ec_read(TP_EC_THERMAL_TMP0 + i, &t)) {
2927 ta1 |= t;
2928 } else {
2929 ta1 = 0;
2930 break;
2932 if (acpi_ec_read(TP_EC_THERMAL_TMP8 + i, &t)) {
2933 ta2 |= t;
2934 } else {
2935 ta1 = 0;
2936 break;
2939 if (ta1 == 0) {
2940 /* This is sheer paranoia, but we handle it anyway */
2941 if (acpi_tmp7) {
2942 printk(IBM_ERR
2943 "ThinkPad ACPI EC access misbehaving, "
2944 "falling back to ACPI TMPx access mode\n");
2945 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;
2946 } else {
2947 printk(IBM_ERR
2948 "ThinkPad ACPI EC access misbehaving, "
2949 "disabling thermal sensors access\n");
2950 thermal_read_mode = TPACPI_THERMAL_NONE;
2952 } else {
2953 thermal_read_mode =
2954 (ta2 != 0) ?
2955 TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8;
2957 } else if (acpi_tmp7) {
2958 if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) {
2959 /* 600e/x, 770e, 770x */
2960 thermal_read_mode = TPACPI_THERMAL_ACPI_UPDT;
2961 } else {
2962 /* Standard ACPI TMPx access, max 8 sensors */
2963 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;
2965 } else {
2966 /* temperatures not supported on 570, G4x, R30, R31, R32 */
2967 thermal_read_mode = TPACPI_THERMAL_NONE;
2970 vdbg_printk(TPACPI_DBG_INIT, "thermal is %s, mode %d\n",
2971 str_supported(thermal_read_mode != TPACPI_THERMAL_NONE),
2972 thermal_read_mode);
2974 switch(thermal_read_mode) {
2975 case TPACPI_THERMAL_TPEC_16:
2976 res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
2977 &thermal_temp_input16_group);
2978 if (res)
2979 return res;
2980 break;
2981 case TPACPI_THERMAL_TPEC_8:
2982 case TPACPI_THERMAL_ACPI_TMP07:
2983 case TPACPI_THERMAL_ACPI_UPDT:
2984 res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
2985 &thermal_temp_input8_group);
2986 if (res)
2987 return res;
2988 break;
2989 case TPACPI_THERMAL_NONE:
2990 default:
2991 return 1;
2994 return 0;
2997 static void thermal_exit(void)
2999 switch(thermal_read_mode) {
3000 case TPACPI_THERMAL_TPEC_16:
3001 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
3002 &thermal_temp_input16_group);
3003 break;
3004 case TPACPI_THERMAL_TPEC_8:
3005 case TPACPI_THERMAL_ACPI_TMP07:
3006 case TPACPI_THERMAL_ACPI_UPDT:
3007 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
3008 &thermal_temp_input16_group);
3009 break;
3010 case TPACPI_THERMAL_NONE:
3011 default:
3012 break;
3016 /* idx is zero-based */
3017 static int thermal_get_sensor(int idx, s32 *value)
3019 int t;
3020 s8 tmp;
3021 char tmpi[5];
3023 t = TP_EC_THERMAL_TMP0;
3025 switch (thermal_read_mode) {
3026 #if TPACPI_MAX_THERMAL_SENSORS >= 16
3027 case TPACPI_THERMAL_TPEC_16:
3028 if (idx >= 8 && idx <= 15) {
3029 t = TP_EC_THERMAL_TMP8;
3030 idx -= 8;
3032 /* fallthrough */
3033 #endif
3034 case TPACPI_THERMAL_TPEC_8:
3035 if (idx <= 7) {
3036 if (!acpi_ec_read(t + idx, &tmp))
3037 return -EIO;
3038 *value = tmp * 1000;
3039 return 0;
3041 break;
3043 case TPACPI_THERMAL_ACPI_UPDT:
3044 if (idx <= 7) {
3045 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
3046 if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
3047 return -EIO;
3048 if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
3049 return -EIO;
3050 *value = (t - 2732) * 100;
3051 return 0;
3053 break;
3055 case TPACPI_THERMAL_ACPI_TMP07:
3056 if (idx <= 7) {
3057 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
3058 if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
3059 return -EIO;
3060 if (t > 127 || t < -127)
3061 t = TP_EC_THERMAL_TMP_NA;
3062 *value = t * 1000;
3063 return 0;
3065 break;
3067 case TPACPI_THERMAL_NONE:
3068 default:
3069 return -ENOSYS;
3072 return -EINVAL;
3075 static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
3077 int res, i;
3078 int n;
3080 n = 8;
3081 i = 0;
3083 if (!s)
3084 return -EINVAL;
3086 if (thermal_read_mode == TPACPI_THERMAL_TPEC_16)
3087 n = 16;
3089 for(i = 0 ; i < n; i++) {
3090 res = thermal_get_sensor(i, &s->temp[i]);
3091 if (res)
3092 return res;
3095 return n;
3098 static int thermal_read(char *p)
3100 int len = 0;
3101 int n, i;
3102 struct ibm_thermal_sensors_struct t;
3104 n = thermal_get_sensors(&t);
3105 if (unlikely(n < 0))
3106 return n;
3108 len += sprintf(p + len, "temperatures:\t");
3110 if (n > 0) {
3111 for (i = 0; i < (n - 1); i++)
3112 len += sprintf(p + len, "%d ", t.temp[i] / 1000);
3113 len += sprintf(p + len, "%d\n", t.temp[i] / 1000);
3114 } else
3115 len += sprintf(p + len, "not supported\n");
3117 return len;
3120 static struct ibm_struct thermal_driver_data = {
3121 .name = "thermal",
3122 .read = thermal_read,
3123 .exit = thermal_exit,
3126 /*************************************************************************
3127 * EC Dump subdriver
3130 static u8 ecdump_regs[256];
3132 static int ecdump_read(char *p)
3134 int len = 0;
3135 int i, j;
3136 u8 v;
3138 len += sprintf(p + len, "EC "
3139 " +00 +01 +02 +03 +04 +05 +06 +07"
3140 " +08 +09 +0a +0b +0c +0d +0e +0f\n");
3141 for (i = 0; i < 256; i += 16) {
3142 len += sprintf(p + len, "EC 0x%02x:", i);
3143 for (j = 0; j < 16; j++) {
3144 if (!acpi_ec_read(i + j, &v))
3145 break;
3146 if (v != ecdump_regs[i + j])
3147 len += sprintf(p + len, " *%02x", v);
3148 else
3149 len += sprintf(p + len, " %02x", v);
3150 ecdump_regs[i + j] = v;
3152 len += sprintf(p + len, "\n");
3153 if (j != 16)
3154 break;
3157 /* These are way too dangerous to advertise openly... */
3158 #if 0
3159 len += sprintf(p + len, "commands:\t0x<offset> 0x<value>"
3160 " (<offset> is 00-ff, <value> is 00-ff)\n");
3161 len += sprintf(p + len, "commands:\t0x<offset> <value> "
3162 " (<offset> is 00-ff, <value> is 0-255)\n");
3163 #endif
3164 return len;
3167 static int ecdump_write(char *buf)
3169 char *cmd;
3170 int i, v;
3172 while ((cmd = next_cmd(&buf))) {
3173 if (sscanf(cmd, "0x%x 0x%x", &i, &v) == 2) {
3174 /* i and v set */
3175 } else if (sscanf(cmd, "0x%x %u", &i, &v) == 2) {
3176 /* i and v set */
3177 } else
3178 return -EINVAL;
3179 if (i >= 0 && i < 256 && v >= 0 && v < 256) {
3180 if (!acpi_ec_write(i, v))
3181 return -EIO;
3182 } else
3183 return -EINVAL;
3186 return 0;
3189 static struct ibm_struct ecdump_driver_data = {
3190 .name = "ecdump",
3191 .read = ecdump_read,
3192 .write = ecdump_write,
3193 .flags.experimental = 1,
3196 /*************************************************************************
3197 * Backlight/brightness subdriver
3200 static struct backlight_device *ibm_backlight_device;
3202 static struct backlight_ops ibm_backlight_data = {
3203 .get_brightness = brightness_get,
3204 .update_status = brightness_update_status,
3207 static struct mutex brightness_mutex;
3209 static int __init tpacpi_query_bcll_levels(acpi_handle handle)
3211 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
3212 union acpi_object *obj;
3213 int rc;
3215 if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
3216 obj = (union acpi_object *)buffer.pointer;
3217 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
3218 printk(IBM_ERR "Unknown BCLL data, "
3219 "please report this to %s\n", IBM_MAIL);
3220 rc = 0;
3221 } else {
3222 rc = obj->package.count;
3224 } else {
3225 return 0;
3228 kfree(buffer.pointer);
3229 return rc;
3232 static acpi_status __init brightness_find_bcll(acpi_handle handle, u32 lvl,
3233 void *context, void **rv)
3235 char name[ACPI_PATH_SEGMENT_LENGTH];
3236 struct acpi_buffer buffer = { sizeof(name), &name };
3238 if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
3239 !strncmp("BCLL", name, sizeof(name) - 1)) {
3240 if (tpacpi_query_bcll_levels(handle) == 16) {
3241 *rv = handle;
3242 return AE_CTRL_TERMINATE;
3243 } else {
3244 return AE_OK;
3246 } else {
3247 return AE_OK;
3251 static int __init brightness_check_levels(void)
3253 int status;
3254 void *found_node = NULL;
3256 if (!vid_handle) {
3257 IBM_ACPIHANDLE_INIT(vid);
3259 if (!vid_handle)
3260 return 0;
3262 /* Search for a BCLL package with 16 levels */
3263 status = acpi_walk_namespace(ACPI_TYPE_PACKAGE, vid_handle, 3,
3264 brightness_find_bcll, NULL, &found_node);
3266 return (ACPI_SUCCESS(status) && found_node != NULL);
3269 static acpi_status __init brightness_find_bcl(acpi_handle handle, u32 lvl,
3270 void *context, void **rv)
3272 char name[ACPI_PATH_SEGMENT_LENGTH];
3273 struct acpi_buffer buffer = { sizeof(name), &name };
3275 if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
3276 !strncmp("_BCL", name, sizeof(name) - 1)) {
3277 *rv = handle;
3278 return AE_CTRL_TERMINATE;
3279 } else {
3280 return AE_OK;
3284 static int __init brightness_check_std_acpi_support(void)
3286 int status;
3287 void *found_node = NULL;
3289 if (!vid_handle) {
3290 IBM_ACPIHANDLE_INIT(vid);
3292 if (!vid_handle)
3293 return 0;
3295 /* Search for a _BCL method, but don't execute it */
3296 status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
3297 brightness_find_bcl, NULL, &found_node);
3299 return (ACPI_SUCCESS(status) && found_node != NULL);
3302 static int __init brightness_init(struct ibm_init_struct *iibm)
3304 int b;
3306 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
3308 mutex_init(&brightness_mutex);
3310 if (!brightness_enable) {
3311 dbg_printk(TPACPI_DBG_INIT,
3312 "brightness support disabled by module parameter\n");
3313 return 1;
3314 } else if (brightness_enable > 1) {
3315 if (brightness_check_std_acpi_support()) {
3316 printk(IBM_NOTICE
3317 "standard ACPI backlight interface available, not loading native one...\n");
3318 return 1;
3322 if (!brightness_mode) {
3323 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
3324 brightness_mode = 2;
3325 else
3326 brightness_mode = 3;
3328 dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n",
3329 brightness_mode);
3332 if (brightness_mode > 3)
3333 return -EINVAL;
3335 tp_features.bright_16levels =
3336 thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO &&
3337 brightness_check_levels();
3339 b = brightness_get(NULL);
3340 if (b < 0)
3341 return 1;
3343 if (tp_features.bright_16levels)
3344 printk(IBM_INFO "detected a 16-level brightness capable ThinkPad\n");
3346 ibm_backlight_device = backlight_device_register(
3347 TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
3348 &ibm_backlight_data);
3349 if (IS_ERR(ibm_backlight_device)) {
3350 printk(IBM_ERR "Could not register backlight device\n");
3351 return PTR_ERR(ibm_backlight_device);
3353 vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n");
3355 ibm_backlight_device->props.max_brightness =
3356 (tp_features.bright_16levels)? 15 : 7;
3357 ibm_backlight_device->props.brightness = b;
3358 backlight_update_status(ibm_backlight_device);
3360 return 0;
3363 static void brightness_exit(void)
3365 if (ibm_backlight_device) {
3366 vdbg_printk(TPACPI_DBG_EXIT,
3367 "calling backlight_device_unregister()\n");
3368 backlight_device_unregister(ibm_backlight_device);
3369 ibm_backlight_device = NULL;
3373 static int brightness_update_status(struct backlight_device *bd)
3375 /* it is the backlight class's job (caller) to handle
3376 * EINTR and other errors properly */
3377 return brightness_set(
3378 (bd->props.fb_blank == FB_BLANK_UNBLANK &&
3379 bd->props.power == FB_BLANK_UNBLANK) ?
3380 bd->props.brightness : 0);
3384 * ThinkPads can read brightness from two places: EC 0x31, or
3385 * CMOS NVRAM byte 0x5E, bits 0-3.
3387 static int brightness_get(struct backlight_device *bd)
3389 u8 lec = 0, lcmos = 0, level = 0;
3391 if (brightness_mode & 1) {
3392 if (!acpi_ec_read(brightness_offset, &lec))
3393 return -EIO;
3394 lec &= (tp_features.bright_16levels)? 0x0f : 0x07;
3395 level = lec;
3397 if (brightness_mode & 2) {
3398 lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
3399 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
3400 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
3401 lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07;
3402 level = lcmos;
3405 if (brightness_mode == 3 && lec != lcmos) {
3406 printk(IBM_ERR
3407 "CMOS NVRAM (%u) and EC (%u) do not agree "
3408 "on display brightness level\n",
3409 (unsigned int) lcmos,
3410 (unsigned int) lec);
3411 return -EIO;
3414 return level;
3417 /* May return EINTR which can always be mapped to ERESTARTSYS */
3418 static int brightness_set(int value)
3420 int cmos_cmd, inc, i, res;
3421 int current_value;
3423 if (value > ((tp_features.bright_16levels)? 15 : 7))
3424 return -EINVAL;
3426 res = mutex_lock_interruptible(&brightness_mutex);
3427 if (res < 0)
3428 return res;
3430 current_value = brightness_get(NULL);
3431 if (current_value < 0) {
3432 res = current_value;
3433 goto errout;
3436 cmos_cmd = value > current_value ?
3437 TP_CMOS_BRIGHTNESS_UP :
3438 TP_CMOS_BRIGHTNESS_DOWN;
3439 inc = (value > current_value)? 1 : -1;
3441 res = 0;
3442 for (i = current_value; i != value; i += inc) {
3443 if ((brightness_mode & 2) &&
3444 issue_thinkpad_cmos_command(cmos_cmd)) {
3445 res = -EIO;
3446 goto errout;
3448 if ((brightness_mode & 1) &&
3449 !acpi_ec_write(brightness_offset, i + inc)) {
3450 res = -EIO;
3451 goto errout;;
3455 errout:
3456 mutex_unlock(&brightness_mutex);
3457 return res;
3460 static int brightness_read(char *p)
3462 int len = 0;
3463 int level;
3465 if ((level = brightness_get(NULL)) < 0) {
3466 len += sprintf(p + len, "level:\t\tunreadable\n");
3467 } else {
3468 len += sprintf(p + len, "level:\t\t%d\n", level);
3469 len += sprintf(p + len, "commands:\tup, down\n");
3470 len += sprintf(p + len, "commands:\tlevel <level>"
3471 " (<level> is 0-%d)\n",
3472 (tp_features.bright_16levels) ? 15 : 7);
3475 return len;
3478 static int brightness_write(char *buf)
3480 int level;
3481 int rc;
3482 char *cmd;
3483 int max_level = (tp_features.bright_16levels) ? 15 : 7;
3485 level = brightness_get(NULL);
3486 if (level < 0)
3487 return level;
3489 while ((cmd = next_cmd(&buf))) {
3490 if (strlencmp(cmd, "up") == 0) {
3491 if (level < max_level)
3492 level++;
3493 } else if (strlencmp(cmd, "down") == 0) {
3494 if (level > 0)
3495 level--;
3496 } else if (sscanf(cmd, "level %d", &level) == 1 &&
3497 level >= 0 && level <= max_level) {
3498 /* new level set */
3499 } else
3500 return -EINVAL;
3504 * Now we know what the final level should be, so we try to set it.
3505 * Doing it this way makes the syscall restartable in case of EINTR
3507 rc = brightness_set(level);
3508 return (rc == -EINTR)? ERESTARTSYS : rc;
3511 static struct ibm_struct brightness_driver_data = {
3512 .name = "brightness",
3513 .read = brightness_read,
3514 .write = brightness_write,
3515 .exit = brightness_exit,
3518 /*************************************************************************
3519 * Volume subdriver
3522 static int volume_read(char *p)
3524 int len = 0;
3525 u8 level;
3527 if (!acpi_ec_read(volume_offset, &level)) {
3528 len += sprintf(p + len, "level:\t\tunreadable\n");
3529 } else {
3530 len += sprintf(p + len, "level:\t\t%d\n", level & 0xf);
3531 len += sprintf(p + len, "mute:\t\t%s\n", onoff(level, 6));
3532 len += sprintf(p + len, "commands:\tup, down, mute\n");
3533 len += sprintf(p + len, "commands:\tlevel <level>"
3534 " (<level> is 0-15)\n");
3537 return len;
3540 static int volume_write(char *buf)
3542 int cmos_cmd, inc, i;
3543 u8 level, mute;
3544 int new_level, new_mute;
3545 char *cmd;
3547 while ((cmd = next_cmd(&buf))) {
3548 if (!acpi_ec_read(volume_offset, &level))
3549 return -EIO;
3550 new_mute = mute = level & 0x40;
3551 new_level = level = level & 0xf;
3553 if (strlencmp(cmd, "up") == 0) {
3554 if (mute)
3555 new_mute = 0;
3556 else
3557 new_level = level == 15 ? 15 : level + 1;
3558 } else if (strlencmp(cmd, "down") == 0) {
3559 if (mute)
3560 new_mute = 0;
3561 else
3562 new_level = level == 0 ? 0 : level - 1;
3563 } else if (sscanf(cmd, "level %d", &new_level) == 1 &&
3564 new_level >= 0 && new_level <= 15) {
3565 /* new_level set */
3566 } else if (strlencmp(cmd, "mute") == 0) {
3567 new_mute = 0x40;
3568 } else
3569 return -EINVAL;
3571 if (new_level != level) { /* mute doesn't change */
3572 cmos_cmd = new_level > level ? TP_CMOS_VOLUME_UP : TP_CMOS_VOLUME_DOWN;
3573 inc = new_level > level ? 1 : -1;
3575 if (mute && (issue_thinkpad_cmos_command(cmos_cmd) ||
3576 !acpi_ec_write(volume_offset, level)))
3577 return -EIO;
3579 for (i = level; i != new_level; i += inc)
3580 if (issue_thinkpad_cmos_command(cmos_cmd) ||
3581 !acpi_ec_write(volume_offset, i + inc))
3582 return -EIO;
3584 if (mute && (issue_thinkpad_cmos_command(TP_CMOS_VOLUME_MUTE) ||
3585 !acpi_ec_write(volume_offset,
3586 new_level + mute)))
3587 return -EIO;
3590 if (new_mute != mute) { /* level doesn't change */
3591 cmos_cmd = new_mute ? TP_CMOS_VOLUME_MUTE : TP_CMOS_VOLUME_UP;
3593 if (issue_thinkpad_cmos_command(cmos_cmd) ||
3594 !acpi_ec_write(volume_offset, level + new_mute))
3595 return -EIO;
3599 return 0;
3602 static struct ibm_struct volume_driver_data = {
3603 .name = "volume",
3604 .read = volume_read,
3605 .write = volume_write,
3608 /*************************************************************************
3609 * Fan subdriver
3613 * FAN ACCESS MODES
3615 * TPACPI_FAN_RD_ACPI_GFAN:
3616 * ACPI GFAN method: returns fan level
3618 * see TPACPI_FAN_WR_ACPI_SFAN
3619 * EC 0x2f (HFSP) not available if GFAN exists
3621 * TPACPI_FAN_WR_ACPI_SFAN:
3622 * ACPI SFAN method: sets fan level, 0 (stop) to 7 (max)
3624 * EC 0x2f (HFSP) might be available *for reading*, but do not use
3625 * it for writing.
3627 * TPACPI_FAN_WR_TPEC:
3628 * ThinkPad EC register 0x2f (HFSP): fan control loop mode
3629 * Supported on almost all ThinkPads
3631 * Fan speed changes of any sort (including those caused by the
3632 * disengaged mode) are usually done slowly by the firmware as the
3633 * maximum ammount of fan duty cycle change per second seems to be
3634 * limited.
3636 * Reading is not available if GFAN exists.
3637 * Writing is not available if SFAN exists.
3639 * Bits
3640 * 7 automatic mode engaged;
3641 * (default operation mode of the ThinkPad)
3642 * fan level is ignored in this mode.
3643 * 6 full speed mode (takes precedence over bit 7);
3644 * not available on all thinkpads. May disable
3645 * the tachometer while the fan controller ramps up
3646 * the speed (which can take up to a few *minutes*).
3647 * Speeds up fan to 100% duty-cycle, which is far above
3648 * the standard RPM levels. It is not impossible that
3649 * it could cause hardware damage.
3650 * 5-3 unused in some models. Extra bits for fan level
3651 * in others, but still useless as all values above
3652 * 7 map to the same speed as level 7 in these models.
3653 * 2-0 fan level (0..7 usually)
3654 * 0x00 = stop
3655 * 0x07 = max (set when temperatures critical)
3656 * Some ThinkPads may have other levels, see
3657 * TPACPI_FAN_WR_ACPI_FANS (X31/X40/X41)
3659 * FIRMWARE BUG: on some models, EC 0x2f might not be initialized at
3660 * boot. Apparently the EC does not intialize it, so unless ACPI DSDT
3661 * does so, its initial value is meaningless (0x07).
3663 * For firmware bugs, refer to:
3664 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
3666 * ----
3668 * ThinkPad EC register 0x84 (LSB), 0x85 (MSB):
3669 * Main fan tachometer reading (in RPM)
3671 * This register is present on all ThinkPads with a new-style EC, and
3672 * it is known not to be present on the A21m/e, and T22, as there is
3673 * something else in offset 0x84 according to the ACPI DSDT. Other
3674 * ThinkPads from this same time period (and earlier) probably lack the
3675 * tachometer as well.
3677 * Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare
3678 * was never fixed by IBM to report the EC firmware version string
3679 * probably support the tachometer (like the early X models), so
3680 * detecting it is quite hard. We need more data to know for sure.
3682 * FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings
3683 * might result.
3685 * FIRMWARE BUG: may go stale while the EC is switching to full speed
3686 * mode.
3688 * For firmware bugs, refer to:
3689 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
3691 * TPACPI_FAN_WR_ACPI_FANS:
3692 * ThinkPad X31, X40, X41. Not available in the X60.
3694 * FANS ACPI handle: takes three arguments: low speed, medium speed,
3695 * high speed. ACPI DSDT seems to map these three speeds to levels
3696 * as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH
3697 * (this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3")
3699 * The speeds are stored on handles
3700 * (FANA:FAN9), (FANC:FANB), (FANE:FAND).
3702 * There are three default speed sets, acessible as handles:
3703 * FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H
3705 * ACPI DSDT switches which set is in use depending on various
3706 * factors.
3708 * TPACPI_FAN_WR_TPEC is also available and should be used to
3709 * command the fan. The X31/X40/X41 seems to have 8 fan levels,
3710 * but the ACPI tables just mention level 7.
3713 static enum fan_status_access_mode fan_status_access_mode;
3714 static enum fan_control_access_mode fan_control_access_mode;
3715 static enum fan_control_commands fan_control_commands;
3717 static u8 fan_control_initial_status;
3718 static u8 fan_control_desired_level;
3720 static void fan_watchdog_fire(struct work_struct *ignored);
3721 static int fan_watchdog_maxinterval;
3722 static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire);
3724 IBM_HANDLE(fans, ec, "FANS"); /* X31, X40, X41 */
3725 IBM_HANDLE(gfan, ec, "GFAN", /* 570 */
3726 "\\FSPD", /* 600e/x, 770e, 770x */
3727 ); /* all others */
3728 IBM_HANDLE(sfan, ec, "SFAN", /* 570 */
3729 "JFNS", /* 770x-JL */
3730 ); /* all others */
3733 * SYSFS fan layout: hwmon compatible (device)
3735 * pwm*_enable:
3736 * 0: "disengaged" mode
3737 * 1: manual mode
3738 * 2: native EC "auto" mode (recommended, hardware default)
3740 * pwm*: set speed in manual mode, ignored otherwise.
3741 * 0 is level 0; 255 is level 7. Intermediate points done with linear
3742 * interpolation.
3744 * fan*_input: tachometer reading, RPM
3747 * SYSFS fan layout: extensions
3749 * fan_watchdog (driver):
3750 * fan watchdog interval in seconds, 0 disables (default), max 120
3753 /* sysfs fan pwm1_enable ----------------------------------------------- */
3754 static ssize_t fan_pwm1_enable_show(struct device *dev,
3755 struct device_attribute *attr,
3756 char *buf)
3758 int res, mode;
3759 u8 status;
3761 res = fan_get_status_safe(&status);
3762 if (res)
3763 return res;
3765 if (unlikely(tp_features.fan_ctrl_status_undef)) {
3766 if (status != fan_control_initial_status) {
3767 tp_features.fan_ctrl_status_undef = 0;
3768 } else {
3769 /* Return most likely status. In fact, it
3770 * might be the only possible status */
3771 status = TP_EC_FAN_AUTO;
3775 if (status & TP_EC_FAN_FULLSPEED) {
3776 mode = 0;
3777 } else if (status & TP_EC_FAN_AUTO) {
3778 mode = 2;
3779 } else
3780 mode = 1;
3782 return snprintf(buf, PAGE_SIZE, "%d\n", mode);
3785 static ssize_t fan_pwm1_enable_store(struct device *dev,
3786 struct device_attribute *attr,
3787 const char *buf, size_t count)
3789 unsigned long t;
3790 int res, level;
3792 if (parse_strtoul(buf, 2, &t))
3793 return -EINVAL;
3795 switch (t) {
3796 case 0:
3797 level = TP_EC_FAN_FULLSPEED;
3798 break;
3799 case 1:
3800 level = TPACPI_FAN_LAST_LEVEL;
3801 break;
3802 case 2:
3803 level = TP_EC_FAN_AUTO;
3804 break;
3805 case 3:
3806 /* reserved for software-controlled auto mode */
3807 return -ENOSYS;
3808 default:
3809 return -EINVAL;
3812 res = fan_set_level_safe(level);
3813 if (res == -ENXIO)
3814 return -EINVAL;
3815 else if (res < 0)
3816 return res;
3818 fan_watchdog_reset();
3820 return count;
3823 static struct device_attribute dev_attr_fan_pwm1_enable =
3824 __ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
3825 fan_pwm1_enable_show, fan_pwm1_enable_store);
3827 /* sysfs fan pwm1 ------------------------------------------------------ */
3828 static ssize_t fan_pwm1_show(struct device *dev,
3829 struct device_attribute *attr,
3830 char *buf)
3832 int res;
3833 u8 status;
3835 res = fan_get_status_safe(&status);
3836 if (res)
3837 return res;
3839 if (unlikely(tp_features.fan_ctrl_status_undef)) {
3840 if (status != fan_control_initial_status) {
3841 tp_features.fan_ctrl_status_undef = 0;
3842 } else {
3843 status = TP_EC_FAN_AUTO;
3847 if ((status &
3848 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0)
3849 status = fan_control_desired_level;
3851 if (status > 7)
3852 status = 7;
3854 return snprintf(buf, PAGE_SIZE, "%u\n", (status * 255) / 7);
3857 static ssize_t fan_pwm1_store(struct device *dev,
3858 struct device_attribute *attr,
3859 const char *buf, size_t count)
3861 unsigned long s;
3862 int rc;
3863 u8 status, newlevel;
3865 if (parse_strtoul(buf, 255, &s))
3866 return -EINVAL;
3868 /* scale down from 0-255 to 0-7 */
3869 newlevel = (s >> 5) & 0x07;
3871 if (mutex_lock_interruptible(&fan_mutex))
3872 return -ERESTARTSYS;
3874 rc = fan_get_status(&status);
3875 if (!rc && (status &
3876 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
3877 rc = fan_set_level(newlevel);
3878 if (rc == -ENXIO)
3879 rc = -EINVAL;
3880 else if (!rc) {
3881 fan_update_desired_level(newlevel);
3882 fan_watchdog_reset();
3886 mutex_unlock(&fan_mutex);
3887 return (rc)? rc : count;
3890 static struct device_attribute dev_attr_fan_pwm1 =
3891 __ATTR(pwm1, S_IWUSR | S_IRUGO,
3892 fan_pwm1_show, fan_pwm1_store);
3894 /* sysfs fan fan1_input ------------------------------------------------ */
3895 static ssize_t fan_fan1_input_show(struct device *dev,
3896 struct device_attribute *attr,
3897 char *buf)
3899 int res;
3900 unsigned int speed;
3902 res = fan_get_speed(&speed);
3903 if (res < 0)
3904 return res;
3906 return snprintf(buf, PAGE_SIZE, "%u\n", speed);
3909 static struct device_attribute dev_attr_fan_fan1_input =
3910 __ATTR(fan1_input, S_IRUGO,
3911 fan_fan1_input_show, NULL);
3913 /* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */
3914 static ssize_t fan_fan_watchdog_show(struct device_driver *drv,
3915 char *buf)
3917 return snprintf(buf, PAGE_SIZE, "%u\n", fan_watchdog_maxinterval);
3920 static ssize_t fan_fan_watchdog_store(struct device_driver *drv,
3921 const char *buf, size_t count)
3923 unsigned long t;
3925 if (parse_strtoul(buf, 120, &t))
3926 return -EINVAL;
3928 if (!fan_control_allowed)
3929 return -EPERM;
3931 fan_watchdog_maxinterval = t;
3932 fan_watchdog_reset();
3934 return count;
3937 static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO,
3938 fan_fan_watchdog_show, fan_fan_watchdog_store);
3940 /* --------------------------------------------------------------------- */
3941 static struct attribute *fan_attributes[] = {
3942 &dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr,
3943 &dev_attr_fan_fan1_input.attr,
3944 NULL
3947 static const struct attribute_group fan_attr_group = {
3948 .attrs = fan_attributes,
3951 static int __init fan_init(struct ibm_init_struct *iibm)
3953 int rc;
3955 vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
3957 mutex_init(&fan_mutex);
3958 fan_status_access_mode = TPACPI_FAN_NONE;
3959 fan_control_access_mode = TPACPI_FAN_WR_NONE;
3960 fan_control_commands = 0;
3961 fan_watchdog_maxinterval = 0;
3962 tp_features.fan_ctrl_status_undef = 0;
3963 fan_control_desired_level = 7;
3965 IBM_ACPIHANDLE_INIT(fans);
3966 IBM_ACPIHANDLE_INIT(gfan);
3967 IBM_ACPIHANDLE_INIT(sfan);
3969 if (gfan_handle) {
3970 /* 570, 600e/x, 770e, 770x */
3971 fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN;
3972 } else {
3973 /* all other ThinkPads: note that even old-style
3974 * ThinkPad ECs supports the fan control register */
3975 if (likely(acpi_ec_read(fan_status_offset,
3976 &fan_control_initial_status))) {
3977 fan_status_access_mode = TPACPI_FAN_RD_TPEC;
3979 /* In some ThinkPads, neither the EC nor the ACPI
3980 * DSDT initialize the fan status, and it ends up
3981 * being set to 0x07 when it *could* be either
3982 * 0x07 or 0x80.
3984 * Enable for TP-1Y (T43), TP-78 (R51e),
3985 * TP-76 (R52), TP-70 (T43, R52), which are known
3986 * to be buggy. */
3987 if (fan_control_initial_status == 0x07) {
3988 switch (thinkpad_id.ec_model) {
3989 case 0x5931: /* TP-1Y */
3990 case 0x3837: /* TP-78 */
3991 case 0x3637: /* TP-76 */
3992 case 0x3037: /* TP-70 */
3993 printk(IBM_NOTICE
3994 "fan_init: initial fan status is "
3995 "unknown, assuming it is in auto "
3996 "mode\n");
3997 tp_features.fan_ctrl_status_undef = 1;
4001 } else {
4002 printk(IBM_ERR
4003 "ThinkPad ACPI EC access misbehaving, "
4004 "fan status and control unavailable\n");
4005 return 1;
4009 if (sfan_handle) {
4010 /* 570, 770x-JL */
4011 fan_control_access_mode = TPACPI_FAN_WR_ACPI_SFAN;
4012 fan_control_commands |=
4013 TPACPI_FAN_CMD_LEVEL | TPACPI_FAN_CMD_ENABLE;
4014 } else {
4015 if (!gfan_handle) {
4016 /* gfan without sfan means no fan control */
4017 /* all other models implement TP EC 0x2f control */
4019 if (fans_handle) {
4020 /* X31, X40, X41 */
4021 fan_control_access_mode =
4022 TPACPI_FAN_WR_ACPI_FANS;
4023 fan_control_commands |=
4024 TPACPI_FAN_CMD_SPEED |
4025 TPACPI_FAN_CMD_LEVEL |
4026 TPACPI_FAN_CMD_ENABLE;
4027 } else {
4028 fan_control_access_mode = TPACPI_FAN_WR_TPEC;
4029 fan_control_commands |=
4030 TPACPI_FAN_CMD_LEVEL |
4031 TPACPI_FAN_CMD_ENABLE;
4036 vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n",
4037 str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||
4038 fan_control_access_mode != TPACPI_FAN_WR_NONE),
4039 fan_status_access_mode, fan_control_access_mode);
4041 /* fan control master switch */
4042 if (!fan_control_allowed) {
4043 fan_control_access_mode = TPACPI_FAN_WR_NONE;
4044 fan_control_commands = 0;
4045 dbg_printk(TPACPI_DBG_INIT,
4046 "fan control features disabled by parameter\n");
4049 /* update fan_control_desired_level */
4050 if (fan_status_access_mode != TPACPI_FAN_NONE)
4051 fan_get_status_safe(NULL);
4053 if (fan_status_access_mode != TPACPI_FAN_NONE ||
4054 fan_control_access_mode != TPACPI_FAN_WR_NONE) {
4055 rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
4056 &fan_attr_group);
4057 if (!(rc < 0))
4058 rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
4059 &driver_attr_fan_watchdog);
4060 if (rc < 0)
4061 return rc;
4062 return 0;
4063 } else
4064 return 1;
4068 * Call with fan_mutex held
4070 static void fan_update_desired_level(u8 status)
4072 if ((status &
4073 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
4074 if (status > 7)
4075 fan_control_desired_level = 7;
4076 else
4077 fan_control_desired_level = status;
4081 static int fan_get_status(u8 *status)
4083 u8 s;
4085 /* TODO:
4086 * Add TPACPI_FAN_RD_ACPI_FANS ? */
4088 switch (fan_status_access_mode) {
4089 case TPACPI_FAN_RD_ACPI_GFAN:
4090 /* 570, 600e/x, 770e, 770x */
4092 if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d")))
4093 return -EIO;
4095 if (likely(status))
4096 *status = s & 0x07;
4098 break;
4100 case TPACPI_FAN_RD_TPEC:
4101 /* all except 570, 600e/x, 770e, 770x */
4102 if (unlikely(!acpi_ec_read(fan_status_offset, &s)))
4103 return -EIO;
4105 if (likely(status))
4106 *status = s;
4108 break;
4110 default:
4111 return -ENXIO;
4114 return 0;
4117 static int fan_get_status_safe(u8 *status)
4119 int rc;
4120 u8 s;
4122 if (mutex_lock_interruptible(&fan_mutex))
4123 return -ERESTARTSYS;
4124 rc = fan_get_status(&s);
4125 if (!rc)
4126 fan_update_desired_level(s);
4127 mutex_unlock(&fan_mutex);
4129 if (status)
4130 *status = s;
4132 return rc;
4135 static void fan_exit(void)
4137 vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending fan watchdog tasks\n");
4139 /* FIXME: can we really do this unconditionally? */
4140 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group);
4141 driver_remove_file(&tpacpi_hwmon_pdriver.driver, &driver_attr_fan_watchdog);
4143 cancel_delayed_work(&fan_watchdog_task);
4144 flush_scheduled_work();
4147 static int fan_get_speed(unsigned int *speed)
4149 u8 hi, lo;
4151 switch (fan_status_access_mode) {
4152 case TPACPI_FAN_RD_TPEC:
4153 /* all except 570, 600e/x, 770e, 770x */
4154 if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) ||
4155 !acpi_ec_read(fan_rpm_offset + 1, &hi)))
4156 return -EIO;
4158 if (likely(speed))
4159 *speed = (hi << 8) | lo;
4161 break;
4163 default:
4164 return -ENXIO;
4167 return 0;
4170 static void fan_watchdog_fire(struct work_struct *ignored)
4172 int rc;
4174 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
4175 return;
4177 printk(IBM_NOTICE "fan watchdog: enabling fan\n");
4178 rc = fan_set_enable();
4179 if (rc < 0) {
4180 printk(IBM_ERR "fan watchdog: error %d while enabling fan, "
4181 "will try again later...\n", -rc);
4182 /* reschedule for later */
4183 fan_watchdog_reset();
4187 static void fan_watchdog_reset(void)
4189 static int fan_watchdog_active;
4191 if (fan_control_access_mode == TPACPI_FAN_WR_NONE)
4192 return;
4194 if (fan_watchdog_active)
4195 cancel_delayed_work(&fan_watchdog_task);
4197 if (fan_watchdog_maxinterval > 0 &&
4198 tpacpi_lifecycle != TPACPI_LIFE_EXITING) {
4199 fan_watchdog_active = 1;
4200 if (!schedule_delayed_work(&fan_watchdog_task,
4201 msecs_to_jiffies(fan_watchdog_maxinterval
4202 * 1000))) {
4203 printk(IBM_ERR "failed to schedule the fan watchdog, "
4204 "watchdog will not trigger\n");
4206 } else
4207 fan_watchdog_active = 0;
4210 static int fan_set_level(int level)
4212 if (!fan_control_allowed)
4213 return -EPERM;
4215 switch (fan_control_access_mode) {
4216 case TPACPI_FAN_WR_ACPI_SFAN:
4217 if (level >= 0 && level <= 7) {
4218 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
4219 return -EIO;
4220 } else
4221 return -EINVAL;
4222 break;
4224 case TPACPI_FAN_WR_ACPI_FANS:
4225 case TPACPI_FAN_WR_TPEC:
4226 if ((level != TP_EC_FAN_AUTO) &&
4227 (level != TP_EC_FAN_FULLSPEED) &&
4228 ((level < 0) || (level > 7)))
4229 return -EINVAL;
4231 /* safety net should the EC not support AUTO
4232 * or FULLSPEED mode bits and just ignore them */
4233 if (level & TP_EC_FAN_FULLSPEED)
4234 level |= 7; /* safety min speed 7 */
4235 else if (level & TP_EC_FAN_FULLSPEED)
4236 level |= 4; /* safety min speed 4 */
4238 if (!acpi_ec_write(fan_status_offset, level))
4239 return -EIO;
4240 else
4241 tp_features.fan_ctrl_status_undef = 0;
4242 break;
4244 default:
4245 return -ENXIO;
4247 return 0;
4250 static int fan_set_level_safe(int level)
4252 int rc;
4254 if (!fan_control_allowed)
4255 return -EPERM;
4257 if (mutex_lock_interruptible(&fan_mutex))
4258 return -ERESTARTSYS;
4260 if (level == TPACPI_FAN_LAST_LEVEL)
4261 level = fan_control_desired_level;
4263 rc = fan_set_level(level);
4264 if (!rc)
4265 fan_update_desired_level(level);
4267 mutex_unlock(&fan_mutex);
4268 return rc;
4271 static int fan_set_enable(void)
4273 u8 s;
4274 int rc;
4276 if (!fan_control_allowed)
4277 return -EPERM;
4279 if (mutex_lock_interruptible(&fan_mutex))
4280 return -ERESTARTSYS;
4282 switch (fan_control_access_mode) {
4283 case TPACPI_FAN_WR_ACPI_FANS:
4284 case TPACPI_FAN_WR_TPEC:
4285 rc = fan_get_status(&s);
4286 if (rc < 0)
4287 break;
4289 /* Don't go out of emergency fan mode */
4290 if (s != 7) {
4291 s &= 0x07;
4292 s |= TP_EC_FAN_AUTO | 4; /* min fan speed 4 */
4295 if (!acpi_ec_write(fan_status_offset, s))
4296 rc = -EIO;
4297 else {
4298 tp_features.fan_ctrl_status_undef = 0;
4299 rc = 0;
4301 break;
4303 case TPACPI_FAN_WR_ACPI_SFAN:
4304 rc = fan_get_status(&s);
4305 if (rc < 0)
4306 break;
4308 s &= 0x07;
4310 /* Set fan to at least level 4 */
4311 s |= 4;
4313 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s))
4314 rc= -EIO;
4315 else
4316 rc = 0;
4317 break;
4319 default:
4320 rc = -ENXIO;
4323 mutex_unlock(&fan_mutex);
4324 return rc;
4327 static int fan_set_disable(void)
4329 int rc;
4331 if (!fan_control_allowed)
4332 return -EPERM;
4334 if (mutex_lock_interruptible(&fan_mutex))
4335 return -ERESTARTSYS;
4337 rc = 0;
4338 switch (fan_control_access_mode) {
4339 case TPACPI_FAN_WR_ACPI_FANS:
4340 case TPACPI_FAN_WR_TPEC:
4341 if (!acpi_ec_write(fan_status_offset, 0x00))
4342 rc = -EIO;
4343 else {
4344 fan_control_desired_level = 0;
4345 tp_features.fan_ctrl_status_undef = 0;
4347 break;
4349 case TPACPI_FAN_WR_ACPI_SFAN:
4350 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))
4351 rc = -EIO;
4352 else
4353 fan_control_desired_level = 0;
4354 break;
4356 default:
4357 rc = -ENXIO;
4361 mutex_unlock(&fan_mutex);
4362 return rc;
4365 static int fan_set_speed(int speed)
4367 int rc;
4369 if (!fan_control_allowed)
4370 return -EPERM;
4372 if (mutex_lock_interruptible(&fan_mutex))
4373 return -ERESTARTSYS;
4375 rc = 0;
4376 switch (fan_control_access_mode) {
4377 case TPACPI_FAN_WR_ACPI_FANS:
4378 if (speed >= 0 && speed <= 65535) {
4379 if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
4380 speed, speed, speed))
4381 rc = -EIO;
4382 } else
4383 rc = -EINVAL;
4384 break;
4386 default:
4387 rc = -ENXIO;
4390 mutex_unlock(&fan_mutex);
4391 return rc;
4394 static int fan_read(char *p)
4396 int len = 0;
4397 int rc;
4398 u8 status;
4399 unsigned int speed = 0;
4401 switch (fan_status_access_mode) {
4402 case TPACPI_FAN_RD_ACPI_GFAN:
4403 /* 570, 600e/x, 770e, 770x */
4404 if ((rc = fan_get_status_safe(&status)) < 0)
4405 return rc;
4407 len += sprintf(p + len, "status:\t\t%s\n"
4408 "level:\t\t%d\n",
4409 (status != 0) ? "enabled" : "disabled", status);
4410 break;
4412 case TPACPI_FAN_RD_TPEC:
4413 /* all except 570, 600e/x, 770e, 770x */
4414 if ((rc = fan_get_status_safe(&status)) < 0)
4415 return rc;
4417 if (unlikely(tp_features.fan_ctrl_status_undef)) {
4418 if (status != fan_control_initial_status)
4419 tp_features.fan_ctrl_status_undef = 0;
4420 else
4421 /* Return most likely status. In fact, it
4422 * might be the only possible status */
4423 status = TP_EC_FAN_AUTO;
4426 len += sprintf(p + len, "status:\t\t%s\n",
4427 (status != 0) ? "enabled" : "disabled");
4429 if ((rc = fan_get_speed(&speed)) < 0)
4430 return rc;
4432 len += sprintf(p + len, "speed:\t\t%d\n", speed);
4434 if (status & TP_EC_FAN_FULLSPEED)
4435 /* Disengaged mode takes precedence */
4436 len += sprintf(p + len, "level:\t\tdisengaged\n");
4437 else if (status & TP_EC_FAN_AUTO)
4438 len += sprintf(p + len, "level:\t\tauto\n");
4439 else
4440 len += sprintf(p + len, "level:\t\t%d\n", status);
4441 break;
4443 case TPACPI_FAN_NONE:
4444 default:
4445 len += sprintf(p + len, "status:\t\tnot supported\n");
4448 if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) {
4449 len += sprintf(p + len, "commands:\tlevel <level>");
4451 switch (fan_control_access_mode) {
4452 case TPACPI_FAN_WR_ACPI_SFAN:
4453 len += sprintf(p + len, " (<level> is 0-7)\n");
4454 break;
4456 default:
4457 len += sprintf(p + len, " (<level> is 0-7, "
4458 "auto, disengaged, full-speed)\n");
4459 break;
4463 if (fan_control_commands & TPACPI_FAN_CMD_ENABLE)
4464 len += sprintf(p + len, "commands:\tenable, disable\n"
4465 "commands:\twatchdog <timeout> (<timeout> is 0 (off), "
4466 "1-120 (seconds))\n");
4468 if (fan_control_commands & TPACPI_FAN_CMD_SPEED)
4469 len += sprintf(p + len, "commands:\tspeed <speed>"
4470 " (<speed> is 0-65535)\n");
4472 return len;
4475 static int fan_write_cmd_level(const char *cmd, int *rc)
4477 int level;
4479 if (strlencmp(cmd, "level auto") == 0)
4480 level = TP_EC_FAN_AUTO;
4481 else if ((strlencmp(cmd, "level disengaged") == 0) |
4482 (strlencmp(cmd, "level full-speed") == 0))
4483 level = TP_EC_FAN_FULLSPEED;
4484 else if (sscanf(cmd, "level %d", &level) != 1)
4485 return 0;
4487 if ((*rc = fan_set_level_safe(level)) == -ENXIO)
4488 printk(IBM_ERR "level command accepted for unsupported "
4489 "access mode %d", fan_control_access_mode);
4491 return 1;
4494 static int fan_write_cmd_enable(const char *cmd, int *rc)
4496 if (strlencmp(cmd, "enable") != 0)
4497 return 0;
4499 if ((*rc = fan_set_enable()) == -ENXIO)
4500 printk(IBM_ERR "enable command accepted for unsupported "
4501 "access mode %d", fan_control_access_mode);
4503 return 1;
4506 static int fan_write_cmd_disable(const char *cmd, int *rc)
4508 if (strlencmp(cmd, "disable") != 0)
4509 return 0;
4511 if ((*rc = fan_set_disable()) == -ENXIO)
4512 printk(IBM_ERR "disable command accepted for unsupported "
4513 "access mode %d", fan_control_access_mode);
4515 return 1;
4518 static int fan_write_cmd_speed(const char *cmd, int *rc)
4520 int speed;
4522 /* TODO:
4523 * Support speed <low> <medium> <high> ? */
4525 if (sscanf(cmd, "speed %d", &speed) != 1)
4526 return 0;
4528 if ((*rc = fan_set_speed(speed)) == -ENXIO)
4529 printk(IBM_ERR "speed command accepted for unsupported "
4530 "access mode %d", fan_control_access_mode);
4532 return 1;
4535 static int fan_write_cmd_watchdog(const char *cmd, int *rc)
4537 int interval;
4539 if (sscanf(cmd, "watchdog %d", &interval) != 1)
4540 return 0;
4542 if (interval < 0 || interval > 120)
4543 *rc = -EINVAL;
4544 else
4545 fan_watchdog_maxinterval = interval;
4547 return 1;
4550 static int fan_write(char *buf)
4552 char *cmd;
4553 int rc = 0;
4555 while (!rc && (cmd = next_cmd(&buf))) {
4556 if (!((fan_control_commands & TPACPI_FAN_CMD_LEVEL) &&
4557 fan_write_cmd_level(cmd, &rc)) &&
4558 !((fan_control_commands & TPACPI_FAN_CMD_ENABLE) &&
4559 (fan_write_cmd_enable(cmd, &rc) ||
4560 fan_write_cmd_disable(cmd, &rc) ||
4561 fan_write_cmd_watchdog(cmd, &rc))) &&
4562 !((fan_control_commands & TPACPI_FAN_CMD_SPEED) &&
4563 fan_write_cmd_speed(cmd, &rc))
4565 rc = -EINVAL;
4566 else if (!rc)
4567 fan_watchdog_reset();
4570 return rc;
4573 static struct ibm_struct fan_driver_data = {
4574 .name = "fan",
4575 .read = fan_read,
4576 .write = fan_write,
4577 .exit = fan_exit,
4580 /****************************************************************************
4581 ****************************************************************************
4583 * Infrastructure
4585 ****************************************************************************
4586 ****************************************************************************/
4588 /* sysfs name ---------------------------------------------------------- */
4589 static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev,
4590 struct device_attribute *attr,
4591 char *buf)
4593 return snprintf(buf, PAGE_SIZE, "%s\n", IBM_NAME);
4596 static struct device_attribute dev_attr_thinkpad_acpi_pdev_name =
4597 __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL);
4599 /* --------------------------------------------------------------------- */
4601 /* /proc support */
4602 static struct proc_dir_entry *proc_dir;
4604 /* Subdriver registry */
4605 static LIST_HEAD(tpacpi_all_drivers);
4609 * Module and infrastructure proble, init and exit handling
4612 #ifdef CONFIG_THINKPAD_ACPI_DEBUG
4613 static const char * __init str_supported(int is_supported)
4615 static char text_unsupported[] __initdata = "not supported";
4617 return (is_supported)? &text_unsupported[4] : &text_unsupported[0];
4619 #endif /* CONFIG_THINKPAD_ACPI_DEBUG */
4621 static int __init ibm_init(struct ibm_init_struct *iibm)
4623 int ret;
4624 struct ibm_struct *ibm = iibm->data;
4625 struct proc_dir_entry *entry;
4627 BUG_ON(ibm == NULL);
4629 INIT_LIST_HEAD(&ibm->all_drivers);
4631 if (ibm->flags.experimental && !experimental)
4632 return 0;
4634 dbg_printk(TPACPI_DBG_INIT,
4635 "probing for %s\n", ibm->name);
4637 if (iibm->init) {
4638 ret = iibm->init(iibm);
4639 if (ret > 0)
4640 return 0; /* probe failed */
4641 if (ret)
4642 return ret;
4644 ibm->flags.init_called = 1;
4647 if (ibm->acpi) {
4648 if (ibm->acpi->hid) {
4649 ret = register_tpacpi_subdriver(ibm);
4650 if (ret)
4651 goto err_out;
4654 if (ibm->acpi->notify) {
4655 ret = setup_acpi_notify(ibm);
4656 if (ret == -ENODEV) {
4657 printk(IBM_NOTICE "disabling subdriver %s\n",
4658 ibm->name);
4659 ret = 0;
4660 goto err_out;
4662 if (ret < 0)
4663 goto err_out;
4667 dbg_printk(TPACPI_DBG_INIT,
4668 "%s installed\n", ibm->name);
4670 if (ibm->read) {
4671 entry = create_proc_entry(ibm->name,
4672 S_IFREG | S_IRUGO | S_IWUSR,
4673 proc_dir);
4674 if (!entry) {
4675 printk(IBM_ERR "unable to create proc entry %s\n",
4676 ibm->name);
4677 ret = -ENODEV;
4678 goto err_out;
4680 entry->owner = THIS_MODULE;
4681 entry->data = ibm;
4682 entry->read_proc = &dispatch_procfs_read;
4683 if (ibm->write)
4684 entry->write_proc = &dispatch_procfs_write;
4685 ibm->flags.proc_created = 1;
4688 list_add_tail(&ibm->all_drivers, &tpacpi_all_drivers);
4690 return 0;
4692 err_out:
4693 dbg_printk(TPACPI_DBG_INIT,
4694 "%s: at error exit path with result %d\n",
4695 ibm->name, ret);
4697 ibm_exit(ibm);
4698 return (ret < 0)? ret : 0;
4701 static void ibm_exit(struct ibm_struct *ibm)
4703 dbg_printk(TPACPI_DBG_EXIT, "removing %s\n", ibm->name);
4705 list_del_init(&ibm->all_drivers);
4707 if (ibm->flags.acpi_notify_installed) {
4708 dbg_printk(TPACPI_DBG_EXIT,
4709 "%s: acpi_remove_notify_handler\n", ibm->name);
4710 BUG_ON(!ibm->acpi);
4711 acpi_remove_notify_handler(*ibm->acpi->handle,
4712 ibm->acpi->type,
4713 dispatch_acpi_notify);
4714 ibm->flags.acpi_notify_installed = 0;
4715 ibm->flags.acpi_notify_installed = 0;
4718 if (ibm->flags.proc_created) {
4719 dbg_printk(TPACPI_DBG_EXIT,
4720 "%s: remove_proc_entry\n", ibm->name);
4721 remove_proc_entry(ibm->name, proc_dir);
4722 ibm->flags.proc_created = 0;
4725 if (ibm->flags.acpi_driver_registered) {
4726 dbg_printk(TPACPI_DBG_EXIT,
4727 "%s: acpi_bus_unregister_driver\n", ibm->name);
4728 BUG_ON(!ibm->acpi);
4729 acpi_bus_unregister_driver(ibm->acpi->driver);
4730 kfree(ibm->acpi->driver);
4731 ibm->acpi->driver = NULL;
4732 ibm->flags.acpi_driver_registered = 0;
4735 if (ibm->flags.init_called && ibm->exit) {
4736 ibm->exit();
4737 ibm->flags.init_called = 0;
4740 dbg_printk(TPACPI_DBG_INIT, "finished removing %s\n", ibm->name);
4743 /* Probing */
4745 static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
4747 const struct dmi_device *dev = NULL;
4748 char ec_fw_string[18];
4750 if (!tp)
4751 return;
4753 memset(tp, 0, sizeof(*tp));
4755 if (dmi_name_in_vendors("IBM"))
4756 tp->vendor = PCI_VENDOR_ID_IBM;
4757 else if (dmi_name_in_vendors("LENOVO"))
4758 tp->vendor = PCI_VENDOR_ID_LENOVO;
4759 else
4760 return;
4762 tp->bios_version_str = kstrdup(dmi_get_system_info(DMI_BIOS_VERSION),
4763 GFP_KERNEL);
4764 if (!tp->bios_version_str)
4765 return;
4766 tp->bios_model = tp->bios_version_str[0]
4767 | (tp->bios_version_str[1] << 8);
4770 * ThinkPad T23 or newer, A31 or newer, R50e or newer,
4771 * X32 or newer, all Z series; Some models must have an
4772 * up-to-date BIOS or they will not be detected.
4774 * See http://thinkwiki.org/wiki/List_of_DMI_IDs
4776 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
4777 if (sscanf(dev->name,
4778 "IBM ThinkPad Embedded Controller -[%17c",
4779 ec_fw_string) == 1) {
4780 ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
4781 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
4783 tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL);
4784 tp->ec_model = ec_fw_string[0]
4785 | (ec_fw_string[1] << 8);
4786 break;
4790 tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION),
4791 GFP_KERNEL);
4792 if (strnicmp(tp->model_str, "ThinkPad", 8) != 0) {
4793 kfree(tp->model_str);
4794 tp->model_str = NULL;
4798 static int __init probe_for_thinkpad(void)
4800 int is_thinkpad;
4802 if (acpi_disabled)
4803 return -ENODEV;
4806 * Non-ancient models have better DMI tagging, but very old models
4807 * don't.
4809 is_thinkpad = (thinkpad_id.model_str != NULL);
4811 /* ec is required because many other handles are relative to it */
4812 IBM_ACPIHANDLE_INIT(ec);
4813 if (!ec_handle) {
4814 if (is_thinkpad)
4815 printk(IBM_ERR
4816 "Not yet supported ThinkPad detected!\n");
4817 return -ENODEV;
4821 * Risks a regression on very old machines, but reduces potential
4822 * false positives a damn great deal
4824 if (!is_thinkpad)
4825 is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM);
4827 if (!is_thinkpad && !force_load)
4828 return -ENODEV;
4830 return 0;
4834 /* Module init, exit, parameters */
4836 static struct ibm_init_struct ibms_init[] __initdata = {
4838 .init = thinkpad_acpi_driver_init,
4839 .data = &thinkpad_acpi_driver_data,
4842 .init = hotkey_init,
4843 .data = &hotkey_driver_data,
4846 .init = bluetooth_init,
4847 .data = &bluetooth_driver_data,
4850 .init = wan_init,
4851 .data = &wan_driver_data,
4854 .init = video_init,
4855 .data = &video_driver_data,
4858 .init = light_init,
4859 .data = &light_driver_data,
4861 #ifdef CONFIG_THINKPAD_ACPI_DOCK
4863 .init = dock_init,
4864 .data = &dock_driver_data[0],
4867 .init = dock_init2,
4868 .data = &dock_driver_data[1],
4870 #endif
4871 #ifdef CONFIG_THINKPAD_ACPI_BAY
4873 .init = bay_init,
4874 .data = &bay_driver_data,
4876 #endif
4878 .init = cmos_init,
4879 .data = &cmos_driver_data,
4882 .init = led_init,
4883 .data = &led_driver_data,
4886 .init = beep_init,
4887 .data = &beep_driver_data,
4890 .init = thermal_init,
4891 .data = &thermal_driver_data,
4894 .data = &ecdump_driver_data,
4897 .init = brightness_init,
4898 .data = &brightness_driver_data,
4901 .data = &volume_driver_data,
4904 .init = fan_init,
4905 .data = &fan_driver_data,
4909 static int __init set_ibm_param(const char *val, struct kernel_param *kp)
4911 unsigned int i;
4912 struct ibm_struct *ibm;
4914 if (!kp || !kp->name || !val)
4915 return -EINVAL;
4917 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
4918 ibm = ibms_init[i].data;
4919 WARN_ON(ibm == NULL);
4921 if (!ibm || !ibm->name)
4922 continue;
4924 if (strcmp(ibm->name, kp->name) == 0 && ibm->write) {
4925 if (strlen(val) > sizeof(ibms_init[i].param) - 2)
4926 return -ENOSPC;
4927 strcpy(ibms_init[i].param, val);
4928 strcat(ibms_init[i].param, ",");
4929 return 0;
4933 return -EINVAL;
4936 static int experimental;
4937 module_param(experimental, int, 0);
4939 static u32 dbg_level;
4940 module_param_named(debug, dbg_level, uint, 0);
4942 static int force_load;
4943 module_param(force_load, bool, 0);
4945 static int fan_control_allowed;
4946 module_param_named(fan_control, fan_control_allowed, bool, 0);
4948 static int brightness_mode;
4949 module_param_named(brightness_mode, brightness_mode, int, 0);
4951 static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
4952 module_param(brightness_enable, uint, 0);
4954 static unsigned int hotkey_report_mode;
4955 module_param(hotkey_report_mode, uint, 0);
4957 #define IBM_PARAM(feature) \
4958 module_param_call(feature, set_ibm_param, NULL, NULL, 0)
4960 IBM_PARAM(hotkey);
4961 IBM_PARAM(bluetooth);
4962 IBM_PARAM(video);
4963 IBM_PARAM(light);
4964 #ifdef CONFIG_THINKPAD_ACPI_DOCK
4965 IBM_PARAM(dock);
4966 #endif
4967 #ifdef CONFIG_THINKPAD_ACPI_BAY
4968 IBM_PARAM(bay);
4969 #endif /* CONFIG_THINKPAD_ACPI_BAY */
4970 IBM_PARAM(cmos);
4971 IBM_PARAM(led);
4972 IBM_PARAM(beep);
4973 IBM_PARAM(ecdump);
4974 IBM_PARAM(brightness);
4975 IBM_PARAM(volume);
4976 IBM_PARAM(fan);
4978 static int __init thinkpad_acpi_module_init(void)
4980 int ret, i;
4982 tpacpi_lifecycle = TPACPI_LIFE_INIT;
4984 /* Parameter checking */
4985 if (hotkey_report_mode > 2)
4986 return -EINVAL;
4988 /* Driver-level probe */
4990 get_thinkpad_model_data(&thinkpad_id);
4991 ret = probe_for_thinkpad();
4992 if (ret) {
4993 thinkpad_acpi_module_exit();
4994 return ret;
4997 /* Driver initialization */
4999 IBM_ACPIHANDLE_INIT(ecrd);
5000 IBM_ACPIHANDLE_INIT(ecwr);
5002 proc_dir = proc_mkdir(IBM_PROC_DIR, acpi_root_dir);
5003 if (!proc_dir) {
5004 printk(IBM_ERR "unable to create proc dir " IBM_PROC_DIR);
5005 thinkpad_acpi_module_exit();
5006 return -ENODEV;
5008 proc_dir->owner = THIS_MODULE;
5010 ret = platform_driver_register(&tpacpi_pdriver);
5011 if (ret) {
5012 printk(IBM_ERR "unable to register main platform driver\n");
5013 thinkpad_acpi_module_exit();
5014 return ret;
5016 tp_features.platform_drv_registered = 1;
5018 ret = platform_driver_register(&tpacpi_hwmon_pdriver);
5019 if (ret) {
5020 printk(IBM_ERR "unable to register hwmon platform driver\n");
5021 thinkpad_acpi_module_exit();
5022 return ret;
5024 tp_features.sensors_pdrv_registered = 1;
5026 ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
5027 if (!ret) {
5028 tp_features.platform_drv_attrs_registered = 1;
5029 ret = tpacpi_create_driver_attributes(&tpacpi_hwmon_pdriver.driver);
5031 if (ret) {
5032 printk(IBM_ERR "unable to create sysfs driver attributes\n");
5033 thinkpad_acpi_module_exit();
5034 return ret;
5036 tp_features.sensors_pdrv_attrs_registered = 1;
5039 /* Device initialization */
5040 tpacpi_pdev = platform_device_register_simple(IBM_DRVR_NAME, -1,
5041 NULL, 0);
5042 if (IS_ERR(tpacpi_pdev)) {
5043 ret = PTR_ERR(tpacpi_pdev);
5044 tpacpi_pdev = NULL;
5045 printk(IBM_ERR "unable to register platform device\n");
5046 thinkpad_acpi_module_exit();
5047 return ret;
5049 tpacpi_sensors_pdev = platform_device_register_simple(
5050 IBM_HWMON_DRVR_NAME,
5051 -1, NULL, 0);
5052 if (IS_ERR(tpacpi_sensors_pdev)) {
5053 ret = PTR_ERR(tpacpi_sensors_pdev);
5054 tpacpi_sensors_pdev = NULL;
5055 printk(IBM_ERR "unable to register hwmon platform device\n");
5056 thinkpad_acpi_module_exit();
5057 return ret;
5059 ret = device_create_file(&tpacpi_sensors_pdev->dev,
5060 &dev_attr_thinkpad_acpi_pdev_name);
5061 if (ret) {
5062 printk(IBM_ERR
5063 "unable to create sysfs hwmon device attributes\n");
5064 thinkpad_acpi_module_exit();
5065 return ret;
5067 tp_features.sensors_pdev_attrs_registered = 1;
5068 tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev);
5069 if (IS_ERR(tpacpi_hwmon)) {
5070 ret = PTR_ERR(tpacpi_hwmon);
5071 tpacpi_hwmon = NULL;
5072 printk(IBM_ERR "unable to register hwmon device\n");
5073 thinkpad_acpi_module_exit();
5074 return ret;
5076 mutex_init(&tpacpi_inputdev_send_mutex);
5077 tpacpi_inputdev = input_allocate_device();
5078 if (!tpacpi_inputdev) {
5079 printk(IBM_ERR "unable to allocate input device\n");
5080 thinkpad_acpi_module_exit();
5081 return -ENOMEM;
5082 } else {
5083 /* Prepare input device, but don't register */
5084 tpacpi_inputdev->name = "ThinkPad Extra Buttons";
5085 tpacpi_inputdev->phys = IBM_DRVR_NAME "/input0";
5086 tpacpi_inputdev->id.bustype = BUS_HOST;
5087 tpacpi_inputdev->id.vendor = (thinkpad_id.vendor) ?
5088 thinkpad_id.vendor :
5089 PCI_VENDOR_ID_IBM;
5090 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
5091 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
5093 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
5094 ret = ibm_init(&ibms_init[i]);
5095 if (ret >= 0 && *ibms_init[i].param)
5096 ret = ibms_init[i].data->write(ibms_init[i].param);
5097 if (ret < 0) {
5098 thinkpad_acpi_module_exit();
5099 return ret;
5102 ret = input_register_device(tpacpi_inputdev);
5103 if (ret < 0) {
5104 printk(IBM_ERR "unable to register input device\n");
5105 thinkpad_acpi_module_exit();
5106 return ret;
5107 } else {
5108 tp_features.input_device_registered = 1;
5111 tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
5112 return 0;
5115 static void thinkpad_acpi_module_exit(void)
5117 struct ibm_struct *ibm, *itmp;
5119 tpacpi_lifecycle = TPACPI_LIFE_EXITING;
5121 list_for_each_entry_safe_reverse(ibm, itmp,
5122 &tpacpi_all_drivers,
5123 all_drivers) {
5124 ibm_exit(ibm);
5127 dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
5129 if (tpacpi_inputdev) {
5130 if (tp_features.input_device_registered)
5131 input_unregister_device(tpacpi_inputdev);
5132 else
5133 input_free_device(tpacpi_inputdev);
5136 if (tpacpi_hwmon)
5137 hwmon_device_unregister(tpacpi_hwmon);
5139 if (tp_features.sensors_pdev_attrs_registered)
5140 device_remove_file(&tpacpi_sensors_pdev->dev,
5141 &dev_attr_thinkpad_acpi_pdev_name);
5142 if (tpacpi_sensors_pdev)
5143 platform_device_unregister(tpacpi_sensors_pdev);
5144 if (tpacpi_pdev)
5145 platform_device_unregister(tpacpi_pdev);
5147 if (tp_features.sensors_pdrv_attrs_registered)
5148 tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver);
5149 if (tp_features.platform_drv_attrs_registered)
5150 tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
5152 if (tp_features.sensors_pdrv_registered)
5153 platform_driver_unregister(&tpacpi_hwmon_pdriver);
5155 if (tp_features.platform_drv_registered)
5156 platform_driver_unregister(&tpacpi_pdriver);
5158 if (proc_dir)
5159 remove_proc_entry(IBM_PROC_DIR, acpi_root_dir);
5161 kfree(thinkpad_id.bios_version_str);
5162 kfree(thinkpad_id.ec_version_str);
5163 kfree(thinkpad_id.model_str);
5166 module_init(thinkpad_acpi_module_init);
5167 module_exit(thinkpad_acpi_module_exit);