1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
26#define TPACPI_VERSION "0.25"
27#define TPACPI_SYSFS_VERSION 0x020700
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52#include <linux/kernel.h>
53#include <linux/module.h>
54#include <linux/init.h>
55#include <linux/types.h>
56#include <linux/string.h>
57#include <linux/list.h>
58#include <linux/mutex.h>
59#include <linux/sched.h>
60#include <linux/kthread.h>
61#include <linux/freezer.h>
62#include <linux/delay.h>
63#include <linux/slab.h>
64
65#include <linux/nvram.h>
66#include <linux/proc_fs.h>
67#include <linux/seq_file.h>
68#include <linux/sysfs.h>
69#include <linux/backlight.h>
70#include <linux/fb.h>
71#include <linux/platform_device.h>
72#include <linux/hwmon.h>
73#include <linux/hwmon-sysfs.h>
74#include <linux/input.h>
75#include <linux/leds.h>
76#include <linux/rfkill.h>
77#include <asm/uaccess.h>
78
79#include <linux/dmi.h>
80#include <linux/jiffies.h>
81#include <linux/workqueue.h>
82
83#include <sound/core.h>
84#include <sound/control.h>
85#include <sound/initval.h>
86
87#include <acpi/acpi_drivers.h>
88
89#include <linux/pci_ids.h>
90
91#include <linux/thinkpad_acpi.h>
92
93
94#define TP_CMOS_VOLUME_DOWN 0
95#define TP_CMOS_VOLUME_UP 1
96#define TP_CMOS_VOLUME_MUTE 2
97#define TP_CMOS_BRIGHTNESS_UP 4
98#define TP_CMOS_BRIGHTNESS_DOWN 5
99#define TP_CMOS_THINKLIGHT_ON 12
100#define TP_CMOS_THINKLIGHT_OFF 13
101
102
103enum tp_nvram_addr {
104 TP_NVRAM_ADDR_HK2 = 0x57,
105 TP_NVRAM_ADDR_THINKLIGHT = 0x58,
106 TP_NVRAM_ADDR_VIDEO = 0x59,
107 TP_NVRAM_ADDR_BRIGHTNESS = 0x5e,
108 TP_NVRAM_ADDR_MIXER = 0x60,
109};
110
111
112enum {
113 TP_NVRAM_MASK_HKT_THINKPAD = 0x08,
114 TP_NVRAM_MASK_HKT_ZOOM = 0x20,
115 TP_NVRAM_MASK_HKT_DISPLAY = 0x40,
116 TP_NVRAM_MASK_HKT_HIBERNATE = 0x80,
117 TP_NVRAM_MASK_THINKLIGHT = 0x10,
118 TP_NVRAM_MASK_HKT_DISPEXPND = 0x30,
119 TP_NVRAM_MASK_HKT_BRIGHTNESS = 0x20,
120 TP_NVRAM_MASK_LEVEL_BRIGHTNESS = 0x0f,
121 TP_NVRAM_POS_LEVEL_BRIGHTNESS = 0,
122 TP_NVRAM_MASK_MUTE = 0x40,
123 TP_NVRAM_MASK_HKT_VOLUME = 0x80,
124 TP_NVRAM_MASK_LEVEL_VOLUME = 0x0f,
125 TP_NVRAM_POS_LEVEL_VOLUME = 0,
126};
127
128
129enum {
130 TP_NVRAM_LEVEL_VOLUME_MAX = 14,
131};
132
133
134#define TPACPI_ACPI_IBM_HKEY_HID "IBM0068"
135#define TPACPI_ACPI_LENOVO_HKEY_HID "LEN0068"
136#define TPACPI_ACPI_EC_HID "PNP0C09"
137
138
139#define TPACPI_HKEY_INPUT_PRODUCT 0x5054
140#define TPACPI_HKEY_INPUT_VERSION 0x4101
141
142
143enum {
144 TP_ACPI_WGSV_GET_STATE = 0x01,
145 TP_ACPI_WGSV_PWR_ON_ON_RESUME = 0x02,
146 TP_ACPI_WGSV_PWR_OFF_ON_RESUME = 0x03,
147 TP_ACPI_WGSV_SAVE_STATE = 0x04,
148};
149
150
151enum {
152 TP_ACPI_WGSV_STATE_WWANEXIST = 0x0001,
153 TP_ACPI_WGSV_STATE_WWANPWR = 0x0002,
154 TP_ACPI_WGSV_STATE_WWANPWRRES = 0x0004,
155 TP_ACPI_WGSV_STATE_WWANBIOSOFF = 0x0008,
156 TP_ACPI_WGSV_STATE_BLTHEXIST = 0x0001,
157 TP_ACPI_WGSV_STATE_BLTHPWR = 0x0002,
158 TP_ACPI_WGSV_STATE_BLTHPWRRES = 0x0004,
159 TP_ACPI_WGSV_STATE_BLTHBIOSOFF = 0x0008,
160 TP_ACPI_WGSV_STATE_UWBEXIST = 0x0010,
161 TP_ACPI_WGSV_STATE_UWBPWR = 0x0020,
162};
163
164
165enum tpacpi_hkey_event_t {
166
167 TP_HKEY_EV_HOTKEY_BASE = 0x1001,
168 TP_HKEY_EV_BRGHT_UP = 0x1010,
169 TP_HKEY_EV_BRGHT_DOWN = 0x1011,
170 TP_HKEY_EV_VOL_UP = 0x1015,
171 TP_HKEY_EV_VOL_DOWN = 0x1016,
172 TP_HKEY_EV_VOL_MUTE = 0x1017,
173
174
175 TP_HKEY_EV_WKUP_S3_UNDOCK = 0x2304,
176 TP_HKEY_EV_WKUP_S4_UNDOCK = 0x2404,
177 TP_HKEY_EV_WKUP_S3_BAYEJ = 0x2305,
178 TP_HKEY_EV_WKUP_S4_BAYEJ = 0x2405,
179 TP_HKEY_EV_WKUP_S3_BATLOW = 0x2313,
180 TP_HKEY_EV_WKUP_S4_BATLOW = 0x2413,
181
182
183 TP_HKEY_EV_BAYEJ_ACK = 0x3003,
184 TP_HKEY_EV_UNDOCK_ACK = 0x4003,
185
186
187 TP_HKEY_EV_OPTDRV_EJ = 0x3006,
188 TP_HKEY_EV_HOTPLUG_DOCK = 0x4010,
189
190 TP_HKEY_EV_HOTPLUG_UNDOCK = 0x4011,
191
192
193
194 TP_HKEY_EV_LID_CLOSE = 0x5001,
195 TP_HKEY_EV_LID_OPEN = 0x5002,
196 TP_HKEY_EV_TABLET_TABLET = 0x5009,
197 TP_HKEY_EV_TABLET_NOTEBOOK = 0x500a,
198 TP_HKEY_EV_PEN_INSERTED = 0x500b,
199 TP_HKEY_EV_PEN_REMOVED = 0x500c,
200 TP_HKEY_EV_BRGHT_CHANGED = 0x5010,
201
202
203 TP_HKEY_EV_KEY_NUMLOCK = 0x6000,
204 TP_HKEY_EV_KEY_FN = 0x6005,
205
206
207 TP_HKEY_EV_ALARM_BAT_HOT = 0x6011,
208 TP_HKEY_EV_ALARM_BAT_XHOT = 0x6012,
209 TP_HKEY_EV_ALARM_SENSOR_HOT = 0x6021,
210 TP_HKEY_EV_ALARM_SENSOR_XHOT = 0x6022,
211 TP_HKEY_EV_THM_TABLE_CHANGED = 0x6030,
212
213
214 TP_HKEY_EV_AC_CHANGED = 0x6040,
215
216
217 TP_HKEY_EV_RFKILL_CHANGED = 0x7000,
218};
219
220
221
222
223
224#define TPACPI_NAME "thinkpad"
225#define TPACPI_DESC "ThinkPad ACPI Extras"
226#define TPACPI_FILE TPACPI_NAME "_acpi"
227#define TPACPI_URL "http://ibm-acpi.sf.net/"
228#define TPACPI_MAIL "ibm-acpi-devel@lists.sourceforge.net"
229
230#define TPACPI_PROC_DIR "ibm"
231#define TPACPI_ACPI_EVENT_PREFIX "ibm"
232#define TPACPI_DRVR_NAME TPACPI_FILE
233#define TPACPI_DRVR_SHORTNAME "tpacpi"
234#define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon"
235
236#define TPACPI_NVRAM_KTHREAD_NAME "ktpacpi_nvramd"
237#define TPACPI_WORKQUEUE_NAME "ktpacpid"
238
239#define TPACPI_MAX_ACPI_ARGS 3
240
241
242#define TPACPI_DBG_ALL 0xffff
243#define TPACPI_DBG_DISCLOSETASK 0x8000
244#define TPACPI_DBG_INIT 0x0001
245#define TPACPI_DBG_EXIT 0x0002
246#define TPACPI_DBG_RFKILL 0x0004
247#define TPACPI_DBG_HKEY 0x0008
248#define TPACPI_DBG_FAN 0x0010
249#define TPACPI_DBG_BRGHT 0x0020
250#define TPACPI_DBG_MIXER 0x0040
251
252#define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off")
253#define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
254#define strlencmp(a, b) (strncmp((a), (b), strlen(b)))
255
256
257
258
259
260
261struct ibm_struct;
262
263struct tp_acpi_drv_struct {
264 const struct acpi_device_id *hid;
265 struct acpi_driver *driver;
266
267 void (*notify) (struct ibm_struct *, u32);
268 acpi_handle *handle;
269 u32 type;
270 struct acpi_device *device;
271};
272
273struct ibm_struct {
274 char *name;
275
276 int (*read) (struct seq_file *);
277 int (*write) (char *);
278 void (*exit) (void);
279 void (*resume) (void);
280 void (*suspend) (void);
281 void (*shutdown) (void);
282
283 struct list_head all_drivers;
284
285 struct tp_acpi_drv_struct *acpi;
286
287 struct {
288 u8 acpi_driver_registered:1;
289 u8 acpi_notify_installed:1;
290 u8 proc_created:1;
291 u8 init_called:1;
292 u8 experimental:1;
293 } flags;
294};
295
296struct ibm_init_struct {
297 char param[32];
298
299 int (*init) (struct ibm_init_struct *);
300 umode_t base_procfs_mode;
301 struct ibm_struct *data;
302};
303
304static struct {
305 u32 bluetooth:1;
306 u32 hotkey:1;
307 u32 hotkey_mask:1;
308 u32 hotkey_wlsw:1;
309 u32 hotkey_tablet:1;
310 u32 light:1;
311 u32 light_status:1;
312 u32 bright_acpimode:1;
313 u32 bright_unkfw:1;
314 u32 wan:1;
315 u32 uwb:1;
316 u32 fan_ctrl_status_undef:1;
317 u32 second_fan:1;
318 u32 beep_needs_two_args:1;
319 u32 mixer_no_level_control:1;
320 u32 input_device_registered:1;
321 u32 platform_drv_registered:1;
322 u32 platform_drv_attrs_registered:1;
323 u32 sensors_pdrv_registered:1;
324 u32 sensors_pdrv_attrs_registered:1;
325 u32 sensors_pdev_attrs_registered:1;
326 u32 hotkey_poll_active:1;
327} tp_features;
328
329static struct {
330 u16 hotkey_mask_ff:1;
331 u16 volume_ctrl_forbidden:1;
332} tp_warned;
333
334struct thinkpad_id_data {
335 unsigned int vendor;
336
337
338 char *bios_version_str;
339 char *ec_version_str;
340
341 u16 bios_model;
342 u16 ec_model;
343 u16 bios_release;
344 u16 ec_release;
345
346 char *model_str;
347 char *nummodel_str;
348};
349static struct thinkpad_id_data thinkpad_id;
350
351static enum {
352 TPACPI_LIFE_INIT = 0,
353 TPACPI_LIFE_RUNNING,
354 TPACPI_LIFE_EXITING,
355} tpacpi_lifecycle;
356
357static int experimental;
358static u32 dbg_level;
359
360static struct workqueue_struct *tpacpi_wq;
361
362enum led_status_t {
363 TPACPI_LED_OFF = 0,
364 TPACPI_LED_ON,
365 TPACPI_LED_BLINK,
366};
367
368
369struct tpacpi_led_classdev {
370 struct led_classdev led_classdev;
371 struct work_struct work;
372 enum led_status_t new_state;
373 int led;
374};
375
376
377static unsigned int bright_maxlvl;
378
379#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
380static int dbg_wlswemul;
381static bool tpacpi_wlsw_emulstate;
382static int dbg_bluetoothemul;
383static bool tpacpi_bluetooth_emulstate;
384static int dbg_wwanemul;
385static bool tpacpi_wwan_emulstate;
386static int dbg_uwbemul;
387static bool tpacpi_uwb_emulstate;
388#endif
389
390
391
392
393
394
395#define dbg_printk(a_dbg_level, format, arg...) \
396do { \
397 if (dbg_level & (a_dbg_level)) \
398 printk(KERN_DEBUG pr_fmt("%s: " format), \
399 __func__, ##arg); \
400} while (0)
401
402#ifdef CONFIG_THINKPAD_ACPI_DEBUG
403#define vdbg_printk dbg_printk
404static const char *str_supported(int is_supported);
405#else
406static inline const char *str_supported(int is_supported) { return ""; }
407#define vdbg_printk(a_dbg_level, format, arg...) \
408 no_printk(format, ##arg)
409#endif
410
411static void tpacpi_log_usertask(const char * const what)
412{
413 printk(KERN_DEBUG pr_fmt("%s: access by process with PID %d\n"),
414 what, task_tgid_vnr(current));
415}
416
417#define tpacpi_disclose_usertask(what, format, arg...) \
418do { \
419 if (unlikely((dbg_level & TPACPI_DBG_DISCLOSETASK) && \
420 (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \
421 printk(KERN_DEBUG pr_fmt("%s: PID %d: " format), \
422 what, task_tgid_vnr(current), ## arg); \
423 } \
424} while (0)
425
426
427
428
429
430
431
432
433
434
435#define TPACPI_MATCH_ANY 0xffffU
436#define TPACPI_MATCH_UNKNOWN 0U
437
438
439#define TPID(__c1, __c2) (((__c2) << 8) | (__c1))
440
441#define TPACPI_Q_IBM(__id1, __id2, __quirk) \
442 { .vendor = PCI_VENDOR_ID_IBM, \
443 .bios = TPID(__id1, __id2), \
444 .ec = TPACPI_MATCH_ANY, \
445 .quirks = (__quirk) }
446
447#define TPACPI_Q_LNV(__id1, __id2, __quirk) \
448 { .vendor = PCI_VENDOR_ID_LENOVO, \
449 .bios = TPID(__id1, __id2), \
450 .ec = TPACPI_MATCH_ANY, \
451 .quirks = (__quirk) }
452
453#define TPACPI_QEC_LNV(__id1, __id2, __quirk) \
454 { .vendor = PCI_VENDOR_ID_LENOVO, \
455 .bios = TPACPI_MATCH_ANY, \
456 .ec = TPID(__id1, __id2), \
457 .quirks = (__quirk) }
458
459struct tpacpi_quirk {
460 unsigned int vendor;
461 u16 bios;
462 u16 ec;
463 unsigned long quirks;
464};
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479static unsigned long __init tpacpi_check_quirks(
480 const struct tpacpi_quirk *qlist,
481 unsigned int qlist_size)
482{
483 while (qlist_size) {
484 if ((qlist->vendor == thinkpad_id.vendor ||
485 qlist->vendor == TPACPI_MATCH_ANY) &&
486 (qlist->bios == thinkpad_id.bios_model ||
487 qlist->bios == TPACPI_MATCH_ANY) &&
488 (qlist->ec == thinkpad_id.ec_model ||
489 qlist->ec == TPACPI_MATCH_ANY))
490 return qlist->quirks;
491
492 qlist_size--;
493 qlist++;
494 }
495 return 0;
496}
497
498static inline bool __pure __init tpacpi_is_lenovo(void)
499{
500 return thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO;
501}
502
503static inline bool __pure __init tpacpi_is_ibm(void)
504{
505 return thinkpad_id.vendor == PCI_VENDOR_ID_IBM;
506}
507
508
509
510
511
512
513
514
515
516
517
518
519
520static acpi_handle root_handle;
521static acpi_handle ec_handle;
522
523#define TPACPI_HANDLE(object, parent, paths...) \
524 static acpi_handle object##_handle; \
525 static const acpi_handle * const object##_parent __initconst = \
526 &parent##_handle; \
527 static char *object##_paths[] __initdata = { paths }
528
529TPACPI_HANDLE(ecrd, ec, "ECRD");
530TPACPI_HANDLE(ecwr, ec, "ECWR");
531
532TPACPI_HANDLE(cmos, root, "\\UCMS",
533
534 "\\CMOS",
535 "\\CMS",
536 );
537
538TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY",
539 "^HKEY",
540 "HKEY",
541 );
542
543
544
545
546
547static int acpi_evalf(acpi_handle handle,
548 int *res, char *method, char *fmt, ...)
549{
550 char *fmt0 = fmt;
551 struct acpi_object_list params;
552 union acpi_object in_objs[TPACPI_MAX_ACPI_ARGS];
553 struct acpi_buffer result, *resultp;
554 union acpi_object out_obj;
555 acpi_status status;
556 va_list ap;
557 char res_type;
558 int success;
559 int quiet;
560
561 if (!*fmt) {
562 pr_err("acpi_evalf() called with empty format\n");
563 return 0;
564 }
565
566 if (*fmt == 'q') {
567 quiet = 1;
568 fmt++;
569 } else
570 quiet = 0;
571
572 res_type = *(fmt++);
573
574 params.count = 0;
575 params.pointer = &in_objs[0];
576
577 va_start(ap, fmt);
578 while (*fmt) {
579 char c = *(fmt++);
580 switch (c) {
581 case 'd':
582 in_objs[params.count].integer.value = va_arg(ap, int);
583 in_objs[params.count++].type = ACPI_TYPE_INTEGER;
584 break;
585
586 default:
587 pr_err("acpi_evalf() called "
588 "with invalid format character '%c'\n", c);
589 va_end(ap);
590 return 0;
591 }
592 }
593 va_end(ap);
594
595 if (res_type != 'v') {
596 result.length = sizeof(out_obj);
597 result.pointer = &out_obj;
598 resultp = &result;
599 } else
600 resultp = NULL;
601
602 status = acpi_evaluate_object(handle, method, ¶ms, resultp);
603
604 switch (res_type) {
605 case 'd':
606 success = (status == AE_OK &&
607 out_obj.type == ACPI_TYPE_INTEGER);
608 if (success && res)
609 *res = out_obj.integer.value;
610 break;
611 case 'v':
612 success = status == AE_OK;
613 break;
614
615 default:
616 pr_err("acpi_evalf() called "
617 "with invalid format character '%c'\n", res_type);
618 return 0;
619 }
620
621 if (!success && !quiet)
622 pr_err("acpi_evalf(%s, %s, ...) failed: %s\n",
623 method, fmt0, acpi_format_exception(status));
624
625 return success;
626}
627
628static int acpi_ec_read(int i, u8 *p)
629{
630 int v;
631
632 if (ecrd_handle) {
633 if (!acpi_evalf(ecrd_handle, &v, NULL, "dd", i))
634 return 0;
635 *p = v;
636 } else {
637 if (ec_read(i, p) < 0)
638 return 0;
639 }
640
641 return 1;
642}
643
644static int acpi_ec_write(int i, u8 v)
645{
646 if (ecwr_handle) {
647 if (!acpi_evalf(ecwr_handle, NULL, NULL, "vdd", i, v))
648 return 0;
649 } else {
650 if (ec_write(i, v) < 0)
651 return 0;
652 }
653
654 return 1;
655}
656
657static int issue_thinkpad_cmos_command(int cmos_cmd)
658{
659 if (!cmos_handle)
660 return -ENXIO;
661
662 if (!acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd))
663 return -EIO;
664
665 return 0;
666}
667
668
669
670
671
672#define TPACPI_ACPIHANDLE_INIT(object) \
673 drv_acpi_handle_init(#object, &object##_handle, *object##_parent, \
674 object##_paths, ARRAY_SIZE(object##_paths))
675
676static void __init drv_acpi_handle_init(const char *name,
677 acpi_handle *handle, const acpi_handle parent,
678 char **paths, const int num_paths)
679{
680 int i;
681 acpi_status status;
682
683 vdbg_printk(TPACPI_DBG_INIT, "trying to locate ACPI handle for %s\n",
684 name);
685
686 for (i = 0; i < num_paths; i++) {
687 status = acpi_get_handle(parent, paths[i], handle);
688 if (ACPI_SUCCESS(status)) {
689 dbg_printk(TPACPI_DBG_INIT,
690 "Found ACPI handle %s for %s\n",
691 paths[i], name);
692 return;
693 }
694 }
695
696 vdbg_printk(TPACPI_DBG_INIT, "ACPI handle for %s not found\n",
697 name);
698 *handle = NULL;
699}
700
701static acpi_status __init tpacpi_acpi_handle_locate_callback(acpi_handle handle,
702 u32 level, void *context, void **return_value)
703{
704 struct acpi_device *dev;
705 if (!strcmp(context, "video")) {
706 if (acpi_bus_get_device(handle, &dev))
707 return AE_OK;
708 if (strcmp(ACPI_VIDEO_HID, acpi_device_hid(dev)))
709 return AE_OK;
710 }
711
712 *(acpi_handle *)return_value = handle;
713
714 return AE_CTRL_TERMINATE;
715}
716
717static void __init tpacpi_acpi_handle_locate(const char *name,
718 const char *hid,
719 acpi_handle *handle)
720{
721 acpi_status status;
722 acpi_handle device_found;
723
724 BUG_ON(!name || !handle);
725 vdbg_printk(TPACPI_DBG_INIT,
726 "trying to locate ACPI handle for %s, using HID %s\n",
727 name, hid ? hid : "NULL");
728
729 memset(&device_found, 0, sizeof(device_found));
730 status = acpi_get_devices(hid, tpacpi_acpi_handle_locate_callback,
731 (void *)name, &device_found);
732
733 *handle = NULL;
734
735 if (ACPI_SUCCESS(status)) {
736 *handle = device_found;
737 dbg_printk(TPACPI_DBG_INIT,
738 "Found ACPI handle for %s\n", name);
739 } else {
740 vdbg_printk(TPACPI_DBG_INIT,
741 "Could not locate an ACPI handle for %s: %s\n",
742 name, acpi_format_exception(status));
743 }
744}
745
746static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data)
747{
748 struct ibm_struct *ibm = data;
749
750 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
751 return;
752
753 if (!ibm || !ibm->acpi || !ibm->acpi->notify)
754 return;
755
756 ibm->acpi->notify(ibm, event);
757}
758
759static int __init setup_acpi_notify(struct ibm_struct *ibm)
760{
761 acpi_status status;
762 int rc;
763
764 BUG_ON(!ibm->acpi);
765
766 if (!*ibm->acpi->handle)
767 return 0;
768
769 vdbg_printk(TPACPI_DBG_INIT,
770 "setting up ACPI notify for %s\n", ibm->name);
771
772 rc = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device);
773 if (rc < 0) {
774 pr_err("acpi_bus_get_device(%s) failed: %d\n", ibm->name, rc);
775 return -ENODEV;
776 }
777
778 ibm->acpi->device->driver_data = ibm;
779 sprintf(acpi_device_class(ibm->acpi->device), "%s/%s",
780 TPACPI_ACPI_EVENT_PREFIX,
781 ibm->name);
782
783 status = acpi_install_notify_handler(*ibm->acpi->handle,
784 ibm->acpi->type, dispatch_acpi_notify, ibm);
785 if (ACPI_FAILURE(status)) {
786 if (status == AE_ALREADY_EXISTS) {
787 pr_notice("another device driver is already "
788 "handling %s events\n", ibm->name);
789 } else {
790 pr_err("acpi_install_notify_handler(%s) failed: %s\n",
791 ibm->name, acpi_format_exception(status));
792 }
793 return -ENODEV;
794 }
795 ibm->flags.acpi_notify_installed = 1;
796 return 0;
797}
798
799static int __init tpacpi_device_add(struct acpi_device *device)
800{
801 return 0;
802}
803
804static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
805{
806 int rc;
807
808 dbg_printk(TPACPI_DBG_INIT,
809 "registering %s as an ACPI driver\n", ibm->name);
810
811 BUG_ON(!ibm->acpi);
812
813 ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
814 if (!ibm->acpi->driver) {
815 pr_err("failed to allocate memory for ibm->acpi->driver\n");
816 return -ENOMEM;
817 }
818
819 sprintf(ibm->acpi->driver->name, "%s_%s", TPACPI_NAME, ibm->name);
820 ibm->acpi->driver->ids = ibm->acpi->hid;
821
822 ibm->acpi->driver->ops.add = &tpacpi_device_add;
823
824 rc = acpi_bus_register_driver(ibm->acpi->driver);
825 if (rc < 0) {
826 pr_err("acpi_bus_register_driver(%s) failed: %d\n",
827 ibm->name, rc);
828 kfree(ibm->acpi->driver);
829 ibm->acpi->driver = NULL;
830 } else if (!rc)
831 ibm->flags.acpi_driver_registered = 1;
832
833 return rc;
834}
835
836
837
838
839
840
841
842
843
844
845static int dispatch_proc_show(struct seq_file *m, void *v)
846{
847 struct ibm_struct *ibm = m->private;
848
849 if (!ibm || !ibm->read)
850 return -EINVAL;
851 return ibm->read(m);
852}
853
854static int dispatch_proc_open(struct inode *inode, struct file *file)
855{
856 return single_open(file, dispatch_proc_show, PDE_DATA(inode));
857}
858
859static ssize_t dispatch_proc_write(struct file *file,
860 const char __user *userbuf,
861 size_t count, loff_t *pos)
862{
863 struct ibm_struct *ibm = PDE_DATA(file_inode(file));
864 char *kernbuf;
865 int ret;
866
867 if (!ibm || !ibm->write)
868 return -EINVAL;
869 if (count > PAGE_SIZE - 2)
870 return -EINVAL;
871
872 kernbuf = kmalloc(count + 2, GFP_KERNEL);
873 if (!kernbuf)
874 return -ENOMEM;
875
876 if (copy_from_user(kernbuf, userbuf, count)) {
877 kfree(kernbuf);
878 return -EFAULT;
879 }
880
881 kernbuf[count] = 0;
882 strcat(kernbuf, ",");
883 ret = ibm->write(kernbuf);
884 if (ret == 0)
885 ret = count;
886
887 kfree(kernbuf);
888
889 return ret;
890}
891
892static const struct file_operations dispatch_proc_fops = {
893 .owner = THIS_MODULE,
894 .open = dispatch_proc_open,
895 .read = seq_read,
896 .llseek = seq_lseek,
897 .release = single_release,
898 .write = dispatch_proc_write,
899};
900
901static char *next_cmd(char **cmds)
902{
903 char *start = *cmds;
904 char *end;
905
906 while ((end = strchr(start, ',')) && end == start)
907 start = end + 1;
908
909 if (!end)
910 return NULL;
911
912 *end = 0;
913 *cmds = end + 1;
914 return start;
915}
916
917
918
919
920
921
922
923
924
925
926static struct platform_device *tpacpi_pdev;
927static struct platform_device *tpacpi_sensors_pdev;
928static struct device *tpacpi_hwmon;
929static struct input_dev *tpacpi_inputdev;
930static struct mutex tpacpi_inputdev_send_mutex;
931static LIST_HEAD(tpacpi_all_drivers);
932
933#ifdef CONFIG_PM_SLEEP
934static int tpacpi_suspend_handler(struct device *dev)
935{
936 struct ibm_struct *ibm, *itmp;
937
938 list_for_each_entry_safe(ibm, itmp,
939 &tpacpi_all_drivers,
940 all_drivers) {
941 if (ibm->suspend)
942 (ibm->suspend)();
943 }
944
945 return 0;
946}
947
948static int tpacpi_resume_handler(struct device *dev)
949{
950 struct ibm_struct *ibm, *itmp;
951
952 list_for_each_entry_safe(ibm, itmp,
953 &tpacpi_all_drivers,
954 all_drivers) {
955 if (ibm->resume)
956 (ibm->resume)();
957 }
958
959 return 0;
960}
961#endif
962
963static SIMPLE_DEV_PM_OPS(tpacpi_pm,
964 tpacpi_suspend_handler, tpacpi_resume_handler);
965
966static void tpacpi_shutdown_handler(struct platform_device *pdev)
967{
968 struct ibm_struct *ibm, *itmp;
969
970 list_for_each_entry_safe(ibm, itmp,
971 &tpacpi_all_drivers,
972 all_drivers) {
973 if (ibm->shutdown)
974 (ibm->shutdown)();
975 }
976}
977
978static struct platform_driver tpacpi_pdriver = {
979 .driver = {
980 .name = TPACPI_DRVR_NAME,
981 .owner = THIS_MODULE,
982 .pm = &tpacpi_pm,
983 },
984 .shutdown = tpacpi_shutdown_handler,
985};
986
987static struct platform_driver tpacpi_hwmon_pdriver = {
988 .driver = {
989 .name = TPACPI_HWMON_DRVR_NAME,
990 .owner = THIS_MODULE,
991 },
992};
993
994
995
996
997
998struct attribute_set {
999 unsigned int members, max_members;
1000 struct attribute_group group;
1001};
1002
1003struct attribute_set_obj {
1004 struct attribute_set s;
1005 struct attribute *a;
1006} __attribute__((packed));
1007
1008static struct attribute_set *create_attr_set(unsigned int max_members,
1009 const char *name)
1010{
1011 struct attribute_set_obj *sobj;
1012
1013 if (max_members == 0)
1014 return NULL;
1015
1016
1017 sobj = kzalloc(sizeof(struct attribute_set_obj) +
1018 max_members * sizeof(struct attribute *),
1019 GFP_KERNEL);
1020 if (!sobj)
1021 return NULL;
1022 sobj->s.max_members = max_members;
1023 sobj->s.group.attrs = &sobj->a;
1024 sobj->s.group.name = name;
1025
1026 return &sobj->s;
1027}
1028
1029#define destroy_attr_set(_set) \
1030 kfree(_set);
1031
1032
1033static int add_to_attr_set(struct attribute_set *s, struct attribute *attr)
1034{
1035 if (!s || !attr)
1036 return -EINVAL;
1037
1038 if (s->members >= s->max_members)
1039 return -ENOMEM;
1040
1041 s->group.attrs[s->members] = attr;
1042 s->members++;
1043
1044 return 0;
1045}
1046
1047static int add_many_to_attr_set(struct attribute_set *s,
1048 struct attribute **attr,
1049 unsigned int count)
1050{
1051 int i, res;
1052
1053 for (i = 0; i < count; i++) {
1054 res = add_to_attr_set(s, attr[i]);
1055 if (res)
1056 return res;
1057 }
1058
1059 return 0;
1060}
1061
1062static void delete_attr_set(struct attribute_set *s, struct kobject *kobj)
1063{
1064 sysfs_remove_group(kobj, &s->group);
1065 destroy_attr_set(s);
1066}
1067
1068#define register_attr_set_with_sysfs(_attr_set, _kobj) \
1069 sysfs_create_group(_kobj, &_attr_set->group)
1070
1071static int parse_strtoul(const char *buf,
1072 unsigned long max, unsigned long *value)
1073{
1074 char *endp;
1075
1076 *value = simple_strtoul(skip_spaces(buf), &endp, 0);
1077 endp = skip_spaces(endp);
1078 if (*endp || *value > max)
1079 return -EINVAL;
1080
1081 return 0;
1082}
1083
1084static void tpacpi_disable_brightness_delay(void)
1085{
1086 if (acpi_evalf(hkey_handle, NULL, "PWMS", "qvd", 0))
1087 pr_notice("ACPI backlight control delay disabled\n");
1088}
1089
1090static void printk_deprecated_attribute(const char * const what,
1091 const char * const details)
1092{
1093 tpacpi_log_usertask("deprecated sysfs attribute");
1094 pr_warn("WARNING: sysfs attribute %s is deprecated and "
1095 "will be removed. %s\n",
1096 what, details);
1097}
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123enum tpacpi_rfkill_state {
1124 TPACPI_RFK_RADIO_OFF = 0,
1125 TPACPI_RFK_RADIO_ON
1126};
1127
1128
1129enum tpacpi_rfk_id {
1130 TPACPI_RFK_BLUETOOTH_SW_ID = 0,
1131 TPACPI_RFK_WWAN_SW_ID,
1132 TPACPI_RFK_UWB_SW_ID,
1133 TPACPI_RFK_SW_MAX
1134};
1135
1136static const char *tpacpi_rfkill_names[] = {
1137 [TPACPI_RFK_BLUETOOTH_SW_ID] = "bluetooth",
1138 [TPACPI_RFK_WWAN_SW_ID] = "wwan",
1139 [TPACPI_RFK_UWB_SW_ID] = "uwb",
1140 [TPACPI_RFK_SW_MAX] = NULL
1141};
1142
1143
1144struct tpacpi_rfk {
1145 struct rfkill *rfkill;
1146 enum tpacpi_rfk_id id;
1147 const struct tpacpi_rfk_ops *ops;
1148};
1149
1150struct tpacpi_rfk_ops {
1151
1152 int (*get_status)(void);
1153 int (*set_status)(const enum tpacpi_rfkill_state);
1154};
1155
1156static struct tpacpi_rfk *tpacpi_rfkill_switches[TPACPI_RFK_SW_MAX];
1157
1158
1159static int tpacpi_rfk_update_swstate(const struct tpacpi_rfk *tp_rfk)
1160{
1161 int status;
1162
1163 if (!tp_rfk)
1164 return -ENODEV;
1165
1166 status = (tp_rfk->ops->get_status)();
1167 if (status < 0)
1168 return status;
1169
1170 rfkill_set_sw_state(tp_rfk->rfkill,
1171 (status == TPACPI_RFK_RADIO_OFF));
1172
1173 return status;
1174}
1175
1176
1177static void tpacpi_rfk_update_swstate_all(void)
1178{
1179 unsigned int i;
1180
1181 for (i = 0; i < TPACPI_RFK_SW_MAX; i++)
1182 tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[i]);
1183}
1184
1185
1186
1187
1188
1189static void tpacpi_rfk_update_hwblock_state(bool blocked)
1190{
1191 unsigned int i;
1192 struct tpacpi_rfk *tp_rfk;
1193
1194 for (i = 0; i < TPACPI_RFK_SW_MAX; i++) {
1195 tp_rfk = tpacpi_rfkill_switches[i];
1196 if (tp_rfk) {
1197 if (rfkill_set_hw_state(tp_rfk->rfkill,
1198 blocked)) {
1199
1200 }
1201 }
1202 }
1203}
1204
1205
1206static int hotkey_get_wlsw(void);
1207
1208
1209static bool tpacpi_rfk_check_hwblock_state(void)
1210{
1211 int res = hotkey_get_wlsw();
1212 int hw_blocked;
1213
1214
1215 if (res < 0)
1216 return false;
1217
1218 hw_blocked = (res == TPACPI_RFK_RADIO_OFF);
1219 tpacpi_rfk_update_hwblock_state(hw_blocked);
1220
1221 return hw_blocked;
1222}
1223
1224static int tpacpi_rfk_hook_set_block(void *data, bool blocked)
1225{
1226 struct tpacpi_rfk *tp_rfk = data;
1227 int res;
1228
1229 dbg_printk(TPACPI_DBG_RFKILL,
1230 "request to change radio state to %s\n",
1231 blocked ? "blocked" : "unblocked");
1232
1233
1234 res = (tp_rfk->ops->set_status)(blocked ?
1235 TPACPI_RFK_RADIO_OFF : TPACPI_RFK_RADIO_ON);
1236
1237
1238 tpacpi_rfk_update_swstate(tp_rfk);
1239
1240 return (res < 0) ? res : 0;
1241}
1242
1243static const struct rfkill_ops tpacpi_rfk_rfkill_ops = {
1244 .set_block = tpacpi_rfk_hook_set_block,
1245};
1246
1247static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,
1248 const struct tpacpi_rfk_ops *tp_rfkops,
1249 const enum rfkill_type rfktype,
1250 const char *name,
1251 const bool set_default)
1252{
1253 struct tpacpi_rfk *atp_rfk;
1254 int res;
1255 bool sw_state = false;
1256 bool hw_state;
1257 int sw_status;
1258
1259 BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]);
1260
1261 atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL);
1262 if (atp_rfk)
1263 atp_rfk->rfkill = rfkill_alloc(name,
1264 &tpacpi_pdev->dev,
1265 rfktype,
1266 &tpacpi_rfk_rfkill_ops,
1267 atp_rfk);
1268 if (!atp_rfk || !atp_rfk->rfkill) {
1269 pr_err("failed to allocate memory for rfkill class\n");
1270 kfree(atp_rfk);
1271 return -ENOMEM;
1272 }
1273
1274 atp_rfk->id = id;
1275 atp_rfk->ops = tp_rfkops;
1276
1277 sw_status = (tp_rfkops->get_status)();
1278 if (sw_status < 0) {
1279 pr_err("failed to read initial state for %s, error %d\n",
1280 name, sw_status);
1281 } else {
1282 sw_state = (sw_status == TPACPI_RFK_RADIO_OFF);
1283 if (set_default) {
1284
1285
1286 rfkill_init_sw_state(atp_rfk->rfkill, sw_state);
1287 }
1288 }
1289 hw_state = tpacpi_rfk_check_hwblock_state();
1290 rfkill_set_hw_state(atp_rfk->rfkill, hw_state);
1291
1292 res = rfkill_register(atp_rfk->rfkill);
1293 if (res < 0) {
1294 pr_err("failed to register %s rfkill switch: %d\n", name, res);
1295 rfkill_destroy(atp_rfk->rfkill);
1296 kfree(atp_rfk);
1297 return res;
1298 }
1299
1300 tpacpi_rfkill_switches[id] = atp_rfk;
1301
1302 pr_info("rfkill switch %s: radio is %sblocked\n",
1303 name, (sw_state || hw_state) ? "" : "un");
1304 return 0;
1305}
1306
1307static void tpacpi_destroy_rfkill(const enum tpacpi_rfk_id id)
1308{
1309 struct tpacpi_rfk *tp_rfk;
1310
1311 BUG_ON(id >= TPACPI_RFK_SW_MAX);
1312
1313 tp_rfk = tpacpi_rfkill_switches[id];
1314 if (tp_rfk) {
1315 rfkill_unregister(tp_rfk->rfkill);
1316 rfkill_destroy(tp_rfk->rfkill);
1317 tpacpi_rfkill_switches[id] = NULL;
1318 kfree(tp_rfk);
1319 }
1320}
1321
1322static void printk_deprecated_rfkill_attribute(const char * const what)
1323{
1324 printk_deprecated_attribute(what,
1325 "Please switch to generic rfkill before year 2010");
1326}
1327
1328
1329static ssize_t tpacpi_rfk_sysfs_enable_show(const enum tpacpi_rfk_id id,
1330 struct device_attribute *attr,
1331 char *buf)
1332{
1333 int status;
1334
1335 printk_deprecated_rfkill_attribute(attr->attr.name);
1336
1337
1338 if (tpacpi_rfk_check_hwblock_state()) {
1339 status = TPACPI_RFK_RADIO_OFF;
1340 } else {
1341 status = tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
1342 if (status < 0)
1343 return status;
1344 }
1345
1346 return snprintf(buf, PAGE_SIZE, "%d\n",
1347 (status == TPACPI_RFK_RADIO_ON) ? 1 : 0);
1348}
1349
1350static ssize_t tpacpi_rfk_sysfs_enable_store(const enum tpacpi_rfk_id id,
1351 struct device_attribute *attr,
1352 const char *buf, size_t count)
1353{
1354 unsigned long t;
1355 int res;
1356
1357 printk_deprecated_rfkill_attribute(attr->attr.name);
1358
1359 if (parse_strtoul(buf, 1, &t))
1360 return -EINVAL;
1361
1362 tpacpi_disclose_usertask(attr->attr.name, "set to %ld\n", t);
1363
1364
1365 if (tpacpi_rfk_check_hwblock_state() && !!t)
1366 return -EPERM;
1367
1368 res = tpacpi_rfkill_switches[id]->ops->set_status((!!t) ?
1369 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF);
1370 tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
1371
1372 return (res < 0) ? res : count;
1373}
1374
1375
1376static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, struct seq_file *m)
1377{
1378 if (id >= TPACPI_RFK_SW_MAX)
1379 seq_printf(m, "status:\t\tnot supported\n");
1380 else {
1381 int status;
1382
1383
1384 if (tpacpi_rfk_check_hwblock_state()) {
1385 status = TPACPI_RFK_RADIO_OFF;
1386 } else {
1387 status = tpacpi_rfk_update_swstate(
1388 tpacpi_rfkill_switches[id]);
1389 if (status < 0)
1390 return status;
1391 }
1392
1393 seq_printf(m, "status:\t\t%s\n",
1394 (status == TPACPI_RFK_RADIO_ON) ?
1395 "enabled" : "disabled");
1396 seq_printf(m, "commands:\tenable, disable\n");
1397 }
1398
1399 return 0;
1400}
1401
1402static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf)
1403{
1404 char *cmd;
1405 int status = -1;
1406 int res = 0;
1407
1408 if (id >= TPACPI_RFK_SW_MAX)
1409 return -ENODEV;
1410
1411 while ((cmd = next_cmd(&buf))) {
1412 if (strlencmp(cmd, "enable") == 0)
1413 status = TPACPI_RFK_RADIO_ON;
1414 else if (strlencmp(cmd, "disable") == 0)
1415 status = TPACPI_RFK_RADIO_OFF;
1416 else
1417 return -EINVAL;
1418 }
1419
1420 if (status != -1) {
1421 tpacpi_disclose_usertask("procfs", "attempt to %s %s\n",
1422 (status == TPACPI_RFK_RADIO_ON) ?
1423 "enable" : "disable",
1424 tpacpi_rfkill_names[id]);
1425 res = (tpacpi_rfkill_switches[id]->ops->set_status)(status);
1426 tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
1427 }
1428
1429 return res;
1430}
1431
1432
1433
1434
1435
1436
1437static ssize_t tpacpi_driver_interface_version_show(
1438 struct device_driver *drv,
1439 char *buf)
1440{
1441 return snprintf(buf, PAGE_SIZE, "0x%08x\n", TPACPI_SYSFS_VERSION);
1442}
1443
1444static DRIVER_ATTR(interface_version, S_IRUGO,
1445 tpacpi_driver_interface_version_show, NULL);
1446
1447
1448static ssize_t tpacpi_driver_debug_show(struct device_driver *drv,
1449 char *buf)
1450{
1451 return snprintf(buf, PAGE_SIZE, "0x%04x\n", dbg_level);
1452}
1453
1454static ssize_t tpacpi_driver_debug_store(struct device_driver *drv,
1455 const char *buf, size_t count)
1456{
1457 unsigned long t;
1458
1459 if (parse_strtoul(buf, 0xffff, &t))
1460 return -EINVAL;
1461
1462 dbg_level = t;
1463
1464 return count;
1465}
1466
1467static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
1468 tpacpi_driver_debug_show, tpacpi_driver_debug_store);
1469
1470
1471static ssize_t tpacpi_driver_version_show(struct device_driver *drv,
1472 char *buf)
1473{
1474 return snprintf(buf, PAGE_SIZE, "%s v%s\n",
1475 TPACPI_DESC, TPACPI_VERSION);
1476}
1477
1478static DRIVER_ATTR(version, S_IRUGO,
1479 tpacpi_driver_version_show, NULL);
1480
1481
1482
1483#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
1484
1485
1486static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv,
1487 char *buf)
1488{
1489 return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_wlsw_emulstate);
1490}
1491
1492static ssize_t tpacpi_driver_wlsw_emulstate_store(struct device_driver *drv,
1493 const char *buf, size_t count)
1494{
1495 unsigned long t;
1496
1497 if (parse_strtoul(buf, 1, &t))
1498 return -EINVAL;
1499
1500 if (tpacpi_wlsw_emulstate != !!t) {
1501 tpacpi_wlsw_emulstate = !!t;
1502 tpacpi_rfk_update_hwblock_state(!t);
1503 }
1504
1505 return count;
1506}
1507
1508static DRIVER_ATTR(wlsw_emulstate, S_IWUSR | S_IRUGO,
1509 tpacpi_driver_wlsw_emulstate_show,
1510 tpacpi_driver_wlsw_emulstate_store);
1511
1512
1513static ssize_t tpacpi_driver_bluetooth_emulstate_show(
1514 struct device_driver *drv,
1515 char *buf)
1516{
1517 return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_bluetooth_emulstate);
1518}
1519
1520static ssize_t tpacpi_driver_bluetooth_emulstate_store(
1521 struct device_driver *drv,
1522 const char *buf, size_t count)
1523{
1524 unsigned long t;
1525
1526 if (parse_strtoul(buf, 1, &t))
1527 return -EINVAL;
1528
1529 tpacpi_bluetooth_emulstate = !!t;
1530
1531 return count;
1532}
1533
1534static DRIVER_ATTR(bluetooth_emulstate, S_IWUSR | S_IRUGO,
1535 tpacpi_driver_bluetooth_emulstate_show,
1536 tpacpi_driver_bluetooth_emulstate_store);
1537
1538
1539static ssize_t tpacpi_driver_wwan_emulstate_show(
1540 struct device_driver *drv,
1541 char *buf)
1542{
1543 return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_wwan_emulstate);
1544}
1545
1546static ssize_t tpacpi_driver_wwan_emulstate_store(
1547 struct device_driver *drv,
1548 const char *buf, size_t count)
1549{
1550 unsigned long t;
1551
1552 if (parse_strtoul(buf, 1, &t))
1553 return -EINVAL;
1554
1555 tpacpi_wwan_emulstate = !!t;
1556
1557 return count;
1558}
1559
1560static DRIVER_ATTR(wwan_emulstate, S_IWUSR | S_IRUGO,
1561 tpacpi_driver_wwan_emulstate_show,
1562 tpacpi_driver_wwan_emulstate_store);
1563
1564
1565static ssize_t tpacpi_driver_uwb_emulstate_show(
1566 struct device_driver *drv,
1567 char *buf)
1568{
1569 return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_uwb_emulstate);
1570}
1571
1572static ssize_t tpacpi_driver_uwb_emulstate_store(
1573 struct device_driver *drv,
1574 const char *buf, size_t count)
1575{
1576 unsigned long t;
1577
1578 if (parse_strtoul(buf, 1, &t))
1579 return -EINVAL;
1580
1581 tpacpi_uwb_emulstate = !!t;
1582
1583 return count;
1584}
1585
1586static DRIVER_ATTR(uwb_emulstate, S_IWUSR | S_IRUGO,
1587 tpacpi_driver_uwb_emulstate_show,
1588 tpacpi_driver_uwb_emulstate_store);
1589#endif
1590
1591
1592
1593static struct driver_attribute *tpacpi_driver_attributes[] = {
1594 &driver_attr_debug_level, &driver_attr_version,
1595 &driver_attr_interface_version,
1596};
1597
1598static int __init tpacpi_create_driver_attributes(struct device_driver *drv)
1599{
1600 int i, res;
1601
1602 i = 0;
1603 res = 0;
1604 while (!res && i < ARRAY_SIZE(tpacpi_driver_attributes)) {
1605 res = driver_create_file(drv, tpacpi_driver_attributes[i]);
1606 i++;
1607 }
1608
1609#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
1610 if (!res && dbg_wlswemul)
1611 res = driver_create_file(drv, &driver_attr_wlsw_emulstate);
1612 if (!res && dbg_bluetoothemul)
1613 res = driver_create_file(drv, &driver_attr_bluetooth_emulstate);
1614 if (!res && dbg_wwanemul)
1615 res = driver_create_file(drv, &driver_attr_wwan_emulstate);
1616 if (!res && dbg_uwbemul)
1617 res = driver_create_file(drv, &driver_attr_uwb_emulstate);
1618#endif
1619
1620 return res;
1621}
1622
1623static void tpacpi_remove_driver_attributes(struct device_driver *drv)
1624{
1625 int i;
1626
1627 for (i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++)
1628 driver_remove_file(drv, tpacpi_driver_attributes[i]);
1629
1630#ifdef THINKPAD_ACPI_DEBUGFACILITIES
1631 driver_remove_file(drv, &driver_attr_wlsw_emulstate);
1632 driver_remove_file(drv, &driver_attr_bluetooth_emulstate);
1633 driver_remove_file(drv, &driver_attr_wwan_emulstate);
1634 driver_remove_file(drv, &driver_attr_uwb_emulstate);
1635#endif
1636}
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663#define TPV_Q(__v, __id1, __id2, __bv1, __bv2) \
1664 { .vendor = (__v), \
1665 .bios = TPID(__id1, __id2), \
1666 .ec = TPACPI_MATCH_ANY, \
1667 .quirks = TPACPI_MATCH_ANY << 16 \
1668 | (__bv1) << 8 | (__bv2) }
1669
1670#define TPV_Q_X(__v, __bid1, __bid2, __bv1, __bv2, \
1671 __eid, __ev1, __ev2) \
1672 { .vendor = (__v), \
1673 .bios = TPID(__bid1, __bid2), \
1674 .ec = __eid, \
1675 .quirks = (__ev1) << 24 | (__ev2) << 16 \
1676 | (__bv1) << 8 | (__bv2) }
1677
1678#define TPV_QI0(__id1, __id2, __bv1, __bv2) \
1679 TPV_Q(PCI_VENDOR_ID_IBM, __id1, __id2, __bv1, __bv2)
1680
1681
1682#define TPV_QI1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \
1683 TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2, \
1684 __bv1, __bv2, TPID(__id1, __id2), \
1685 __ev1, __ev2), \
1686 TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2, \
1687 __bv1, __bv2, TPACPI_MATCH_UNKNOWN, \
1688 __ev1, __ev2)
1689
1690
1691#define TPV_QI2(__bid1, __bid2, __bv1, __bv2, \
1692 __eid1, __eid2, __ev1, __ev2) \
1693 TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2, \
1694 __bv1, __bv2, TPID(__eid1, __eid2), \
1695 __ev1, __ev2), \
1696 TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2, \
1697 __bv1, __bv2, TPACPI_MATCH_UNKNOWN, \
1698 __ev1, __ev2)
1699
1700#define TPV_QL0(__id1, __id2, __bv1, __bv2) \
1701 TPV_Q(PCI_VENDOR_ID_LENOVO, __id1, __id2, __bv1, __bv2)
1702
1703#define TPV_QL1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \
1704 TPV_Q_X(PCI_VENDOR_ID_LENOVO, __id1, __id2, \
1705 __bv1, __bv2, TPID(__id1, __id2), \
1706 __ev1, __ev2)
1707
1708#define TPV_QL2(__bid1, __bid2, __bv1, __bv2, \
1709 __eid1, __eid2, __ev1, __ev2) \
1710 TPV_Q_X(PCI_VENDOR_ID_LENOVO, __bid1, __bid2, \
1711 __bv1, __bv2, TPID(__eid1, __eid2), \
1712 __ev1, __ev2)
1713
1714static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = {
1715
1716
1717 TPV_QI0('I', 'M', '6', '5'),
1718 TPV_QI0('I', 'U', '2', '6'),
1719 TPV_QI0('I', 'B', '5', '4'),
1720 TPV_QI0('I', 'H', '4', '7'),
1721 TPV_QI0('I', 'N', '3', '6'),
1722 TPV_QI0('I', 'T', '5', '5'),
1723 TPV_QI0('I', 'D', '4', '8'),
1724 TPV_QI0('I', 'I', '4', '2'),
1725 TPV_QI0('I', 'O', '2', '3'),
1726
1727
1728
1729 TPV_QI0('I', 'W', '5', '9'),
1730 TPV_QI0('I', 'V', '6', '9'),
1731 TPV_QI0('1', '0', '2', '6'),
1732 TPV_QI0('K', 'U', '3', '6'),
1733 TPV_QI0('K', 'X', '3', '6'),
1734 TPV_QI0('K', 'Y', '3', '8'),
1735 TPV_QI0('1', 'B', '1', '7'),
1736 TPV_QI0('1', '3', '2', '0'),
1737 TPV_QI0('1', 'E', '7', '3'),
1738 TPV_QI1('1', 'G', '4', '1', '1', '7'),
1739 TPV_QI1('1', 'N', '1', '6', '0', '7'),
1740
1741
1742
1743 TPV_QI0('1', 'T', 'A', '6'),
1744 TPV_QI0('1', 'X', '5', '7'),
1745
1746
1747
1748 TPV_QI0('1', 'C', 'F', '0'),
1749 TPV_QI0('1', 'F', 'F', '1'),
1750 TPV_QI0('1', 'M', '9', '7'),
1751 TPV_QI0('1', 'O', '6', '1'),
1752 TPV_QI0('1', 'P', '6', '5'),
1753 TPV_QI0('1', 'S', '7', '0'),
1754 TPV_QI1('1', 'R', 'D', 'R', '7', '1'),
1755
1756 TPV_QI1('1', 'V', '7', '1', '2', '8'),
1757 TPV_QI1('7', '8', '7', '1', '0', '6'),
1758 TPV_QI1('7', '6', '6', '9', '1', '6'),
1759 TPV_QI1('7', '0', '6', '9', '2', '8'),
1760
1761 TPV_QI0('I', 'Y', '6', '1'),
1762 TPV_QI0('K', 'Z', '3', '4'),
1763 TPV_QI0('1', '6', '3', '2'),
1764 TPV_QI1('1', 'A', '6', '4', '2', '3'),
1765 TPV_QI1('1', 'I', '7', '1', '2', '0'),
1766 TPV_QI1('1', 'Y', '6', '5', '2', '9'),
1767
1768 TPV_QL1('7', '9', 'E', '3', '5', '0'),
1769 TPV_QL1('7', 'C', 'D', '2', '2', '2'),
1770 TPV_QL1('7', 'E', 'D', '0', '1', '5'),
1771
1772
1773 TPV_QI2('1', 'W', '9', '0', '1', 'V', '2', '8'),
1774 TPV_QL2('7', 'I', '3', '4', '7', '9', '5', '0'),
1775
1776
1777
1778 TPV_QI0('I', 'Z', '9', 'D'),
1779 TPV_QI0('1', 'D', '7', '0'),
1780 TPV_QI1('1', 'K', '4', '8', '1', '8'),
1781 TPV_QI1('1', 'Q', '9', '7', '2', '3'),
1782 TPV_QI1('1', 'U', 'D', '3', 'B', '2'),
1783 TPV_QI1('7', '4', '6', '4', '2', '7'),
1784 TPV_QI1('7', '5', '6', '0', '2', '0'),
1785
1786 TPV_QL1('7', 'B', 'D', '7', '4', '0'),
1787 TPV_QL1('7', 'J', '3', '0', '1', '3'),
1788
1789
1790
1791};
1792
1793#undef TPV_QL1
1794#undef TPV_QL0
1795#undef TPV_QI2
1796#undef TPV_QI1
1797#undef TPV_QI0
1798#undef TPV_Q_X
1799#undef TPV_Q
1800
1801static void __init tpacpi_check_outdated_fw(void)
1802{
1803 unsigned long fwvers;
1804 u16 ec_version, bios_version;
1805
1806 fwvers = tpacpi_check_quirks(tpacpi_bios_version_qtable,
1807 ARRAY_SIZE(tpacpi_bios_version_qtable));
1808
1809 if (!fwvers)
1810 return;
1811
1812 bios_version = fwvers & 0xffffU;
1813 ec_version = (fwvers >> 16) & 0xffffU;
1814
1815
1816 if ((bios_version > thinkpad_id.bios_release) ||
1817 (ec_version > thinkpad_id.ec_release &&
1818 ec_version != TPACPI_MATCH_ANY)) {
1819
1820
1821
1822
1823
1824
1825
1826 pr_warn("WARNING: Outdated ThinkPad BIOS/EC firmware\n");
1827 pr_warn("WARNING: This firmware may be missing critical bug "
1828 "fixes and/or important features\n");
1829 }
1830}
1831
1832static bool __init tpacpi_is_fw_known(void)
1833{
1834 return tpacpi_check_quirks(tpacpi_bios_version_qtable,
1835 ARRAY_SIZE(tpacpi_bios_version_qtable)) != 0;
1836}
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850static int thinkpad_acpi_driver_read(struct seq_file *m)
1851{
1852 seq_printf(m, "driver:\t\t%s\n", TPACPI_DESC);
1853 seq_printf(m, "version:\t%s\n", TPACPI_VERSION);
1854 return 0;
1855}
1856
1857static struct ibm_struct thinkpad_acpi_driver_data = {
1858 .name = "driver",
1859 .read = thinkpad_acpi_driver_read,
1860};
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887enum {
1888 TP_ACPI_HOTKEYSCAN_FNF1 = 0,
1889 TP_ACPI_HOTKEYSCAN_FNF2,
1890 TP_ACPI_HOTKEYSCAN_FNF3,
1891 TP_ACPI_HOTKEYSCAN_FNF4,
1892 TP_ACPI_HOTKEYSCAN_FNF5,
1893 TP_ACPI_HOTKEYSCAN_FNF6,
1894 TP_ACPI_HOTKEYSCAN_FNF7,
1895 TP_ACPI_HOTKEYSCAN_FNF8,
1896 TP_ACPI_HOTKEYSCAN_FNF9,
1897 TP_ACPI_HOTKEYSCAN_FNF10,
1898 TP_ACPI_HOTKEYSCAN_FNF11,
1899 TP_ACPI_HOTKEYSCAN_FNF12,
1900 TP_ACPI_HOTKEYSCAN_FNBACKSPACE,
1901 TP_ACPI_HOTKEYSCAN_FNINSERT,
1902 TP_ACPI_HOTKEYSCAN_FNDELETE,
1903 TP_ACPI_HOTKEYSCAN_FNHOME,
1904 TP_ACPI_HOTKEYSCAN_FNEND,
1905 TP_ACPI_HOTKEYSCAN_FNPAGEUP,
1906 TP_ACPI_HOTKEYSCAN_FNPAGEDOWN,
1907 TP_ACPI_HOTKEYSCAN_FNSPACE,
1908 TP_ACPI_HOTKEYSCAN_VOLUMEUP,
1909 TP_ACPI_HOTKEYSCAN_VOLUMEDOWN,
1910 TP_ACPI_HOTKEYSCAN_MUTE,
1911 TP_ACPI_HOTKEYSCAN_THINKPAD,
1912 TP_ACPI_HOTKEYSCAN_UNK1,
1913 TP_ACPI_HOTKEYSCAN_UNK2,
1914 TP_ACPI_HOTKEYSCAN_UNK3,
1915 TP_ACPI_HOTKEYSCAN_UNK4,
1916 TP_ACPI_HOTKEYSCAN_UNK5,
1917 TP_ACPI_HOTKEYSCAN_UNK6,
1918 TP_ACPI_HOTKEYSCAN_UNK7,
1919 TP_ACPI_HOTKEYSCAN_UNK8,
1920
1921
1922 TPACPI_HOTKEY_MAP_LEN
1923};
1924
1925enum {
1926 TPACPI_HKEY_NVRAM_KNOWN_MASK = 0x00fb88c0U,
1927 TPACPI_HKEY_NVRAM_GOOD_MASK = 0x00fb8000U,
1928};
1929
1930enum {
1931 TP_ACPI_HKEY_DISPSWTCH_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF7,
1932 TP_ACPI_HKEY_DISPXPAND_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF8,
1933 TP_ACPI_HKEY_HIBERNATE_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF12,
1934 TP_ACPI_HKEY_BRGHTUP_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNHOME,
1935 TP_ACPI_HKEY_BRGHTDWN_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNEND,
1936 TP_ACPI_HKEY_THNKLGHT_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNPAGEUP,
1937 TP_ACPI_HKEY_ZOOM_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNSPACE,
1938 TP_ACPI_HKEY_VOLUP_MASK = 1 << TP_ACPI_HOTKEYSCAN_VOLUMEUP,
1939 TP_ACPI_HKEY_VOLDWN_MASK = 1 << TP_ACPI_HOTKEYSCAN_VOLUMEDOWN,
1940 TP_ACPI_HKEY_MUTE_MASK = 1 << TP_ACPI_HOTKEYSCAN_MUTE,
1941 TP_ACPI_HKEY_THINKPAD_MASK = 1 << TP_ACPI_HOTKEYSCAN_THINKPAD,
1942};
1943
1944enum {
1945 TP_NVRAM_HKEY_GROUP_HK2 = TP_ACPI_HKEY_THINKPAD_MASK |
1946 TP_ACPI_HKEY_ZOOM_MASK |
1947 TP_ACPI_HKEY_DISPSWTCH_MASK |
1948 TP_ACPI_HKEY_HIBERNATE_MASK,
1949 TP_NVRAM_HKEY_GROUP_BRIGHTNESS = TP_ACPI_HKEY_BRGHTUP_MASK |
1950 TP_ACPI_HKEY_BRGHTDWN_MASK,
1951 TP_NVRAM_HKEY_GROUP_VOLUME = TP_ACPI_HKEY_VOLUP_MASK |
1952 TP_ACPI_HKEY_VOLDWN_MASK |
1953 TP_ACPI_HKEY_MUTE_MASK,
1954};
1955
1956#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1957struct tp_nvram_state {
1958 u16 thinkpad_toggle:1;
1959 u16 zoom_toggle:1;
1960 u16 display_toggle:1;
1961 u16 thinklight_toggle:1;
1962 u16 hibernate_toggle:1;
1963 u16 displayexp_toggle:1;
1964 u16 display_state:1;
1965 u16 brightness_toggle:1;
1966 u16 volume_toggle:1;
1967 u16 mute:1;
1968
1969 u8 brightness_level;
1970 u8 volume_level;
1971};
1972
1973
1974static struct task_struct *tpacpi_hotkey_task;
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985static struct mutex hotkey_thread_data_mutex;
1986static unsigned int hotkey_config_change;
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998static u32 hotkey_source_mask;
1999static unsigned int hotkey_poll_freq = 10;
2000
2001#define HOTKEY_CONFIG_CRITICAL_START \
2002 do { \
2003 mutex_lock(&hotkey_thread_data_mutex); \
2004 hotkey_config_change++; \
2005 } while (0);
2006#define HOTKEY_CONFIG_CRITICAL_END \
2007 mutex_unlock(&hotkey_thread_data_mutex);
2008
2009#else
2010
2011#define hotkey_source_mask 0U
2012#define HOTKEY_CONFIG_CRITICAL_START
2013#define HOTKEY_CONFIG_CRITICAL_END
2014
2015#endif
2016
2017static struct mutex hotkey_mutex;
2018
2019static enum {
2020 TP_ACPI_WAKEUP_NONE = 0,
2021 TP_ACPI_WAKEUP_BAYEJ,
2022 TP_ACPI_WAKEUP_UNDOCK,
2023} hotkey_wakeup_reason;
2024
2025static int hotkey_autosleep_ack;
2026
2027static u32 hotkey_orig_mask;
2028static u32 hotkey_all_mask;
2029static u32 hotkey_reserved_mask;
2030static u32 hotkey_driver_mask;
2031static u32 hotkey_user_mask;
2032static u32 hotkey_acpi_mask;
2033
2034static u16 *hotkey_keycode_map;
2035
2036static struct attribute_set *hotkey_dev_attributes;
2037
2038static void tpacpi_driver_event(const unsigned int hkey_event);
2039static void hotkey_driver_event(const unsigned int scancode);
2040static void hotkey_poll_setup(const bool may_warn);
2041
2042
2043#define TP_HOTKEY_TABLET_MASK (1 << 3)
2044
2045static int hotkey_get_wlsw(void)
2046{
2047 int status;
2048
2049 if (!tp_features.hotkey_wlsw)
2050 return -ENODEV;
2051
2052#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
2053 if (dbg_wlswemul)
2054 return (tpacpi_wlsw_emulstate) ?
2055 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
2056#endif
2057
2058 if (!acpi_evalf(hkey_handle, &status, "WLSW", "d"))
2059 return -EIO;
2060
2061 return (status) ? TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
2062}
2063
2064static int hotkey_get_tablet_mode(int *status)
2065{
2066 int s;
2067
2068 if (!acpi_evalf(hkey_handle, &s, "MHKG", "d"))
2069 return -EIO;
2070
2071 *status = ((s & TP_HOTKEY_TABLET_MASK) != 0);
2072 return 0;
2073}
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083static int hotkey_mask_get(void)
2084{
2085 if (tp_features.hotkey_mask) {
2086 u32 m = 0;
2087
2088 if (!acpi_evalf(hkey_handle, &m, "DHKN", "d"))
2089 return -EIO;
2090
2091 hotkey_acpi_mask = m;
2092 } else {
2093
2094 hotkey_acpi_mask = hotkey_all_mask;
2095 }
2096
2097
2098 hotkey_user_mask &= (hotkey_acpi_mask | hotkey_source_mask);
2099
2100 return 0;
2101}
2102
2103void static hotkey_mask_warn_incomplete_mask(void)
2104{
2105
2106 const u32 wantedmask = hotkey_driver_mask &
2107 ~(hotkey_acpi_mask | hotkey_source_mask) &
2108 (hotkey_all_mask | TPACPI_HKEY_NVRAM_KNOWN_MASK);
2109
2110 if (wantedmask)
2111 pr_notice("required events 0x%08x not enabled!\n", wantedmask);
2112}
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123static int hotkey_mask_set(u32 mask)
2124{
2125 int i;
2126 int rc = 0;
2127
2128 const u32 fwmask = mask & ~hotkey_source_mask;
2129
2130 if (tp_features.hotkey_mask) {
2131 for (i = 0; i < 32; i++) {
2132 if (!acpi_evalf(hkey_handle,
2133 NULL, "MHKM", "vdd", i + 1,
2134 !!(mask & (1 << i)))) {
2135 rc = -EIO;
2136 break;
2137 }
2138 }
2139 }
2140
2141
2142
2143
2144
2145
2146
2147
2148 if (!hotkey_mask_get() && !rc && (fwmask & ~hotkey_acpi_mask)) {
2149 pr_notice("asked for hotkey mask 0x%08x, but "
2150 "firmware forced it to 0x%08x\n",
2151 fwmask, hotkey_acpi_mask);
2152 }
2153
2154 if (tpacpi_lifecycle != TPACPI_LIFE_EXITING)
2155 hotkey_mask_warn_incomplete_mask();
2156
2157 return rc;
2158}
2159
2160
2161
2162
2163
2164
2165static int hotkey_user_mask_set(const u32 mask)
2166{
2167 int rc;
2168
2169
2170
2171 if (!tp_warned.hotkey_mask_ff &&
2172 (mask == 0xffff || mask == 0xffffff ||
2173 mask == 0xffffffff)) {
2174 tp_warned.hotkey_mask_ff = 1;
2175 pr_notice("setting the hotkey mask to 0x%08x is likely "
2176 "not the best way to go about it\n", mask);
2177 pr_notice("please consider using the driver defaults, "
2178 "and refer to up-to-date thinkpad-acpi "
2179 "documentation\n");
2180 }
2181
2182
2183
2184 rc = hotkey_mask_set((mask | hotkey_driver_mask) & ~hotkey_source_mask);
2185
2186
2187 hotkey_user_mask = mask & (hotkey_acpi_mask | hotkey_source_mask);
2188
2189 return rc;
2190}
2191
2192
2193
2194
2195
2196
2197static int tpacpi_hotkey_driver_mask_set(const u32 mask)
2198{
2199 int rc;
2200
2201
2202 if (!tp_features.hotkey) {
2203 hotkey_driver_mask = mask;
2204 return 0;
2205 }
2206
2207 mutex_lock(&hotkey_mutex);
2208
2209 HOTKEY_CONFIG_CRITICAL_START
2210 hotkey_driver_mask = mask;
2211#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2212 hotkey_source_mask |= (mask & ~hotkey_all_mask);
2213#endif
2214 HOTKEY_CONFIG_CRITICAL_END
2215
2216 rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) &
2217 ~hotkey_source_mask);
2218 hotkey_poll_setup(true);
2219
2220 mutex_unlock(&hotkey_mutex);
2221
2222 return rc;
2223}
2224
2225static int hotkey_status_get(int *status)
2226{
2227 if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
2228 return -EIO;
2229
2230 return 0;
2231}
2232
2233static int hotkey_status_set(bool enable)
2234{
2235 if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", enable ? 1 : 0))
2236 return -EIO;
2237
2238 return 0;
2239}
2240
2241static void tpacpi_input_send_tabletsw(void)
2242{
2243 int state;
2244
2245 if (tp_features.hotkey_tablet &&
2246 !hotkey_get_tablet_mode(&state)) {
2247 mutex_lock(&tpacpi_inputdev_send_mutex);
2248
2249 input_report_switch(tpacpi_inputdev,
2250 SW_TABLET_MODE, !!state);
2251 input_sync(tpacpi_inputdev);
2252
2253 mutex_unlock(&tpacpi_inputdev_send_mutex);
2254 }
2255}
2256
2257
2258static void tpacpi_input_send_key(const unsigned int scancode)
2259{
2260 const unsigned int keycode = hotkey_keycode_map[scancode];
2261
2262 if (keycode != KEY_RESERVED) {
2263 mutex_lock(&tpacpi_inputdev_send_mutex);
2264
2265 input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, scancode);
2266 input_report_key(tpacpi_inputdev, keycode, 1);
2267 input_sync(tpacpi_inputdev);
2268
2269 input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, scancode);
2270 input_report_key(tpacpi_inputdev, keycode, 0);
2271 input_sync(tpacpi_inputdev);
2272
2273 mutex_unlock(&tpacpi_inputdev_send_mutex);
2274 }
2275}
2276
2277
2278static void tpacpi_input_send_key_masked(const unsigned int scancode)
2279{
2280 hotkey_driver_event(scancode);
2281 if (hotkey_user_mask & (1 << scancode))
2282 tpacpi_input_send_key(scancode);
2283}
2284
2285#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2286static struct tp_acpi_drv_struct ibm_hotkey_acpidriver;
2287
2288
2289static void tpacpi_hotkey_send_key(unsigned int scancode)
2290{
2291 tpacpi_input_send_key_masked(scancode);
2292}
2293
2294static void hotkey_read_nvram(struct tp_nvram_state *n, const u32 m)
2295{
2296 u8 d;
2297
2298 if (m & TP_NVRAM_HKEY_GROUP_HK2) {
2299 d = nvram_read_byte(TP_NVRAM_ADDR_HK2);
2300 n->thinkpad_toggle = !!(d & TP_NVRAM_MASK_HKT_THINKPAD);
2301 n->zoom_toggle = !!(d & TP_NVRAM_MASK_HKT_ZOOM);
2302 n->display_toggle = !!(d & TP_NVRAM_MASK_HKT_DISPLAY);
2303 n->hibernate_toggle = !!(d & TP_NVRAM_MASK_HKT_HIBERNATE);
2304 }
2305 if (m & TP_ACPI_HKEY_THNKLGHT_MASK) {
2306 d = nvram_read_byte(TP_NVRAM_ADDR_THINKLIGHT);
2307 n->thinklight_toggle = !!(d & TP_NVRAM_MASK_THINKLIGHT);
2308 }
2309 if (m & TP_ACPI_HKEY_DISPXPAND_MASK) {
2310 d = nvram_read_byte(TP_NVRAM_ADDR_VIDEO);
2311 n->displayexp_toggle =
2312 !!(d & TP_NVRAM_MASK_HKT_DISPEXPND);
2313 }
2314 if (m & TP_NVRAM_HKEY_GROUP_BRIGHTNESS) {
2315 d = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
2316 n->brightness_level = (d & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
2317 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
2318 n->brightness_toggle =
2319 !!(d & TP_NVRAM_MASK_HKT_BRIGHTNESS);
2320 }
2321 if (m & TP_NVRAM_HKEY_GROUP_VOLUME) {
2322 d = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
2323 n->volume_level = (d & TP_NVRAM_MASK_LEVEL_VOLUME)
2324 >> TP_NVRAM_POS_LEVEL_VOLUME;
2325 n->mute = !!(d & TP_NVRAM_MASK_MUTE);
2326 n->volume_toggle = !!(d & TP_NVRAM_MASK_HKT_VOLUME);
2327 }
2328}
2329
2330static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
2331 struct tp_nvram_state *newn,
2332 const u32 event_mask)
2333{
2334
2335#define TPACPI_COMPARE_KEY(__scancode, __member) \
2336 do { \
2337 if ((event_mask & (1 << __scancode)) && \
2338 oldn->__member != newn->__member) \
2339 tpacpi_hotkey_send_key(__scancode); \
2340 } while (0)
2341
2342#define TPACPI_MAY_SEND_KEY(__scancode) \
2343 do { \
2344 if (event_mask & (1 << __scancode)) \
2345 tpacpi_hotkey_send_key(__scancode); \
2346 } while (0)
2347
2348 void issue_volchange(const unsigned int oldvol,
2349 const unsigned int newvol)
2350 {
2351 unsigned int i = oldvol;
2352
2353 while (i > newvol) {
2354 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN);
2355 i--;
2356 }
2357 while (i < newvol) {
2358 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);
2359 i++;
2360 }
2361 }
2362
2363 void issue_brightnesschange(const unsigned int oldbrt,
2364 const unsigned int newbrt)
2365 {
2366 unsigned int i = oldbrt;
2367
2368 while (i > newbrt) {
2369 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND);
2370 i--;
2371 }
2372 while (i < newbrt) {
2373 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME);
2374 i++;
2375 }
2376 }
2377
2378 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle);
2379 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle);
2380 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle);
2381 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF12, hibernate_toggle);
2382
2383 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNPAGEUP, thinklight_toggle);
2384
2385 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF8, displayexp_toggle);
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404 if (newn->mute) {
2405
2406 if (!oldn->mute ||
2407 oldn->volume_toggle != newn->volume_toggle ||
2408 oldn->volume_level != newn->volume_level) {
2409
2410
2411 issue_volchange(oldn->volume_level, newn->volume_level);
2412 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE);
2413 }
2414 } else {
2415
2416 if (oldn->mute) {
2417
2418 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);
2419 }
2420 if (oldn->volume_level != newn->volume_level) {
2421 issue_volchange(oldn->volume_level, newn->volume_level);
2422 } else if (oldn->volume_toggle != newn->volume_toggle) {
2423
2424 if (newn->volume_level == 0)
2425 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN);
2426 else if (newn->volume_level >= TP_NVRAM_LEVEL_VOLUME_MAX)
2427 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);
2428 }
2429 }
2430
2431
2432 if (oldn->brightness_level != newn->brightness_level) {
2433 issue_brightnesschange(oldn->brightness_level,
2434 newn->brightness_level);
2435 } else if (oldn->brightness_toggle != newn->brightness_toggle) {
2436
2437 if (newn->brightness_level == 0)
2438 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND);
2439 else if (newn->brightness_level >= bright_maxlvl
2440 && !tp_features.bright_unkfw)
2441 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME);
2442 }
2443
2444#undef TPACPI_COMPARE_KEY
2445#undef TPACPI_MAY_SEND_KEY
2446}
2447
2448
2449
2450
2451
2452
2453
2454
2455static int hotkey_kthread(void *data)
2456{
2457 struct tp_nvram_state s[2];
2458 u32 poll_mask, event_mask;
2459 unsigned int si, so;
2460 unsigned long t;
2461 unsigned int change_detector;
2462 unsigned int poll_freq;
2463 bool was_frozen;
2464
2465 if (tpacpi_lifecycle == TPACPI_LIFE_EXITING)
2466 goto exit;
2467
2468 set_freezable();
2469
2470 so = 0;
2471 si = 1;
2472 t = 0;
2473
2474
2475 mutex_lock(&hotkey_thread_data_mutex);
2476 change_detector = hotkey_config_change;
2477 poll_mask = hotkey_source_mask;
2478 event_mask = hotkey_source_mask &
2479 (hotkey_driver_mask | hotkey_user_mask);
2480 poll_freq = hotkey_poll_freq;
2481 mutex_unlock(&hotkey_thread_data_mutex);
2482 hotkey_read_nvram(&s[so], poll_mask);
2483
2484 while (!kthread_should_stop()) {
2485 if (t == 0) {
2486 if (likely(poll_freq))
2487 t = 1000/poll_freq;
2488 else
2489 t = 100;
2490 }
2491 t = msleep_interruptible(t);
2492 if (unlikely(kthread_freezable_should_stop(&was_frozen)))
2493 break;
2494
2495 if (t > 0 && !was_frozen)
2496 continue;
2497
2498 mutex_lock(&hotkey_thread_data_mutex);
2499 if (was_frozen || hotkey_config_change != change_detector) {
2500
2501 si = so;
2502 t = 0;
2503 change_detector = hotkey_config_change;
2504 }
2505 poll_mask = hotkey_source_mask;
2506 event_mask = hotkey_source_mask &
2507 (hotkey_driver_mask | hotkey_user_mask);
2508 poll_freq = hotkey_poll_freq;
2509 mutex_unlock(&hotkey_thread_data_mutex);
2510
2511 if (likely(poll_mask)) {
2512 hotkey_read_nvram(&s[si], poll_mask);
2513 if (likely(si != so)) {
2514 hotkey_compare_and_issue_event(&s[so], &s[si],
2515 event_mask);
2516 }
2517 }
2518
2519 so = si;
2520 si ^= 1;
2521 }
2522
2523exit:
2524 return 0;
2525}
2526
2527
2528static void hotkey_poll_stop_sync(void)
2529{
2530 if (tpacpi_hotkey_task) {
2531 kthread_stop(tpacpi_hotkey_task);
2532 tpacpi_hotkey_task = NULL;
2533 }
2534}
2535
2536
2537static void hotkey_poll_setup(const bool may_warn)
2538{
2539 const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask;
2540 const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask;
2541
2542 if (hotkey_poll_freq > 0 &&
2543 (poll_driver_mask ||
2544 (poll_user_mask && tpacpi_inputdev->users > 0))) {
2545 if (!tpacpi_hotkey_task) {
2546 tpacpi_hotkey_task = kthread_run(hotkey_kthread,
2547 NULL, TPACPI_NVRAM_KTHREAD_NAME);
2548 if (IS_ERR(tpacpi_hotkey_task)) {
2549 tpacpi_hotkey_task = NULL;
2550 pr_err("could not create kernel thread "
2551 "for hotkey polling\n");
2552 }
2553 }
2554 } else {
2555 hotkey_poll_stop_sync();
2556 if (may_warn && (poll_driver_mask || poll_user_mask) &&
2557 hotkey_poll_freq == 0) {
2558 pr_notice("hot keys 0x%08x and/or events 0x%08x "
2559 "require polling, which is currently "
2560 "disabled\n",
2561 poll_user_mask, poll_driver_mask);
2562 }
2563 }
2564}
2565
2566static void hotkey_poll_setup_safe(const bool may_warn)
2567{
2568 mutex_lock(&hotkey_mutex);
2569 hotkey_poll_setup(may_warn);
2570 mutex_unlock(&hotkey_mutex);
2571}
2572
2573
2574static void hotkey_poll_set_freq(unsigned int freq)
2575{
2576 if (!freq)
2577 hotkey_poll_stop_sync();
2578
2579 hotkey_poll_freq = freq;
2580}
2581
2582#else
2583
2584static void hotkey_poll_setup(const bool __unused)
2585{
2586}
2587
2588static void hotkey_poll_setup_safe(const bool __unused)
2589{
2590}
2591
2592#endif
2593
2594static int hotkey_inputdev_open(struct input_dev *dev)
2595{
2596 switch (tpacpi_lifecycle) {
2597 case TPACPI_LIFE_INIT:
2598 case TPACPI_LIFE_RUNNING:
2599 hotkey_poll_setup_safe(false);
2600 return 0;
2601 case TPACPI_LIFE_EXITING:
2602 return -EBUSY;
2603 }
2604
2605
2606 BUG();
2607 return -EBUSY;
2608}
2609
2610static void hotkey_inputdev_close(struct input_dev *dev)
2611{
2612
2613 if (tpacpi_lifecycle != TPACPI_LIFE_EXITING &&
2614 !(hotkey_source_mask & hotkey_driver_mask))
2615 hotkey_poll_setup_safe(false);
2616}
2617
2618
2619static ssize_t hotkey_enable_show(struct device *dev,
2620 struct device_attribute *attr,
2621 char *buf)
2622{
2623 int res, status;
2624
2625 printk_deprecated_attribute("hotkey_enable",
2626 "Hotkey reporting is always enabled");
2627
2628 res = hotkey_status_get(&status);
2629 if (res)
2630 return res;
2631
2632 return snprintf(buf, PAGE_SIZE, "%d\n", status);
2633}
2634
2635static ssize_t hotkey_enable_store(struct device *dev,
2636 struct device_attribute *attr,
2637 const char *buf, size_t count)
2638{
2639 unsigned long t;
2640
2641 printk_deprecated_attribute("hotkey_enable",
2642 "Hotkeys can be disabled through hotkey_mask");
2643
2644 if (parse_strtoul(buf, 1, &t))
2645 return -EINVAL;
2646
2647 if (t == 0)
2648 return -EPERM;
2649
2650 return count;
2651}
2652
2653static struct device_attribute dev_attr_hotkey_enable =
2654 __ATTR(hotkey_enable, S_IWUSR | S_IRUGO,
2655 hotkey_enable_show, hotkey_enable_store);
2656
2657
2658static ssize_t hotkey_mask_show(struct device *dev,
2659 struct device_attribute *attr,
2660 char *buf)
2661{
2662 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_user_mask);
2663}
2664
2665static ssize_t hotkey_mask_store(struct device *dev,
2666 struct device_attribute *attr,
2667 const char *buf, size_t count)
2668{
2669 unsigned long t;
2670 int res;
2671
2672 if (parse_strtoul(buf, 0xffffffffUL, &t))
2673 return -EINVAL;
2674
2675 if (mutex_lock_killable(&hotkey_mutex))
2676 return -ERESTARTSYS;
2677
2678 res = hotkey_user_mask_set(t);
2679
2680#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2681 hotkey_poll_setup(true);
2682#endif
2683
2684 mutex_unlock(&hotkey_mutex);
2685
2686 tpacpi_disclose_usertask("hotkey_mask", "set to 0x%08lx\n", t);
2687
2688 return (res) ? res : count;
2689}
2690
2691static struct device_attribute dev_attr_hotkey_mask =
2692 __ATTR(hotkey_mask, S_IWUSR | S_IRUGO,
2693 hotkey_mask_show, hotkey_mask_store);
2694
2695
2696static ssize_t hotkey_bios_enabled_show(struct device *dev,
2697 struct device_attribute *attr,
2698 char *buf)
2699{
2700 return sprintf(buf, "0\n");
2701}
2702
2703static struct device_attribute dev_attr_hotkey_bios_enabled =
2704 __ATTR(hotkey_bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL);
2705
2706
2707static ssize_t hotkey_bios_mask_show(struct device *dev,
2708 struct device_attribute *attr,
2709 char *buf)
2710{
2711 printk_deprecated_attribute("hotkey_bios_mask",
2712 "This attribute is useless.");
2713 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask);
2714}
2715
2716static struct device_attribute dev_attr_hotkey_bios_mask =
2717 __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL);
2718
2719
2720static ssize_t hotkey_all_mask_show(struct device *dev,
2721 struct device_attribute *attr,
2722 char *buf)
2723{
2724 return snprintf(buf, PAGE_SIZE, "0x%08x\n",
2725 hotkey_all_mask | hotkey_source_mask);
2726}
2727
2728static struct device_attribute dev_attr_hotkey_all_mask =
2729 __ATTR(hotkey_all_mask, S_IRUGO, hotkey_all_mask_show, NULL);
2730
2731
2732static ssize_t hotkey_recommended_mask_show(struct device *dev,
2733 struct device_attribute *attr,
2734 char *buf)
2735{
2736 return snprintf(buf, PAGE_SIZE, "0x%08x\n",
2737 (hotkey_all_mask | hotkey_source_mask)
2738 & ~hotkey_reserved_mask);
2739}
2740
2741static struct device_attribute dev_attr_hotkey_recommended_mask =
2742 __ATTR(hotkey_recommended_mask, S_IRUGO,
2743 hotkey_recommended_mask_show, NULL);
2744
2745#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2746
2747
2748static ssize_t hotkey_source_mask_show(struct device *dev,
2749 struct device_attribute *attr,
2750 char *buf)
2751{
2752 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_source_mask);
2753}
2754
2755static ssize_t hotkey_source_mask_store(struct device *dev,
2756 struct device_attribute *attr,
2757 const char *buf, size_t count)
2758{
2759 unsigned long t;
2760 u32 r_ev;
2761 int rc;
2762
2763 if (parse_strtoul(buf, 0xffffffffUL, &t) ||
2764 ((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0))
2765 return -EINVAL;
2766
2767 if (mutex_lock_killable(&hotkey_mutex))
2768 return -ERESTARTSYS;
2769
2770 HOTKEY_CONFIG_CRITICAL_START
2771 hotkey_source_mask = t;
2772 HOTKEY_CONFIG_CRITICAL_END
2773
2774 rc = hotkey_mask_set((hotkey_user_mask | hotkey_driver_mask) &
2775 ~hotkey_source_mask);
2776 hotkey_poll_setup(true);
2777
2778
2779 r_ev = hotkey_driver_mask & ~(hotkey_acpi_mask & hotkey_all_mask)
2780 & ~hotkey_source_mask & TPACPI_HKEY_NVRAM_KNOWN_MASK;
2781
2782 mutex_unlock(&hotkey_mutex);
2783
2784 if (rc < 0)
2785 pr_err("hotkey_source_mask: "
2786 "failed to update the firmware event mask!\n");
2787
2788 if (r_ev)
2789 pr_notice("hotkey_source_mask: "
2790 "some important events were disabled: 0x%04x\n",
2791 r_ev);
2792
2793 tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t);
2794
2795 return (rc < 0) ? rc : count;
2796}
2797
2798static struct device_attribute dev_attr_hotkey_source_mask =
2799 __ATTR(hotkey_source_mask, S_IWUSR | S_IRUGO,
2800 hotkey_source_mask_show, hotkey_source_mask_store);
2801
2802
2803static ssize_t hotkey_poll_freq_show(struct device *dev,
2804 struct device_attribute *attr,
2805 char *buf)
2806{
2807 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_poll_freq);
2808}
2809
2810static ssize_t hotkey_poll_freq_store(struct device *dev,
2811 struct device_attribute *attr,
2812 const char *buf, size_t count)
2813{
2814 unsigned long t;
2815
2816 if (parse_strtoul(buf, 25, &t))
2817 return -EINVAL;
2818
2819 if (mutex_lock_killable(&hotkey_mutex))
2820 return -ERESTARTSYS;
2821
2822 hotkey_poll_set_freq(t);
2823 hotkey_poll_setup(true);
2824
2825 mutex_unlock(&hotkey_mutex);
2826
2827 tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t);
2828
2829 return count;
2830}
2831
2832static struct device_attribute dev_attr_hotkey_poll_freq =
2833 __ATTR(hotkey_poll_freq, S_IWUSR | S_IRUGO,
2834 hotkey_poll_freq_show, hotkey_poll_freq_store);
2835
2836#endif
2837
2838
2839static ssize_t hotkey_radio_sw_show(struct device *dev,
2840 struct device_attribute *attr,
2841 char *buf)
2842{
2843 int res;
2844 res = hotkey_get_wlsw();
2845 if (res < 0)
2846 return res;
2847
2848
2849 tpacpi_rfk_update_hwblock_state((res == TPACPI_RFK_RADIO_OFF));
2850
2851 return snprintf(buf, PAGE_SIZE, "%d\n",
2852 (res == TPACPI_RFK_RADIO_OFF) ? 0 : 1);
2853}
2854
2855static struct device_attribute dev_attr_hotkey_radio_sw =
2856 __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL);
2857
2858static void hotkey_radio_sw_notify_change(void)
2859{
2860 if (tp_features.hotkey_wlsw)
2861 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
2862 "hotkey_radio_sw");
2863}
2864
2865
2866static ssize_t hotkey_tablet_mode_show(struct device *dev,
2867 struct device_attribute *attr,
2868 char *buf)
2869{
2870 int res, s;
2871 res = hotkey_get_tablet_mode(&s);
2872 if (res < 0)
2873 return res;
2874
2875 return snprintf(buf, PAGE_SIZE, "%d\n", !!s);
2876}
2877
2878static struct device_attribute dev_attr_hotkey_tablet_mode =
2879 __ATTR(hotkey_tablet_mode, S_IRUGO, hotkey_tablet_mode_show, NULL);
2880
2881static void hotkey_tablet_mode_notify_change(void)
2882{
2883 if (tp_features.hotkey_tablet)
2884 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
2885 "hotkey_tablet_mode");
2886}
2887
2888
2889static ssize_t hotkey_wakeup_reason_show(struct device *dev,
2890 struct device_attribute *attr,
2891 char *buf)
2892{
2893 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_wakeup_reason);
2894}
2895
2896static struct device_attribute dev_attr_hotkey_wakeup_reason =
2897 __ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL);
2898
2899static void hotkey_wakeup_reason_notify_change(void)
2900{
2901 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
2902 "wakeup_reason");
2903}
2904
2905
2906static ssize_t hotkey_wakeup_hotunplug_complete_show(struct device *dev,
2907 struct device_attribute *attr,
2908 char *buf)
2909{
2910 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_autosleep_ack);
2911}
2912
2913static struct device_attribute dev_attr_hotkey_wakeup_hotunplug_complete =
2914 __ATTR(wakeup_hotunplug_complete, S_IRUGO,
2915 hotkey_wakeup_hotunplug_complete_show, NULL);
2916
2917static void hotkey_wakeup_hotunplug_complete_notify_change(void)
2918{
2919 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
2920 "wakeup_hotunplug_complete");
2921}
2922
2923
2924
2925static struct attribute *hotkey_attributes[] __initdata = {
2926 &dev_attr_hotkey_enable.attr,
2927 &dev_attr_hotkey_bios_enabled.attr,
2928 &dev_attr_hotkey_bios_mask.attr,
2929 &dev_attr_hotkey_wakeup_reason.attr,
2930 &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
2931 &dev_attr_hotkey_mask.attr,
2932 &dev_attr_hotkey_all_mask.attr,
2933 &dev_attr_hotkey_recommended_mask.attr,
2934#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2935 &dev_attr_hotkey_source_mask.attr,
2936 &dev_attr_hotkey_poll_freq.attr,
2937#endif
2938};
2939
2940
2941
2942
2943static void tpacpi_send_radiosw_update(void)
2944{
2945 int wlsw;
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958 wlsw = hotkey_get_wlsw();
2959
2960
2961 if (wlsw == TPACPI_RFK_RADIO_OFF)
2962 tpacpi_rfk_update_hwblock_state(true);
2963
2964
2965 tpacpi_rfk_update_swstate_all();
2966
2967
2968 if (wlsw == TPACPI_RFK_RADIO_ON)
2969 tpacpi_rfk_update_hwblock_state(false);
2970
2971
2972 if (!(wlsw < 0)) {
2973 mutex_lock(&tpacpi_inputdev_send_mutex);
2974
2975 input_report_switch(tpacpi_inputdev,
2976 SW_RFKILL_ALL, (wlsw > 0));
2977 input_sync(tpacpi_inputdev);
2978
2979 mutex_unlock(&tpacpi_inputdev_send_mutex);
2980 }
2981
2982
2983
2984
2985
2986 hotkey_radio_sw_notify_change();
2987}
2988
2989static void hotkey_exit(void)
2990{
2991#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2992 mutex_lock(&hotkey_mutex);
2993 hotkey_poll_stop_sync();
2994 mutex_unlock(&hotkey_mutex);
2995#endif
2996
2997 if (hotkey_dev_attributes)
2998 delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
2999
3000 dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,
3001 "restoring original HKEY status and mask\n");
3002
3003
3004 if (((tp_features.hotkey_mask &&
3005 hotkey_mask_set(hotkey_orig_mask)) |
3006 hotkey_status_set(false)) != 0)
3007 pr_err("failed to restore hot key mask "
3008 "to BIOS defaults\n");
3009}
3010
3011static void __init hotkey_unmap(const unsigned int scancode)
3012{
3013 if (hotkey_keycode_map[scancode] != KEY_RESERVED) {
3014 clear_bit(hotkey_keycode_map[scancode],
3015 tpacpi_inputdev->keybit);
3016 hotkey_keycode_map[scancode] = KEY_RESERVED;
3017 }
3018}
3019
3020
3021
3022
3023
3024
3025#define TPACPI_HK_Q_INIMASK 0x0001
3026
3027static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = {
3028 TPACPI_Q_IBM('I', 'H', TPACPI_HK_Q_INIMASK),
3029 TPACPI_Q_IBM('I', 'N', TPACPI_HK_Q_INIMASK),
3030 TPACPI_Q_IBM('I', 'D', TPACPI_HK_Q_INIMASK),
3031 TPACPI_Q_IBM('I', 'W', TPACPI_HK_Q_INIMASK),
3032 TPACPI_Q_IBM('I', 'V', TPACPI_HK_Q_INIMASK),
3033 TPACPI_Q_IBM('1', '0', TPACPI_HK_Q_INIMASK),
3034 TPACPI_Q_IBM('K', 'U', TPACPI_HK_Q_INIMASK),
3035 TPACPI_Q_IBM('K', 'X', TPACPI_HK_Q_INIMASK),
3036 TPACPI_Q_IBM('K', 'Y', TPACPI_HK_Q_INIMASK),
3037 TPACPI_Q_IBM('1', 'B', TPACPI_HK_Q_INIMASK),
3038 TPACPI_Q_IBM('1', '3', TPACPI_HK_Q_INIMASK),
3039 TPACPI_Q_IBM('1', 'E', TPACPI_HK_Q_INIMASK),
3040 TPACPI_Q_IBM('1', 'C', TPACPI_HK_Q_INIMASK),
3041 TPACPI_Q_IBM('1', 'F', TPACPI_HK_Q_INIMASK),
3042 TPACPI_Q_IBM('I', 'Y', TPACPI_HK_Q_INIMASK),
3043 TPACPI_Q_IBM('K', 'Z', TPACPI_HK_Q_INIMASK),
3044 TPACPI_Q_IBM('1', '6', TPACPI_HK_Q_INIMASK),
3045 TPACPI_Q_IBM('I', 'Z', TPACPI_HK_Q_INIMASK),
3046 TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK),
3047};
3048
3049typedef u16 tpacpi_keymap_entry_t;
3050typedef tpacpi_keymap_entry_t tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN];
3051
3052static int __init hotkey_init(struct ibm_init_struct *iibm)
3053{
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084 enum keymap_index {
3085 TPACPI_KEYMAP_IBM_GENERIC = 0,
3086 TPACPI_KEYMAP_LENOVO_GENERIC,
3087 };
3088
3089 static const tpacpi_keymap_t tpacpi_keymaps[] __initconst = {
3090
3091 [TPACPI_KEYMAP_IBM_GENERIC] = {
3092
3093 KEY_FN_F1, KEY_BATTERY, KEY_COFFEE, KEY_SLEEP,
3094 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
3095 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
3096
3097
3098 KEY_UNKNOWN,
3099 KEY_UNKNOWN,
3100 KEY_UNKNOWN,
3101
3102
3103 KEY_RESERVED,
3104 KEY_RESERVED,
3105
3106
3107 KEY_RESERVED,
3108
3109 KEY_UNKNOWN,
3110 KEY_ZOOM,
3111
3112
3113
3114
3115 KEY_RESERVED,
3116 KEY_RESERVED,
3117 KEY_RESERVED,
3118
3119 KEY_VENDOR,
3120
3121
3122 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
3123 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
3124 },
3125
3126
3127 [TPACPI_KEYMAP_LENOVO_GENERIC] = {
3128
3129 KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP,
3130 KEY_WLAN, KEY_CAMERA, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
3131 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
3132
3133
3134 KEY_UNKNOWN,
3135 KEY_UNKNOWN,
3136 KEY_UNKNOWN,
3137
3138
3139
3140
3141 KEY_BRIGHTNESSUP,
3142 KEY_BRIGHTNESSDOWN,
3143
3144 KEY_RESERVED,
3145
3146 KEY_UNKNOWN,
3147 KEY_ZOOM,
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160 KEY_RESERVED,
3161 KEY_RESERVED,
3162 KEY_RESERVED,
3163
3164 KEY_VENDOR,
3165
3166
3167 KEY_UNKNOWN, KEY_UNKNOWN,
3168
3169
3170
3171
3172
3173 KEY_MICMUTE,
3174
3175
3176 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
3177 KEY_UNKNOWN,
3178 },
3179 };
3180
3181 static const struct tpacpi_quirk tpacpi_keymap_qtable[] __initconst = {
3182
3183 {
3184 .vendor = PCI_VENDOR_ID_IBM,
3185 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
3186 .quirks = TPACPI_KEYMAP_IBM_GENERIC,
3187 },
3188 {
3189 .vendor = PCI_VENDOR_ID_LENOVO,
3190 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
3191 .quirks = TPACPI_KEYMAP_LENOVO_GENERIC,
3192 },
3193 };
3194
3195#define TPACPI_HOTKEY_MAP_SIZE sizeof(tpacpi_keymap_t)
3196#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(tpacpi_keymap_entry_t)
3197
3198 int res, i;
3199 int status;
3200 int hkeyv;
3201 bool radiosw_state = false;
3202 bool tabletsw_state = false;
3203
3204 unsigned long quirks;
3205 unsigned long keymap_id;
3206
3207 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3208 "initializing hotkey subdriver\n");
3209
3210 BUG_ON(!tpacpi_inputdev);
3211 BUG_ON(tpacpi_inputdev->open != NULL ||
3212 tpacpi_inputdev->close != NULL);
3213
3214 TPACPI_ACPIHANDLE_INIT(hkey);
3215 mutex_init(&hotkey_mutex);
3216
3217#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
3218 mutex_init(&hotkey_thread_data_mutex);
3219#endif
3220
3221
3222 tp_features.hotkey = hkey_handle != NULL;
3223
3224 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3225 "hotkeys are %s\n",
3226 str_supported(tp_features.hotkey));
3227
3228 if (!tp_features.hotkey)
3229 return 1;
3230
3231 quirks = tpacpi_check_quirks(tpacpi_hotkey_qtable,
3232 ARRAY_SIZE(tpacpi_hotkey_qtable));
3233
3234 tpacpi_disable_brightness_delay();
3235
3236
3237
3238 hotkey_dev_attributes = create_attr_set(
3239 ARRAY_SIZE(hotkey_attributes) + 2,
3240 NULL);
3241 if (!hotkey_dev_attributes)
3242 return -ENOMEM;
3243 res = add_many_to_attr_set(hotkey_dev_attributes,
3244 hotkey_attributes,
3245 ARRAY_SIZE(hotkey_attributes));
3246 if (res)
3247 goto err_exit;
3248
3249
3250
3251
3252 if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
3253 if ((hkeyv >> 8) != 1) {
3254 pr_err("unknown version of the HKEY interface: 0x%x\n",
3255 hkeyv);
3256 pr_err("please report this to %s\n", TPACPI_MAIL);
3257 } else {
3258
3259
3260
3261
3262 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3263 "firmware HKEY interface version: 0x%x\n",
3264 hkeyv);
3265
3266
3267 if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
3268 "MHKA", "qd")) {
3269 pr_err("missing MHKA handler, "
3270 "please report this to %s\n",
3271 TPACPI_MAIL);
3272
3273 hotkey_all_mask = 0x080cU;
3274 } else {
3275 tp_features.hotkey_mask = 1;
3276 }
3277 }
3278 }
3279
3280 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3281 "hotkey masks are %s\n",
3282 str_supported(tp_features.hotkey_mask));
3283
3284
3285 if (!tp_features.hotkey_mask && !hotkey_all_mask &&
3286 (quirks & TPACPI_HK_Q_INIMASK))
3287 hotkey_all_mask = 0x080cU;
3288
3289
3290 if (tp_features.hotkey_mask) {
3291
3292
3293 res = hotkey_mask_get();
3294 if (res)
3295 goto err_exit;
3296
3297 hotkey_orig_mask = hotkey_acpi_mask;
3298 } else {
3299 hotkey_orig_mask = hotkey_all_mask;
3300 hotkey_acpi_mask = hotkey_all_mask;
3301 }
3302
3303#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3304 if (dbg_wlswemul) {
3305 tp_features.hotkey_wlsw = 1;
3306 radiosw_state = !!tpacpi_wlsw_emulstate;
3307 pr_info("radio switch emulation enabled\n");
3308 } else
3309#endif
3310
3311 if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
3312 tp_features.hotkey_wlsw = 1;
3313 radiosw_state = !!status;
3314 pr_info("radio switch found; radios are %s\n",
3315 enabled(status, 0));
3316 }
3317 if (tp_features.hotkey_wlsw)
3318 res = add_to_attr_set(hotkey_dev_attributes,
3319 &dev_attr_hotkey_radio_sw.attr);
3320
3321
3322 if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) {
3323 tp_features.hotkey_tablet = 1;
3324 tabletsw_state = !!(status & TP_HOTKEY_TABLET_MASK);
3325 pr_info("possible tablet mode switch found; "
3326 "ThinkPad in %s mode\n",
3327 (tabletsw_state) ? "tablet" : "laptop");
3328 res = add_to_attr_set(hotkey_dev_attributes,
3329 &dev_attr_hotkey_tablet_mode.attr);
3330 }
3331
3332 if (!res)
3333 res = register_attr_set_with_sysfs(
3334 hotkey_dev_attributes,
3335 &tpacpi_pdev->dev.kobj);
3336 if (res)
3337 goto err_exit;
3338
3339
3340 hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
3341 GFP_KERNEL);
3342 if (!hotkey_keycode_map) {
3343 pr_err("failed to allocate memory for key map\n");
3344 res = -ENOMEM;
3345 goto err_exit;
3346 }
3347
3348 keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable,
3349 ARRAY_SIZE(tpacpi_keymap_qtable));
3350 BUG_ON(keymap_id >= ARRAY_SIZE(tpacpi_keymaps));
3351 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3352 "using keymap number %lu\n", keymap_id);
3353
3354 memcpy(hotkey_keycode_map, &tpacpi_keymaps[keymap_id],
3355 TPACPI_HOTKEY_MAP_SIZE);
3356
3357 input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN);
3358 tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
3359 tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN;
3360 tpacpi_inputdev->keycode = hotkey_keycode_map;
3361 for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) {
3362 if (hotkey_keycode_map[i] != KEY_RESERVED) {
3363 input_set_capability(tpacpi_inputdev, EV_KEY,
3364 hotkey_keycode_map[i]);
3365 } else {
3366 if (i < sizeof(hotkey_reserved_mask)*8)
3367 hotkey_reserved_mask |= 1 << i;
3368 }
3369 }
3370
3371 if (tp_features.hotkey_wlsw) {
3372 input_set_capability(tpacpi_inputdev, EV_SW, SW_RFKILL_ALL);
3373 input_report_switch(tpacpi_inputdev,
3374 SW_RFKILL_ALL, radiosw_state);
3375 }
3376 if (tp_features.hotkey_tablet) {
3377 input_set_capability(tpacpi_inputdev, EV_SW, SW_TABLET_MODE);
3378 input_report_switch(tpacpi_inputdev,
3379 SW_TABLET_MODE, tabletsw_state);
3380 }
3381
3382
3383
3384
3385 if (acpi_video_backlight_support()) {
3386 pr_info("This ThinkPad has standard ACPI backlight "
3387 "brightness control, supported by the ACPI "
3388 "video driver\n");
3389 pr_notice("Disabling thinkpad-acpi brightness events "
3390 "by default...\n");
3391
3392
3393
3394
3395 hotkey_reserved_mask |=
3396 (1 << TP_ACPI_HOTKEYSCAN_FNHOME)
3397 | (1 << TP_ACPI_HOTKEYSCAN_FNEND);
3398 hotkey_unmap(TP_ACPI_HOTKEYSCAN_FNHOME);
3399 hotkey_unmap(TP_ACPI_HOTKEYSCAN_FNEND);
3400 }
3401
3402#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
3403 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
3404 & ~hotkey_all_mask
3405 & ~hotkey_reserved_mask;
3406
3407 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3408 "hotkey source mask 0x%08x, polling freq %u\n",
3409 hotkey_source_mask, hotkey_poll_freq);
3410#endif
3411
3412 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3413 "enabling firmware HKEY event interface...\n");
3414 res = hotkey_status_set(true);
3415 if (res) {
3416 hotkey_exit();
3417 return res;
3418 }
3419 res = hotkey_mask_set(((hotkey_all_mask & ~hotkey_reserved_mask)
3420 | hotkey_driver_mask)
3421 & ~hotkey_source_mask);
3422 if (res < 0 && res != -ENXIO) {
3423 hotkey_exit();
3424 return res;
3425 }
3426 hotkey_user_mask = (hotkey_acpi_mask | hotkey_source_mask)
3427 & ~hotkey_reserved_mask;
3428 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3429 "initial masks: user=0x%08x, fw=0x%08x, poll=0x%08x\n",
3430 hotkey_user_mask, hotkey_acpi_mask, hotkey_source_mask);
3431
3432 tpacpi_inputdev->open = &hotkey_inputdev_open;
3433 tpacpi_inputdev->close = &hotkey_inputdev_close;
3434
3435 hotkey_poll_setup_safe(true);
3436
3437 return 0;
3438
3439err_exit:
3440 delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
3441 hotkey_dev_attributes = NULL;
3442
3443 return (res < 0)? res : 1;
3444}
3445
3446static bool hotkey_notify_hotkey(const u32 hkey,
3447 bool *send_acpi_ev,
3448 bool *ignore_acpi_ev)
3449{
3450
3451 unsigned int scancode = hkey & 0xfff;
3452 *send_acpi_ev = true;
3453 *ignore_acpi_ev = false;
3454
3455
3456 if (scancode > 0 && scancode <= TPACPI_HOTKEY_MAP_LEN) {
3457 scancode--;
3458 if (!(hotkey_source_mask & (1 << scancode))) {
3459 tpacpi_input_send_key_masked(scancode);
3460 *send_acpi_ev = false;
3461 } else {
3462 *ignore_acpi_ev = true;
3463 }
3464 return true;
3465 }
3466 return false;
3467}
3468
3469static bool hotkey_notify_wakeup(const u32 hkey,
3470 bool *send_acpi_ev,
3471 bool *ignore_acpi_ev)
3472{
3473
3474 *send_acpi_ev = true;
3475 *ignore_acpi_ev = false;
3476
3477 switch (hkey) {
3478 case TP_HKEY_EV_WKUP_S3_UNDOCK:
3479 case TP_HKEY_EV_WKUP_S4_UNDOCK:
3480 hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK;
3481 *ignore_acpi_ev = true;
3482 break;
3483
3484 case TP_HKEY_EV_WKUP_S3_BAYEJ:
3485 case TP_HKEY_EV_WKUP_S4_BAYEJ:
3486 hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ;
3487 *ignore_acpi_ev = true;
3488 break;
3489
3490 case TP_HKEY_EV_WKUP_S3_BATLOW:
3491 case TP_HKEY_EV_WKUP_S4_BATLOW:
3492 pr_alert("EMERGENCY WAKEUP: battery almost empty\n");
3493
3494
3495
3496 break;
3497
3498 default:
3499 return false;
3500 }
3501
3502 if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) {
3503 pr_info("woke up due to a hot-unplug request...\n");
3504 hotkey_wakeup_reason_notify_change();
3505 }
3506 return true;
3507}
3508
3509static bool hotkey_notify_dockevent(const u32 hkey,
3510 bool *send_acpi_ev,
3511 bool *ignore_acpi_ev)
3512{
3513
3514 *send_acpi_ev = true;
3515 *ignore_acpi_ev = false;
3516
3517 switch (hkey) {
3518 case TP_HKEY_EV_UNDOCK_ACK:
3519
3520 hotkey_autosleep_ack = 1;
3521 pr_info("undocked\n");
3522 hotkey_wakeup_hotunplug_complete_notify_change();
3523 return true;
3524
3525 case TP_HKEY_EV_HOTPLUG_DOCK:
3526 pr_info("docked into hotplug port replicator\n");
3527 return true;
3528 case TP_HKEY_EV_HOTPLUG_UNDOCK:
3529 pr_info("undocked from hotplug port replicator\n");
3530 return true;
3531
3532 default:
3533 return false;
3534 }
3535}
3536
3537static bool hotkey_notify_usrevent(const u32 hkey,
3538 bool *send_acpi_ev,
3539 bool *ignore_acpi_ev)
3540{
3541
3542 *send_acpi_ev = true;
3543 *ignore_acpi_ev = false;
3544
3545 switch (hkey) {
3546 case TP_HKEY_EV_PEN_INSERTED:
3547 case TP_HKEY_EV_PEN_REMOVED:
3548 return true;
3549
3550 case TP_HKEY_EV_TABLET_TABLET:
3551 case TP_HKEY_EV_TABLET_NOTEBOOK:
3552 tpacpi_input_send_tabletsw();
3553 hotkey_tablet_mode_notify_change();
3554 *send_acpi_ev = false;
3555 return true;
3556
3557 case TP_HKEY_EV_LID_CLOSE:
3558 case TP_HKEY_EV_LID_OPEN:
3559 case TP_HKEY_EV_BRGHT_CHANGED:
3560
3561 *ignore_acpi_ev = true;
3562 return true;
3563
3564 default:
3565 return false;
3566 }
3567}
3568
3569static void thermal_dump_all_sensors(void);
3570
3571static bool hotkey_notify_6xxx(const u32 hkey,
3572 bool *send_acpi_ev,
3573 bool *ignore_acpi_ev)
3574{
3575 bool known = true;
3576
3577
3578 *send_acpi_ev = true;
3579 *ignore_acpi_ev = false;
3580
3581 switch (hkey) {
3582 case TP_HKEY_EV_THM_TABLE_CHANGED:
3583 pr_info("EC reports that Thermal Table has changed\n");
3584
3585
3586 return true;
3587 case TP_HKEY_EV_ALARM_BAT_HOT:
3588 pr_crit("THERMAL ALARM: battery is too hot!\n");
3589
3590 break;
3591 case TP_HKEY_EV_ALARM_BAT_XHOT:
3592 pr_alert("THERMAL EMERGENCY: battery is extremely hot!\n");
3593
3594 break;
3595 case TP_HKEY_EV_ALARM_SENSOR_HOT:
3596 pr_crit("THERMAL ALARM: "
3597 "a sensor reports something is too hot!\n");
3598
3599
3600 break;
3601 case TP_HKEY_EV_ALARM_SENSOR_XHOT:
3602 pr_alert("THERMAL EMERGENCY: "
3603 "a sensor reports something is extremely hot!\n");
3604
3605 break;
3606 case TP_HKEY_EV_AC_CHANGED:
3607
3608
3609
3610
3611
3612
3613 case TP_HKEY_EV_KEY_NUMLOCK:
3614 case TP_HKEY_EV_KEY_FN:
3615
3616
3617 *send_acpi_ev = false;
3618 *ignore_acpi_ev = true;
3619 return true;
3620
3621 default:
3622 pr_warn("unknown possible thermal alarm or keyboard event received\n");
3623 known = false;
3624 }
3625
3626 thermal_dump_all_sensors();
3627
3628 return known;
3629}
3630
3631static void hotkey_notify(struct ibm_struct *ibm, u32 event)
3632{
3633 u32 hkey;
3634 bool send_acpi_ev;
3635 bool ignore_acpi_ev;
3636 bool known_ev;
3637
3638 if (event != 0x80) {
3639 pr_err("unknown HKEY notification event %d\n", event);
3640
3641 acpi_bus_generate_netlink_event(
3642 ibm->acpi->device->pnp.device_class,
3643 dev_name(&ibm->acpi->device->dev),
3644 event, 0);
3645 return;
3646 }
3647
3648 while (1) {
3649 if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
3650 pr_err("failed to retrieve HKEY event\n");
3651 return;
3652 }
3653
3654 if (hkey == 0) {
3655
3656 return;
3657 }
3658
3659 send_acpi_ev = true;
3660 ignore_acpi_ev = false;
3661
3662 switch (hkey >> 12) {
3663 case 1:
3664
3665 known_ev = hotkey_notify_hotkey(hkey, &send_acpi_ev,
3666 &ignore_acpi_ev);
3667 break;
3668 case 2:
3669
3670 known_ev = hotkey_notify_wakeup(hkey, &send_acpi_ev,
3671 &ignore_acpi_ev);
3672 break;
3673 case 3:
3674
3675 switch (hkey) {
3676 case TP_HKEY_EV_BAYEJ_ACK:
3677 hotkey_autosleep_ack = 1;
3678 pr_info("bay ejected\n");
3679 hotkey_wakeup_hotunplug_complete_notify_change();
3680 known_ev = true;
3681 break;
3682 case TP_HKEY_EV_OPTDRV_EJ:
3683
3684 known_ev = true;
3685 break;
3686 default:
3687 known_ev = false;
3688 }
3689 break;
3690 case 4:
3691
3692 known_ev = hotkey_notify_dockevent(hkey, &send_acpi_ev,
3693 &ignore_acpi_ev);
3694 break;
3695 case 5:
3696
3697 known_ev = hotkey_notify_usrevent(hkey, &send_acpi_ev,
3698 &ignore_acpi_ev);
3699 break;
3700 case 6:
3701
3702
3703 known_ev = hotkey_notify_6xxx(hkey, &send_acpi_ev,
3704 &ignore_acpi_ev);
3705 break;
3706 case 7:
3707
3708 if (tp_features.hotkey_wlsw &&
3709 hkey == TP_HKEY_EV_RFKILL_CHANGED) {
3710 tpacpi_send_radiosw_update();
3711 send_acpi_ev = 0;
3712 known_ev = true;
3713 break;
3714 }
3715
3716 default:
3717 known_ev = false;
3718 }
3719 if (!known_ev) {
3720 pr_notice("unhandled HKEY event 0x%04x\n", hkey);
3721 pr_notice("please report the conditions when this "
3722 "event happened to %s\n", TPACPI_MAIL);
3723 }
3724
3725
3726 if (!ignore_acpi_ev && send_acpi_ev) {
3727 acpi_bus_generate_netlink_event(
3728 ibm->acpi->device->pnp.device_class,
3729 dev_name(&ibm->acpi->device->dev),
3730 event, hkey);
3731 }
3732 }
3733}
3734
3735static void hotkey_suspend(void)
3736{
3737
3738 hotkey_wakeup_reason = TP_ACPI_WAKEUP_NONE;
3739 hotkey_autosleep_ack = 0;
3740}
3741
3742static void hotkey_resume(void)
3743{
3744 tpacpi_disable_brightness_delay();
3745
3746 if (hotkey_status_set(true) < 0 ||
3747 hotkey_mask_set(hotkey_acpi_mask) < 0)
3748 pr_err("error while attempting to reset the event "
3749 "firmware interface\n");
3750
3751 tpacpi_send_radiosw_update();
3752 hotkey_tablet_mode_notify_change();
3753 hotkey_wakeup_reason_notify_change();
3754 hotkey_wakeup_hotunplug_complete_notify_change();
3755 hotkey_poll_setup_safe(false);
3756}
3757
3758
3759static int hotkey_read(struct seq_file *m)
3760{
3761 int res, status;
3762
3763 if (!tp_features.hotkey) {
3764 seq_printf(m, "status:\t\tnot supported\n");
3765 return 0;
3766 }
3767
3768 if (mutex_lock_killable(&hotkey_mutex))
3769 return -ERESTARTSYS;
3770 res = hotkey_status_get(&status);
3771 if (!res)
3772 res = hotkey_mask_get();
3773 mutex_unlock(&hotkey_mutex);
3774 if (res)
3775 return res;
3776
3777 seq_printf(m, "status:\t\t%s\n", enabled(status, 0));
3778 if (hotkey_all_mask) {
3779 seq_printf(m, "mask:\t\t0x%08x\n", hotkey_user_mask);
3780 seq_printf(m, "commands:\tenable, disable, reset, <mask>\n");
3781 } else {
3782 seq_printf(m, "mask:\t\tnot supported\n");
3783 seq_printf(m, "commands:\tenable, disable, reset\n");
3784 }
3785
3786 return 0;
3787}
3788
3789static void hotkey_enabledisable_warn(bool enable)
3790{
3791 tpacpi_log_usertask("procfs hotkey enable/disable");
3792 if (!WARN((tpacpi_lifecycle == TPACPI_LIFE_RUNNING || !enable),
3793 pr_fmt("hotkey enable/disable functionality has been "
3794 "removed from the driver. "
3795 "Hotkeys are always enabled.\n")))
3796 pr_err("Please remove the hotkey=enable module "
3797 "parameter, it is deprecated. "
3798 "Hotkeys are always enabled.\n");
3799}
3800
3801static int hotkey_write(char *buf)
3802{
3803 int res;
3804 u32 mask;
3805 char *cmd;
3806
3807 if (!tp_features.hotkey)
3808 return -ENODEV;
3809
3810 if (mutex_lock_killable(&hotkey_mutex))
3811 return -ERESTARTSYS;
3812
3813 mask = hotkey_user_mask;
3814
3815 res = 0;
3816 while ((cmd = next_cmd(&buf))) {
3817 if (strlencmp(cmd, "enable") == 0) {
3818 hotkey_enabledisable_warn(1);
3819 } else if (strlencmp(cmd, "disable") == 0) {
3820 hotkey_enabledisable_warn(0);
3821 res = -EPERM;
3822 } else if (strlencmp(cmd, "reset") == 0) {
3823 mask = (hotkey_all_mask | hotkey_source_mask)
3824 & ~hotkey_reserved_mask;
3825 } else if (sscanf(cmd, "0x%x", &mask) == 1) {
3826
3827 } else if (sscanf(cmd, "%x", &mask) == 1) {
3828
3829 } else {
3830 res = -EINVAL;
3831 goto errexit;
3832 }
3833 }
3834
3835 if (!res) {
3836 tpacpi_disclose_usertask("procfs hotkey",
3837 "set mask to 0x%08x\n", mask);
3838 res = hotkey_user_mask_set(mask);
3839 }
3840
3841errexit:
3842 mutex_unlock(&hotkey_mutex);
3843 return res;
3844}
3845
3846static const struct acpi_device_id ibm_htk_device_ids[] = {
3847 {TPACPI_ACPI_IBM_HKEY_HID, 0},
3848 {TPACPI_ACPI_LENOVO_HKEY_HID, 0},
3849 {"", 0},
3850};
3851
3852static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = {
3853 .hid = ibm_htk_device_ids,
3854 .notify = hotkey_notify,
3855 .handle = &hkey_handle,
3856 .type = ACPI_DEVICE_NOTIFY,
3857};
3858
3859static struct ibm_struct hotkey_driver_data = {
3860 .name = "hotkey",
3861 .read = hotkey_read,
3862 .write = hotkey_write,
3863 .exit = hotkey_exit,
3864 .resume = hotkey_resume,
3865 .suspend = hotkey_suspend,
3866 .acpi = &ibm_hotkey_acpidriver,
3867};
3868
3869
3870
3871
3872
3873enum {
3874
3875 TP_ACPI_BLUETOOTH_HWPRESENT = 0x01,
3876 TP_ACPI_BLUETOOTH_RADIOSSW = 0x02,
3877 TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04,
3878
3879};
3880
3881enum {
3882
3883 TP_ACPI_BLTH_GET_ULTRAPORT_ID = 0x00,
3884 TP_ACPI_BLTH_GET_PWR_ON_RESUME = 0x01,
3885 TP_ACPI_BLTH_PWR_ON_ON_RESUME = 0x02,
3886 TP_ACPI_BLTH_PWR_OFF_ON_RESUME = 0x03,
3887 TP_ACPI_BLTH_SAVE_STATE = 0x05,
3888};
3889
3890#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw"
3891
3892static int bluetooth_get_status(void)
3893{
3894 int status;
3895
3896#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3897 if (dbg_bluetoothemul)
3898 return (tpacpi_bluetooth_emulstate) ?
3899 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3900#endif
3901
3902 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
3903 return -EIO;
3904
3905 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ?
3906 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3907}
3908
3909static int bluetooth_set_status(enum tpacpi_rfkill_state state)
3910{
3911 int status;
3912
3913 vdbg_printk(TPACPI_DBG_RFKILL,
3914 "will attempt to %s bluetooth\n",
3915 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
3916
3917#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3918 if (dbg_bluetoothemul) {
3919 tpacpi_bluetooth_emulstate = (state == TPACPI_RFK_RADIO_ON);
3920 return 0;
3921 }
3922#endif
3923
3924 if (state == TPACPI_RFK_RADIO_ON)
3925 status = TP_ACPI_BLUETOOTH_RADIOSSW
3926 | TP_ACPI_BLUETOOTH_RESUMECTRL;
3927 else
3928 status = 0;
3929
3930 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
3931 return -EIO;
3932
3933 return 0;
3934}
3935
3936
3937static ssize_t bluetooth_enable_show(struct device *dev,
3938 struct device_attribute *attr,
3939 char *buf)
3940{
3941 return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_BLUETOOTH_SW_ID,
3942 attr, buf);
3943}
3944
3945static ssize_t bluetooth_enable_store(struct device *dev,
3946 struct device_attribute *attr,
3947 const char *buf, size_t count)
3948{
3949 return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_BLUETOOTH_SW_ID,
3950 attr, buf, count);
3951}
3952
3953static struct device_attribute dev_attr_bluetooth_enable =
3954 __ATTR(bluetooth_enable, S_IWUSR | S_IRUGO,
3955 bluetooth_enable_show, bluetooth_enable_store);
3956
3957
3958
3959static struct attribute *bluetooth_attributes[] = {
3960 &dev_attr_bluetooth_enable.attr,
3961 NULL
3962};
3963
3964static const struct attribute_group bluetooth_attr_group = {
3965 .attrs = bluetooth_attributes,
3966};
3967
3968static const struct tpacpi_rfk_ops bluetooth_tprfk_ops = {
3969 .get_status = bluetooth_get_status,
3970 .set_status = bluetooth_set_status,
3971};
3972
3973static void bluetooth_shutdown(void)
3974{
3975
3976 if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
3977 TP_ACPI_BLTH_SAVE_STATE))
3978 pr_notice("failed to save bluetooth state to NVRAM\n");
3979 else
3980 vdbg_printk(TPACPI_DBG_RFKILL,
3981 "bluetooth state saved to NVRAM\n");
3982}
3983
3984static void bluetooth_exit(void)
3985{
3986 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
3987 &bluetooth_attr_group);
3988
3989 tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);
3990
3991 bluetooth_shutdown();
3992}
3993
3994static int __init bluetooth_init(struct ibm_init_struct *iibm)
3995{
3996 int res;
3997 int status = 0;
3998
3999 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4000 "initializing bluetooth subdriver\n");
4001
4002 TPACPI_ACPIHANDLE_INIT(hkey);
4003
4004
4005
4006 tp_features.bluetooth = hkey_handle &&
4007 acpi_evalf(hkey_handle, &status, "GBDC", "qd");
4008
4009 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4010 "bluetooth is %s, status 0x%02x\n",
4011 str_supported(tp_features.bluetooth),
4012 status);
4013
4014#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
4015 if (dbg_bluetoothemul) {
4016 tp_features.bluetooth = 1;
4017 pr_info("bluetooth switch emulation enabled\n");
4018 } else
4019#endif
4020 if (tp_features.bluetooth &&
4021 !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
4022
4023 tp_features.bluetooth = 0;
4024 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4025 "bluetooth hardware not installed\n");
4026 }
4027
4028 if (!tp_features.bluetooth)
4029 return 1;
4030
4031 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
4032 &bluetooth_tprfk_ops,
4033 RFKILL_TYPE_BLUETOOTH,
4034 TPACPI_RFK_BLUETOOTH_SW_NAME,
4035 true);
4036 if (res)
4037 return res;
4038
4039 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
4040 &bluetooth_attr_group);
4041 if (res) {
4042 tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);
4043 return res;
4044 }
4045
4046 return 0;
4047}
4048
4049
4050static int bluetooth_read(struct seq_file *m)
4051{
4052 return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, m);
4053}
4054
4055static int bluetooth_write(char *buf)
4056{
4057 return tpacpi_rfk_procfs_write(TPACPI_RFK_BLUETOOTH_SW_ID, buf);
4058}
4059
4060static struct ibm_struct bluetooth_driver_data = {
4061 .name = "bluetooth",
4062 .read = bluetooth_read,
4063 .write = bluetooth_write,
4064 .exit = bluetooth_exit,
4065 .shutdown = bluetooth_shutdown,
4066};
4067
4068
4069
4070
4071
4072enum {
4073
4074 TP_ACPI_WANCARD_HWPRESENT = 0x01,
4075 TP_ACPI_WANCARD_RADIOSSW = 0x02,
4076 TP_ACPI_WANCARD_RESUMECTRL = 0x04,
4077
4078};
4079
4080#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
4081
4082static int wan_get_status(void)
4083{
4084 int status;
4085
4086#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
4087 if (dbg_wwanemul)
4088 return (tpacpi_wwan_emulstate) ?
4089 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
4090#endif
4091
4092 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
4093 return -EIO;
4094
4095 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ?
4096 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
4097}
4098
4099static int wan_set_status(enum tpacpi_rfkill_state state)
4100{
4101 int status;
4102
4103 vdbg_printk(TPACPI_DBG_RFKILL,
4104 "will attempt to %s wwan\n",
4105 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
4106
4107#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
4108 if (dbg_wwanemul) {
4109 tpacpi_wwan_emulstate = (state == TPACPI_RFK_RADIO_ON);
4110 return 0;
4111 }
4112#endif
4113
4114 if (state == TPACPI_RFK_RADIO_ON)
4115 status = TP_ACPI_WANCARD_RADIOSSW
4116 | TP_ACPI_WANCARD_RESUMECTRL;
4117 else
4118 status = 0;
4119
4120 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
4121 return -EIO;
4122
4123 return 0;
4124}
4125
4126
4127static ssize_t wan_enable_show(struct device *dev,
4128 struct device_attribute *attr,
4129 char *buf)
4130{
4131 return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_WWAN_SW_ID,
4132 attr, buf);
4133}
4134
4135static ssize_t wan_enable_store(struct device *dev,
4136 struct device_attribute *attr,
4137 const char *buf, size_t count)
4138{
4139 return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_WWAN_SW_ID,
4140 attr, buf, count);
4141}
4142
4143static struct device_attribute dev_attr_wan_enable =
4144 __ATTR(wwan_enable, S_IWUSR | S_IRUGO,
4145 wan_enable_show, wan_enable_store);
4146
4147
4148
4149static struct attribute *wan_attributes[] = {
4150 &dev_attr_wan_enable.attr,
4151 NULL
4152};
4153
4154static const struct attribute_group wan_attr_group = {
4155 .attrs = wan_attributes,
4156};
4157
4158static const struct tpacpi_rfk_ops wan_tprfk_ops = {
4159 .get_status = wan_get_status,
4160 .set_status = wan_set_status,
4161};
4162
4163static void wan_shutdown(void)
4164{
4165
4166 if (!acpi_evalf(NULL, NULL, "\\WGSV", "vd",
4167 TP_ACPI_WGSV_SAVE_STATE))
4168 pr_notice("failed to save WWAN state to NVRAM\n");
4169 else
4170 vdbg_printk(TPACPI_DBG_RFKILL,
4171 "WWAN state saved to NVRAM\n");
4172}
4173
4174static void wan_exit(void)
4175{
4176 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
4177 &wan_attr_group);
4178
4179 tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);
4180
4181 wan_shutdown();
4182}
4183
4184static int __init wan_init(struct ibm_init_struct *iibm)
4185{
4186 int res;
4187 int status = 0;
4188
4189 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4190 "initializing wan subdriver\n");
4191
4192 TPACPI_ACPIHANDLE_INIT(hkey);
4193
4194 tp_features.wan = hkey_handle &&
4195 acpi_evalf(hkey_handle, &status, "GWAN", "qd");
4196
4197 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4198 "wan is %s, status 0x%02x\n",
4199 str_supported(tp_features.wan),
4200 status);
4201
4202#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
4203 if (dbg_wwanemul) {
4204 tp_features.wan = 1;
4205 pr_info("wwan switch emulation enabled\n");
4206 } else
4207#endif
4208 if (tp_features.wan &&
4209 !(status & TP_ACPI_WANCARD_HWPRESENT)) {
4210
4211 tp_features.wan = 0;
4212 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4213 "wan hardware not installed\n");
4214 }
4215
4216 if (!tp_features.wan)
4217 return 1;
4218
4219 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
4220 &wan_tprfk_ops,
4221 RFKILL_TYPE_WWAN,
4222 TPACPI_RFK_WWAN_SW_NAME,
4223 true);
4224 if (res)
4225 return res;
4226
4227 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
4228 &wan_attr_group);
4229
4230 if (res) {
4231 tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);
4232 return res;
4233 }
4234
4235 return 0;
4236}
4237
4238
4239static int wan_read(struct seq_file *m)
4240{
4241 return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, m);
4242}
4243
4244static int wan_write(char *buf)
4245{
4246 return tpacpi_rfk_procfs_write(TPACPI_RFK_WWAN_SW_ID, buf);
4247}
4248
4249static struct ibm_struct wan_driver_data = {
4250 .name = "wan",
4251 .read = wan_read,
4252 .write = wan_write,
4253 .exit = wan_exit,
4254 .shutdown = wan_shutdown,
4255};
4256
4257
4258
4259
4260
4261enum {
4262
4263 TP_ACPI_UWB_HWPRESENT = 0x01,
4264 TP_ACPI_UWB_RADIOSSW = 0x02,
4265};
4266
4267#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw"
4268
4269static int uwb_get_status(void)
4270{
4271 int status;
4272
4273#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
4274 if (dbg_uwbemul)
4275 return (tpacpi_uwb_emulstate) ?
4276 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
4277#endif
4278
4279 if (!acpi_evalf(hkey_handle, &status, "GUWB", "d"))
4280 return -EIO;
4281
4282 return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ?
4283 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
4284}
4285
4286static int uwb_set_status(enum tpacpi_rfkill_state state)
4287{
4288 int status;
4289
4290 vdbg_printk(TPACPI_DBG_RFKILL,
4291 "will attempt to %s UWB\n",
4292 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
4293
4294#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
4295 if (dbg_uwbemul) {
4296 tpacpi_uwb_emulstate = (state == TPACPI_RFK_RADIO_ON);
4297 return 0;
4298 }
4299#endif
4300
4301 if (state == TPACPI_RFK_RADIO_ON)
4302 status = TP_ACPI_UWB_RADIOSSW;
4303 else
4304 status = 0;
4305
4306 if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status))
4307 return -EIO;
4308
4309 return 0;
4310}
4311
4312
4313
4314static const struct tpacpi_rfk_ops uwb_tprfk_ops = {
4315 .get_status = uwb_get_status,
4316 .set_status = uwb_set_status,
4317};
4318
4319static void uwb_exit(void)
4320{
4321 tpacpi_destroy_rfkill(TPACPI_RFK_UWB_SW_ID);
4322}
4323
4324static int __init uwb_init(struct ibm_init_struct *iibm)
4325{
4326 int res;
4327 int status = 0;
4328
4329 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4330 "initializing uwb subdriver\n");
4331
4332 TPACPI_ACPIHANDLE_INIT(hkey);
4333
4334 tp_features.uwb = hkey_handle &&
4335 acpi_evalf(hkey_handle, &status, "GUWB", "qd");
4336
4337 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4338 "uwb is %s, status 0x%02x\n",
4339 str_supported(tp_features.uwb),
4340 status);
4341
4342#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
4343 if (dbg_uwbemul) {
4344 tp_features.uwb = 1;
4345 pr_info("uwb switch emulation enabled\n");
4346 } else
4347#endif
4348 if (tp_features.uwb &&
4349 !(status & TP_ACPI_UWB_HWPRESENT)) {
4350
4351 tp_features.uwb = 0;
4352 dbg_printk(TPACPI_DBG_INIT,
4353 "uwb hardware not installed\n");
4354 }
4355
4356 if (!tp_features.uwb)
4357 return 1;
4358
4359 res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
4360 &uwb_tprfk_ops,
4361 RFKILL_TYPE_UWB,
4362 TPACPI_RFK_UWB_SW_NAME,
4363 false);
4364 return res;
4365}
4366
4367static struct ibm_struct uwb_driver_data = {
4368 .name = "uwb",
4369 .exit = uwb_exit,
4370 .flags.experimental = 1,
4371};
4372
4373
4374
4375
4376
4377#ifdef CONFIG_THINKPAD_ACPI_VIDEO
4378
4379enum video_access_mode {
4380 TPACPI_VIDEO_NONE = 0,
4381 TPACPI_VIDEO_570,
4382 TPACPI_VIDEO_770,
4383 TPACPI_VIDEO_NEW,
4384};
4385
4386enum {
4387 TP_ACPI_VIDEO_S_LCD = 0x01,
4388 TP_ACPI_VIDEO_S_CRT = 0x02,
4389 TP_ACPI_VIDEO_S_DVI = 0x08,
4390};
4391
4392enum {
4393 TP_ACPI_VIDEO_570_PHSCMD = 0x87,
4394 TP_ACPI_VIDEO_570_PHSMASK = 0x03,
4395
4396 TP_ACPI_VIDEO_570_PHS2CMD = 0x8b,
4397 TP_ACPI_VIDEO_570_PHS2SET = 0x80,
4398};
4399
4400static enum video_access_mode video_supported;
4401static int video_orig_autosw;
4402
4403static int video_autosw_get(void);
4404static int video_autosw_set(int enable);
4405
4406TPACPI_HANDLE(vid, root,
4407 "\\_SB.PCI.AGP.VGA",
4408 "\\_SB.PCI0.AGP0.VID0",
4409 "\\_SB.PCI0.VID0",
4410 "\\_SB.PCI0.VID",
4411 "\\_SB.PCI0.AGP.VGA",
4412 "\\_SB.PCI0.AGP.VID",
4413 );
4414
4415TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID");
4416
4417static int __init video_init(struct ibm_init_struct *iibm)
4418{
4419 int ivga;
4420
4421 vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n");
4422
4423 TPACPI_ACPIHANDLE_INIT(vid);
4424 if (tpacpi_is_ibm())
4425 TPACPI_ACPIHANDLE_INIT(vid2);
4426
4427 if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga)
4428
4429 vid_handle = vid2_handle;
4430
4431 if (!vid_handle)
4432
4433 video_supported = TPACPI_VIDEO_NONE;
4434 else if (tpacpi_is_ibm() &&
4435 acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd"))
4436
4437 video_supported = TPACPI_VIDEO_570;
4438 else if (tpacpi_is_ibm() &&
4439 acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd"))
4440
4441 video_supported = TPACPI_VIDEO_770;
4442 else
4443
4444 video_supported = TPACPI_VIDEO_NEW;
4445
4446 vdbg_printk(TPACPI_DBG_INIT, "video is %s, mode %d\n",
4447 str_supported(video_supported != TPACPI_VIDEO_NONE),
4448 video_supported);
4449
4450 return (video_supported != TPACPI_VIDEO_NONE)? 0 : 1;
4451}
4452
4453static void video_exit(void)
4454{
4455 dbg_printk(TPACPI_DBG_EXIT,
4456 "restoring original video autoswitch mode\n");
4457 if (video_autosw_set(video_orig_autosw))
4458 pr_err("error while trying to restore original "
4459 "video autoswitch mode\n");
4460}
4461
4462static int video_outputsw_get(void)
4463{
4464 int status = 0;
4465 int i;
4466
4467 switch (video_supported) {
4468 case TPACPI_VIDEO_570:
4469 if (!acpi_evalf(NULL, &i, "\\_SB.PHS", "dd",
4470 TP_ACPI_VIDEO_570_PHSCMD))
4471 return -EIO;
4472 status = i & TP_ACPI_VIDEO_570_PHSMASK;
4473 break;
4474 case TPACPI_VIDEO_770:
4475 if (!acpi_evalf(NULL, &i, "\\VCDL", "d"))
4476 return -EIO;
4477 if (i)
4478 status |= TP_ACPI_VIDEO_S_LCD;
4479 if (!acpi_evalf(NULL, &i, "\\VCDC", "d"))
4480 return -EIO;
4481 if (i)
4482 status |= TP_ACPI_VIDEO_S_CRT;
4483 break;
4484 case TPACPI_VIDEO_NEW:
4485 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1) ||
4486 !acpi_evalf(NULL, &i, "\\VCDC", "d"))
4487 return -EIO;
4488 if (i)
4489 status |= TP_ACPI_VIDEO_S_CRT;
4490
4491 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0) ||
4492 !acpi_evalf(NULL, &i, "\\VCDL", "d"))
4493 return -EIO;
4494 if (i)
4495 status |= TP_ACPI_VIDEO_S_LCD;
4496 if (!acpi_evalf(NULL, &i, "\\VCDD", "d"))
4497 return -EIO;
4498 if (i)
4499 status |= TP_ACPI_VIDEO_S_DVI;
4500 break;
4501 default:
4502 return -ENOSYS;
4503 }
4504
4505 return status;
4506}
4507
4508static int video_outputsw_set(int status)
4509{
4510 int autosw;
4511 int res = 0;
4512
4513 switch (video_supported) {
4514 case TPACPI_VIDEO_570:
4515 res = acpi_evalf(NULL, NULL,
4516 "\\_SB.PHS2", "vdd",
4517 TP_ACPI_VIDEO_570_PHS2CMD,
4518 status | TP_ACPI_VIDEO_570_PHS2SET);
4519 break;
4520 case TPACPI_VIDEO_770:
4521 autosw = video_autosw_get();
4522 if (autosw < 0)
4523 return autosw;
4524
4525 res = video_autosw_set(1);
4526 if (res)
4527 return res;
4528 res = acpi_evalf(vid_handle, NULL,
4529 "ASWT", "vdd", status * 0x100, 0);
4530 if (!autosw && video_autosw_set(autosw)) {
4531 pr_err("video auto-switch left enabled due to error\n");
4532 return -EIO;
4533 }
4534 break;
4535 case TPACPI_VIDEO_NEW:
4536 res = acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80) &&
4537 acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1);
4538 break;
4539 default:
4540 return -ENOSYS;
4541 }
4542
4543 return (res)? 0 : -EIO;
4544}
4545
4546static int video_autosw_get(void)
4547{
4548 int autosw = 0;
4549
4550 switch (video_supported) {
4551 case TPACPI_VIDEO_570:
4552 if (!acpi_evalf(vid_handle, &autosw, "SWIT", "d"))
4553 return -EIO;
4554 break;
4555 case TPACPI_VIDEO_770:
4556 case TPACPI_VIDEO_NEW:
4557 if (!acpi_evalf(vid_handle, &autosw, "^VDEE", "d"))
4558 return -EIO;
4559 break;
4560 default:
4561 return -ENOSYS;
4562 }
4563
4564 return autosw & 1;
4565}
4566
4567static int video_autosw_set(int enable)
4568{
4569 if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", (enable)? 1 : 0))
4570 return -EIO;
4571 return 0;
4572}
4573
4574static int video_outputsw_cycle(void)
4575{
4576 int autosw = video_autosw_get();
4577 int res;
4578
4579 if (autosw < 0)
4580 return autosw;
4581
4582 switch (video_supported) {
4583 case TPACPI_VIDEO_570:
4584 res = video_autosw_set(1);
4585 if (res)
4586 return res;
4587 res = acpi_evalf(ec_handle, NULL, "_Q16", "v");
4588 break;
4589 case TPACPI_VIDEO_770:
4590 case TPACPI_VIDEO_NEW:
4591 res = video_autosw_set(1);
4592 if (res)
4593 return res;
4594 res = acpi_evalf(vid_handle, NULL, "VSWT", "v");
4595 break;
4596 default:
4597 return -ENOSYS;
4598 }
4599 if (!autosw && video_autosw_set(autosw)) {
4600 pr_err("video auto-switch left enabled due to error\n");
4601 return -EIO;
4602 }
4603
4604 return (res)? 0 : -EIO;
4605}
4606
4607static int video_expand_toggle(void)
4608{
4609 switch (video_supported) {
4610 case TPACPI_VIDEO_570:
4611 return acpi_evalf(ec_handle, NULL, "_Q17", "v")?
4612 0 : -EIO;
4613 case TPACPI_VIDEO_770:
4614 return acpi_evalf(vid_handle, NULL, "VEXP", "v")?
4615 0 : -EIO;
4616 case TPACPI_VIDEO_NEW:
4617 return acpi_evalf(NULL, NULL, "\\VEXP", "v")?
4618 0 : -EIO;
4619 default:
4620 return -ENOSYS;
4621 }
4622
4623}
4624
4625static int video_read(struct seq_file *m)
4626{
4627 int status, autosw;
4628
4629 if (video_supported == TPACPI_VIDEO_NONE) {
4630 seq_printf(m, "status:\t\tnot supported\n");
4631 return 0;
4632 }
4633
4634
4635 if (!capable(CAP_SYS_ADMIN))
4636 return -EPERM;
4637
4638 status = video_outputsw_get();
4639 if (status < 0)
4640 return status;
4641
4642 autosw = video_autosw_get();
4643 if (autosw < 0)
4644 return autosw;
4645
4646 seq_printf(m, "status:\t\tsupported\n");
4647 seq_printf(m, "lcd:\t\t%s\n", enabled(status, 0));
4648 seq_printf(m, "crt:\t\t%s\n", enabled(status, 1));
4649 if (video_supported == TPACPI_VIDEO_NEW)
4650 seq_printf(m, "dvi:\t\t%s\n", enabled(status, 3));
4651 seq_printf(m, "auto:\t\t%s\n", enabled(autosw, 0));
4652 seq_printf(m, "commands:\tlcd_enable, lcd_disable\n");
4653 seq_printf(m, "commands:\tcrt_enable, crt_disable\n");
4654 if (video_supported == TPACPI_VIDEO_NEW)
4655 seq_printf(m, "commands:\tdvi_enable, dvi_disable\n");
4656 seq_printf(m, "commands:\tauto_enable, auto_disable\n");
4657 seq_printf(m, "commands:\tvideo_switch, expand_toggle\n");
4658
4659 return 0;
4660}
4661
4662static int video_write(char *buf)
4663{
4664 char *cmd;
4665 int enable, disable, status;
4666 int res;
4667
4668 if (video_supported == TPACPI_VIDEO_NONE)
4669 return -ENODEV;
4670
4671
4672 if (!capable(CAP_SYS_ADMIN))
4673 return -EPERM;
4674
4675 enable = 0;
4676 disable = 0;
4677
4678 while ((cmd = next_cmd(&buf))) {
4679 if (strlencmp(cmd, "lcd_enable") == 0) {
4680 enable |= TP_ACPI_VIDEO_S_LCD;
4681 } else if (strlencmp(cmd, "lcd_disable") == 0) {
4682 disable |= TP_ACPI_VIDEO_S_LCD;
4683 } else if (strlencmp(cmd, "crt_enable") == 0) {
4684 enable |= TP_ACPI_VIDEO_S_CRT;
4685 } else if (strlencmp(cmd, "crt_disable") == 0) {
4686 disable |= TP_ACPI_VIDEO_S_CRT;
4687 } else if (video_supported == TPACPI_VIDEO_NEW &&
4688 strlencmp(cmd, "dvi_enable") == 0) {
4689 enable |= TP_ACPI_VIDEO_S_DVI;
4690 } else if (video_supported == TPACPI_VIDEO_NEW &&
4691 strlencmp(cmd, "dvi_disable") == 0) {
4692 disable |= TP_ACPI_VIDEO_S_DVI;
4693 } else if (strlencmp(cmd, "auto_enable") == 0) {
4694 res = video_autosw_set(1);
4695 if (res)
4696 return res;
4697 } else if (strlencmp(cmd, "auto_disable") == 0) {
4698 res = video_autosw_set(0);
4699 if (res)
4700 return res;
4701 } else if (strlencmp(cmd, "video_switch") == 0) {
4702 res = video_outputsw_cycle();
4703 if (res)
4704 return res;
4705 } else if (strlencmp(cmd, "expand_toggle") == 0) {
4706 res = video_expand_toggle();
4707 if (res)
4708 return res;
4709 } else
4710 return -EINVAL;
4711 }
4712
4713 if (enable || disable) {
4714 status = video_outputsw_get();
4715 if (status < 0)
4716 return status;
4717 res = video_outputsw_set((status & ~disable) | enable);
4718 if (res)
4719 return res;
4720 }
4721
4722 return 0;
4723}
4724
4725static struct ibm_struct video_driver_data = {
4726 .name = "video",
4727 .read = video_read,
4728 .write = video_write,
4729 .exit = video_exit,
4730};
4731
4732#endif
4733
4734
4735
4736
4737
4738TPACPI_HANDLE(lght, root, "\\LGHT");
4739TPACPI_HANDLE(ledb, ec, "LEDB");
4740
4741static int light_get_status(void)
4742{
4743 int status = 0;
4744
4745 if (tp_features.light_status) {
4746 if (!acpi_evalf(ec_handle, &status, "KBLT", "d"))
4747 return -EIO;
4748 return (!!status);
4749 }
4750
4751 return -ENXIO;
4752}
4753
4754static int light_set_status(int status)
4755{
4756 int rc;
4757
4758 if (tp_features.light) {
4759 if (cmos_handle) {
4760 rc = acpi_evalf(cmos_handle, NULL, NULL, "vd",
4761 (status)?
4762 TP_CMOS_THINKLIGHT_ON :
4763 TP_CMOS_THINKLIGHT_OFF);
4764 } else {
4765 rc = acpi_evalf(lght_handle, NULL, NULL, "vd",
4766 (status)? 1 : 0);
4767 }
4768 return (rc)? 0 : -EIO;
4769 }
4770
4771 return -ENXIO;
4772}
4773
4774static void light_set_status_worker(struct work_struct *work)
4775{
4776 struct tpacpi_led_classdev *data =
4777 container_of(work, struct tpacpi_led_classdev, work);
4778
4779 if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
4780 light_set_status((data->new_state != TPACPI_LED_OFF));
4781}
4782
4783static void light_sysfs_set(struct led_classdev *led_cdev,
4784 enum led_brightness brightness)
4785{
4786 struct tpacpi_led_classdev *data =
4787 container_of(led_cdev,
4788 struct tpacpi_led_classdev,
4789 led_classdev);
4790 data->new_state = (brightness != LED_OFF) ?
4791 TPACPI_LED_ON : TPACPI_LED_OFF;
4792 queue_work(tpacpi_wq, &data->work);
4793}
4794
4795static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev)
4796{
4797 return (light_get_status() == 1)? LED_FULL : LED_OFF;
4798}
4799
4800static struct tpacpi_led_classdev tpacpi_led_thinklight = {
4801 .led_classdev = {
4802 .name = "tpacpi::thinklight",
4803 .brightness_set = &light_sysfs_set,
4804 .brightness_get = &light_sysfs_get,
4805 }
4806};
4807
4808static int __init light_init(struct ibm_init_struct *iibm)
4809{
4810 int rc;
4811
4812 vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
4813
4814 if (tpacpi_is_ibm()) {
4815 TPACPI_ACPIHANDLE_INIT(ledb);
4816 TPACPI_ACPIHANDLE_INIT(lght);
4817 }
4818 TPACPI_ACPIHANDLE_INIT(cmos);
4819 INIT_WORK(&tpacpi_led_thinklight.work, light_set_status_worker);
4820
4821
4822 tp_features.light = (cmos_handle || lght_handle) && !ledb_handle;
4823
4824 if (tp_features.light)
4825
4826
4827 tp_features.light_status =
4828 acpi_evalf(ec_handle, NULL, "KBLT", "qv");
4829
4830 vdbg_printk(TPACPI_DBG_INIT, "light is %s, light status is %s\n",
4831 str_supported(tp_features.light),
4832 str_supported(tp_features.light_status));
4833
4834 if (!tp_features.light)
4835 return 1;
4836
4837 rc = led_classdev_register(&tpacpi_pdev->dev,
4838 &tpacpi_led_thinklight.led_classdev);
4839
4840 if (rc < 0) {
4841 tp_features.light = 0;
4842 tp_features.light_status = 0;
4843 } else {
4844 rc = 0;
4845 }
4846
4847 return rc;
4848}
4849
4850static void light_exit(void)
4851{
4852 led_classdev_unregister(&tpacpi_led_thinklight.led_classdev);
4853 flush_workqueue(tpacpi_wq);
4854}
4855
4856static int light_read(struct seq_file *m)
4857{
4858 int status;
4859
4860 if (!tp_features.light) {
4861 seq_printf(m, "status:\t\tnot supported\n");
4862 } else if (!tp_features.light_status) {
4863 seq_printf(m, "status:\t\tunknown\n");
4864 seq_printf(m, "commands:\ton, off\n");
4865 } else {
4866 status = light_get_status();
4867 if (status < 0)
4868 return status;
4869 seq_printf(m, "status:\t\t%s\n", onoff(status, 0));
4870 seq_printf(m, "commands:\ton, off\n");
4871 }
4872
4873 return 0;
4874}
4875
4876static int light_write(char *buf)
4877{
4878 char *cmd;
4879 int newstatus = 0;
4880
4881 if (!tp_features.light)
4882 return -ENODEV;
4883
4884 while ((cmd = next_cmd(&buf))) {
4885 if (strlencmp(cmd, "on") == 0) {
4886 newstatus = 1;
4887 } else if (strlencmp(cmd, "off") == 0) {
4888 newstatus = 0;
4889 } else
4890 return -EINVAL;
4891 }
4892
4893 return light_set_status(newstatus);
4894}
4895
4896static struct ibm_struct light_driver_data = {
4897 .name = "light",
4898 .read = light_read,
4899 .write = light_write,
4900 .exit = light_exit,
4901};
4902
4903
4904
4905
4906
4907
4908static ssize_t cmos_command_store(struct device *dev,
4909 struct device_attribute *attr,
4910 const char *buf, size_t count)
4911{
4912 unsigned long cmos_cmd;
4913 int res;
4914
4915 if (parse_strtoul(buf, 21, &cmos_cmd))
4916 return -EINVAL;
4917
4918 res = issue_thinkpad_cmos_command(cmos_cmd);
4919 return (res)? res : count;
4920}
4921
4922static struct device_attribute dev_attr_cmos_command =
4923 __ATTR(cmos_command, S_IWUSR, NULL, cmos_command_store);
4924
4925
4926
4927static int __init cmos_init(struct ibm_init_struct *iibm)
4928{
4929 int res;
4930
4931 vdbg_printk(TPACPI_DBG_INIT,
4932 "initializing cmos commands subdriver\n");
4933
4934 TPACPI_ACPIHANDLE_INIT(cmos);
4935
4936 vdbg_printk(TPACPI_DBG_INIT, "cmos commands are %s\n",
4937 str_supported(cmos_handle != NULL));
4938
4939 res = device_create_file(&tpacpi_pdev->dev, &dev_attr_cmos_command);
4940 if (res)
4941 return res;
4942
4943 return (cmos_handle)? 0 : 1;
4944}
4945
4946static void cmos_exit(void)
4947{
4948 device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command);
4949}
4950
4951static int cmos_read(struct seq_file *m)
4952{
4953
4954
4955 if (!cmos_handle)
4956 seq_printf(m, "status:\t\tnot supported\n");
4957 else {
4958 seq_printf(m, "status:\t\tsupported\n");
4959 seq_printf(m, "commands:\t<cmd> (<cmd> is 0-21)\n");
4960 }
4961
4962 return 0;
4963}
4964
4965static int cmos_write(char *buf)
4966{
4967 char *cmd;
4968 int cmos_cmd, res;
4969
4970 while ((cmd = next_cmd(&buf))) {
4971 if (sscanf(cmd, "%u", &cmos_cmd) == 1 &&
4972 cmos_cmd >= 0 && cmos_cmd <= 21) {
4973
4974 } else
4975 return -EINVAL;
4976
4977 res = issue_thinkpad_cmos_command(cmos_cmd);
4978 if (res)
4979 return res;
4980 }
4981
4982 return 0;
4983}
4984
4985static struct ibm_struct cmos_driver_data = {
4986 .name = "cmos",
4987 .read = cmos_read,
4988 .write = cmos_write,
4989 .exit = cmos_exit,
4990};
4991
4992
4993
4994
4995
4996enum led_access_mode {
4997 TPACPI_LED_NONE = 0,
4998 TPACPI_LED_570,
4999 TPACPI_LED_OLD,
5000 TPACPI_LED_NEW,
5001};
5002
5003enum {
5004 TPACPI_LED_EC_HLCL = 0x0c,
5005 TPACPI_LED_EC_HLBL = 0x0d,
5006 TPACPI_LED_EC_HLMS = 0x0e,
5007};
5008
5009static enum led_access_mode led_supported;
5010
5011static acpi_handle led_handle;
5012
5013#define TPACPI_LED_NUMLEDS 16
5014static struct tpacpi_led_classdev *tpacpi_leds;
5015static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS];
5016static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = {
5017
5018 "tpacpi::power",
5019 "tpacpi:orange:batt",
5020 "tpacpi:green:batt",
5021 "tpacpi::dock_active",
5022 "tpacpi::bay_active",
5023 "tpacpi::dock_batt",
5024 "tpacpi::unknown_led",
5025 "tpacpi::standby",
5026 "tpacpi::dock_status1",
5027 "tpacpi::dock_status2",
5028 "tpacpi::unknown_led2",
5029 "tpacpi::unknown_led3",
5030 "tpacpi::thinkvantage",
5031};
5032#define TPACPI_SAFE_LEDS 0x1081U
5033
5034static inline bool tpacpi_is_led_restricted(const unsigned int led)
5035{
5036#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
5037 return false;
5038#else
5039 return (1U & (TPACPI_SAFE_LEDS >> led)) == 0;
5040#endif
5041}
5042
5043static int led_get_status(const unsigned int led)
5044{
5045 int status;
5046 enum led_status_t led_s;
5047
5048 switch (led_supported) {
5049 case TPACPI_LED_570:
5050 if (!acpi_evalf(ec_handle,
5051 &status, "GLED", "dd", 1 << led))
5052 return -EIO;
5053 led_s = (status == 0)?
5054 TPACPI_LED_OFF :
5055 ((status == 1)?
5056 TPACPI_LED_ON :
5057 TPACPI_LED_BLINK);
5058 tpacpi_led_state_cache[led] = led_s;
5059 return led_s;
5060 default:
5061 return -ENXIO;
5062 }
5063
5064
5065}
5066
5067static int led_set_status(const unsigned int led,
5068 const enum led_status_t ledstatus)
5069{
5070
5071 static const unsigned int led_sled_arg1[] = { 0, 1, 3 };
5072 static const unsigned int led_led_arg1[] = { 0, 0x80, 0xc0 };
5073
5074 int rc = 0;
5075
5076 switch (led_supported) {
5077 case TPACPI_LED_570:
5078
5079 if (unlikely(led > 7))
5080 return -EINVAL;
5081 if (unlikely(tpacpi_is_led_restricted(led)))
5082 return -EPERM;
5083 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
5084 (1 << led), led_sled_arg1[ledstatus]))
5085 rc = -EIO;
5086 break;
5087 case TPACPI_LED_OLD:
5088
5089 if (unlikely(led > 7))
5090 return -EINVAL;
5091 if (unlikely(tpacpi_is_led_restricted(led)))
5092 return -EPERM;
5093 rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led));
5094 if (rc >= 0)
5095 rc = ec_write(TPACPI_LED_EC_HLBL,
5096 (ledstatus == TPACPI_LED_BLINK) << led);
5097 if (rc >= 0)
5098 rc = ec_write(TPACPI_LED_EC_HLCL,
5099 (ledstatus != TPACPI_LED_OFF) << led);
5100 break;
5101 case TPACPI_LED_NEW:
5102
5103 if (unlikely(led >= TPACPI_LED_NUMLEDS))
5104 return -EINVAL;
5105 if (unlikely(tpacpi_is_led_restricted(led)))
5106 return -EPERM;
5107 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
5108 led, led_led_arg1[ledstatus]))
5109 rc = -EIO;
5110 break;
5111 default:
5112 rc = -ENXIO;
5113 }
5114
5115 if (!rc)
5116 tpacpi_led_state_cache[led] = ledstatus;
5117
5118 return rc;
5119}
5120
5121static void led_set_status_worker(struct work_struct *work)
5122{
5123 struct tpacpi_led_classdev *data =
5124 container_of(work, struct tpacpi_led_classdev, work);
5125
5126 if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
5127 led_set_status(data->led, data->new_state);
5128}
5129
5130static void led_sysfs_set(struct led_classdev *led_cdev,
5131 enum led_brightness brightness)
5132{
5133 struct tpacpi_led_classdev *data = container_of(led_cdev,
5134 struct tpacpi_led_classdev, led_classdev);
5135
5136 if (brightness == LED_OFF)
5137 data->new_state = TPACPI_LED_OFF;
5138 else if (tpacpi_led_state_cache[data->led] != TPACPI_LED_BLINK)
5139 data->new_state = TPACPI_LED_ON;
5140 else
5141 data->new_state = TPACPI_LED_BLINK;
5142
5143 queue_work(tpacpi_wq, &data->work);
5144}
5145
5146static int led_sysfs_blink_set(struct led_classdev *led_cdev,
5147 unsigned long *delay_on, unsigned long *delay_off)
5148{
5149 struct tpacpi_led_classdev *data = container_of(led_cdev,
5150 struct tpacpi_led_classdev, led_classdev);
5151
5152
5153 if (*delay_on == 0 && *delay_off == 0) {
5154
5155 *delay_on = 500;
5156 *delay_off = 500;
5157 } else if ((*delay_on != 500) || (*delay_off != 500))
5158 return -EINVAL;
5159
5160 data->new_state = TPACPI_LED_BLINK;
5161 queue_work(tpacpi_wq, &data->work);
5162
5163 return 0;
5164}
5165
5166static enum led_brightness led_sysfs_get(struct led_classdev *led_cdev)
5167{
5168 int rc;
5169
5170 struct tpacpi_led_classdev *data = container_of(led_cdev,
5171 struct tpacpi_led_classdev, led_classdev);
5172
5173 rc = led_get_status(data->led);
5174
5175 if (rc == TPACPI_LED_OFF || rc < 0)
5176 rc = LED_OFF;
5177 else
5178 rc = LED_FULL;
5179
5180 return rc;
5181}
5182
5183static void led_exit(void)
5184{
5185 unsigned int i;
5186
5187 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
5188 if (tpacpi_leds[i].led_classdev.name)
5189 led_classdev_unregister(&tpacpi_leds[i].led_classdev);
5190 }
5191
5192 flush_workqueue(tpacpi_wq);
5193 kfree(tpacpi_leds);
5194}
5195
5196static int __init tpacpi_init_led(unsigned int led)
5197{
5198 int rc;
5199
5200 tpacpi_leds[led].led = led;
5201
5202
5203 if (!tpacpi_led_names[led])
5204 return 0;
5205
5206 tpacpi_leds[led].led_classdev.brightness_set = &led_sysfs_set;
5207 tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set;
5208 if (led_supported == TPACPI_LED_570)
5209 tpacpi_leds[led].led_classdev.brightness_get =
5210 &led_sysfs_get;
5211
5212 tpacpi_leds[led].led_classdev.name = tpacpi_led_names[led];
5213
5214 INIT_WORK(&tpacpi_leds[led].work, led_set_status_worker);
5215
5216 rc = led_classdev_register(&tpacpi_pdev->dev,
5217 &tpacpi_leds[led].led_classdev);
5218 if (rc < 0)
5219 tpacpi_leds[led].led_classdev.name = NULL;
5220
5221 return rc;
5222}
5223
5224static const struct tpacpi_quirk led_useful_qtable[] __initconst = {
5225 TPACPI_Q_IBM('1', 'E', 0x009f),
5226 TPACPI_Q_IBM('1', 'N', 0x009f),
5227 TPACPI_Q_IBM('1', 'G', 0x009f),
5228
5229 TPACPI_Q_IBM('1', 'I', 0x0097),
5230 TPACPI_Q_IBM('1', 'R', 0x0097),
5231 TPACPI_Q_IBM('7', '0', 0x0097),
5232 TPACPI_Q_IBM('1', 'Y', 0x0097),
5233 TPACPI_Q_IBM('1', 'W', 0x0097),
5234 TPACPI_Q_IBM('1', 'V', 0x0097),
5235 TPACPI_Q_IBM('7', '8', 0x0097),
5236 TPACPI_Q_IBM('7', '6', 0x0097),
5237
5238 TPACPI_Q_IBM('1', 'K', 0x00bf),
5239 TPACPI_Q_IBM('1', 'Q', 0x00bf),
5240 TPACPI_Q_IBM('1', 'U', 0x00bf),
5241 TPACPI_Q_IBM('7', '4', 0x00bf),
5242 TPACPI_Q_IBM('7', '5', 0x00bf),
5243
5244 TPACPI_Q_IBM('7', '9', 0x1f97),
5245 TPACPI_Q_IBM('7', '7', 0x1f97),
5246 TPACPI_Q_IBM('7', 'F', 0x1f97),
5247 TPACPI_Q_IBM('7', 'B', 0x1fb7),
5248
5249
5250
5251
5252 {
5253 .vendor = PCI_VENDOR_ID_LENOVO,
5254 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
5255 .quirks = 0x1fffU,
5256 },
5257 {
5258 .vendor = PCI_VENDOR_ID_IBM,
5259 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_UNKNOWN,
5260 .quirks = 0x00ffU,
5261 },
5262 {
5263 .vendor = PCI_VENDOR_ID_IBM,
5264 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
5265 .quirks = 0x00bfU,
5266 },
5267};
5268
5269#undef TPACPI_LEDQ_IBM
5270#undef TPACPI_LEDQ_LNV
5271
5272static enum led_access_mode __init led_init_detect_mode(void)
5273{
5274 acpi_status status;
5275
5276 if (tpacpi_is_ibm()) {
5277
5278 status = acpi_get_handle(ec_handle, "SLED", &led_handle);
5279 if (ACPI_SUCCESS(status))
5280 return TPACPI_LED_570;
5281
5282
5283 status = acpi_get_handle(ec_handle, "SYSL", &led_handle);
5284 if (ACPI_SUCCESS(status))
5285 return TPACPI_LED_OLD;
5286 }
5287
5288
5289 status = acpi_get_handle(ec_handle, "LED", &led_handle);
5290 if (ACPI_SUCCESS(status))
5291 return TPACPI_LED_NEW;
5292
5293
5294 led_handle = NULL;
5295 return TPACPI_LED_NONE;
5296}
5297
5298static int __init led_init(struct ibm_init_struct *iibm)
5299{
5300 unsigned int i;
5301 int rc;
5302 unsigned long useful_leds;
5303
5304 vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
5305
5306 led_supported = led_init_detect_mode();
5307
5308 if (led_supported != TPACPI_LED_NONE) {
5309 useful_leds = tpacpi_check_quirks(led_useful_qtable,
5310 ARRAY_SIZE(led_useful_qtable));
5311
5312 if (!useful_leds) {
5313 led_handle = NULL;
5314 led_supported = TPACPI_LED_NONE;
5315 }
5316 }
5317
5318 vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n",
5319 str_supported(led_supported), led_supported);
5320
5321 if (led_supported == TPACPI_LED_NONE)
5322 return 1;
5323
5324 tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS,
5325 GFP_KERNEL);
5326 if (!tpacpi_leds) {
5327 pr_err("Out of memory for LED data\n");
5328 return -ENOMEM;
5329 }
5330
5331 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
5332 tpacpi_leds[i].led = -1;
5333
5334 if (!tpacpi_is_led_restricted(i) &&
5335 test_bit(i, &useful_leds)) {
5336 rc = tpacpi_init_led(i);
5337 if (rc < 0) {
5338 led_exit();
5339 return rc;
5340 }
5341 }
5342 }
5343
5344#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
5345 pr_notice("warning: userspace override of important "
5346 "firmware LEDs is enabled\n");
5347#endif
5348 return 0;
5349}
5350
5351#define str_led_status(s) \
5352 ((s) == TPACPI_LED_OFF ? "off" : \
5353 ((s) == TPACPI_LED_ON ? "on" : "blinking"))
5354
5355static int led_read(struct seq_file *m)
5356{
5357 if (!led_supported) {
5358 seq_printf(m, "status:\t\tnot supported\n");
5359 return 0;
5360 }
5361 seq_printf(m, "status:\t\tsupported\n");
5362
5363 if (led_supported == TPACPI_LED_570) {
5364
5365 int i, status;
5366 for (i = 0; i < 8; i++) {
5367 status = led_get_status(i);
5368 if (status < 0)
5369 return -EIO;
5370 seq_printf(m, "%d:\t\t%s\n",
5371 i, str_led_status(status));
5372 }
5373 }
5374
5375 seq_printf(m, "commands:\t"
5376 "<led> on, <led> off, <led> blink (<led> is 0-15)\n");
5377
5378 return 0;
5379}
5380
5381static int led_write(char *buf)
5382{
5383 char *cmd;
5384 int led, rc;
5385 enum led_status_t s;
5386
5387 if (!led_supported)
5388 return -ENODEV;
5389
5390 while ((cmd = next_cmd(&buf))) {
5391 if (sscanf(cmd, "%d", &led) != 1)
5392 return -EINVAL;
5393
5394 if (led < 0 || led > (TPACPI_LED_NUMLEDS - 1) ||
5395 tpacpi_leds[led].led < 0)
5396 return -ENODEV;
5397
5398 if (strstr(cmd, "off")) {
5399 s = TPACPI_LED_OFF;
5400 } else if (strstr(cmd, "on")) {
5401 s = TPACPI_LED_ON;
5402 } else if (strstr(cmd, "blink")) {
5403 s = TPACPI_LED_BLINK;
5404 } else {
5405 return -EINVAL;
5406 }
5407
5408 rc = led_set_status(led, s);
5409 if (rc < 0)
5410 return rc;
5411 }
5412
5413 return 0;
5414}
5415
5416static struct ibm_struct led_driver_data = {
5417 .name = "led",
5418 .read = led_read,
5419 .write = led_write,
5420 .exit = led_exit,
5421};
5422
5423
5424
5425
5426
5427TPACPI_HANDLE(beep, ec, "BEEP");
5428
5429#define TPACPI_BEEP_Q1 0x0001
5430
5431static const struct tpacpi_quirk beep_quirk_table[] __initconst = {
5432 TPACPI_Q_IBM('I', 'M', TPACPI_BEEP_Q1),
5433 TPACPI_Q_IBM('I', 'U', TPACPI_BEEP_Q1),
5434};
5435
5436static int __init beep_init(struct ibm_init_struct *iibm)
5437{
5438 unsigned long quirks;
5439
5440 vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n");
5441
5442 TPACPI_ACPIHANDLE_INIT(beep);
5443
5444 vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n",
5445 str_supported(beep_handle != NULL));
5446
5447 quirks = tpacpi_check_quirks(beep_quirk_table,
5448 ARRAY_SIZE(beep_quirk_table));
5449
5450 tp_features.beep_needs_two_args = !!(quirks & TPACPI_BEEP_Q1);
5451
5452 return (beep_handle)? 0 : 1;
5453}
5454
5455static int beep_read(struct seq_file *m)
5456{
5457 if (!beep_handle)
5458 seq_printf(m, "status:\t\tnot supported\n");
5459 else {
5460 seq_printf(m, "status:\t\tsupported\n");
5461 seq_printf(m, "commands:\t<cmd> (<cmd> is 0-17)\n");
5462 }
5463
5464 return 0;
5465}
5466
5467static int beep_write(char *buf)
5468{
5469 char *cmd;
5470 int beep_cmd;
5471
5472 if (!beep_handle)
5473 return -ENODEV;
5474
5475 while ((cmd = next_cmd(&buf))) {
5476 if (sscanf(cmd, "%u", &beep_cmd) == 1 &&
5477 beep_cmd >= 0 && beep_cmd <= 17) {
5478
5479 } else
5480 return -EINVAL;
5481 if (tp_features.beep_needs_two_args) {
5482 if (!acpi_evalf(beep_handle, NULL, NULL, "vdd",
5483 beep_cmd, 0))
5484 return -EIO;
5485 } else {
5486 if (!acpi_evalf(beep_handle, NULL, NULL, "vd",
5487 beep_cmd))
5488 return -EIO;
5489 }
5490 }
5491
5492 return 0;
5493}
5494
5495static struct ibm_struct beep_driver_data = {
5496 .name = "beep",
5497 .read = beep_read,
5498 .write = beep_write,
5499};
5500
5501
5502
5503
5504
5505enum thermal_access_mode {
5506 TPACPI_THERMAL_NONE = 0,
5507 TPACPI_THERMAL_ACPI_TMP07,
5508 TPACPI_THERMAL_ACPI_UPDT,
5509 TPACPI_THERMAL_TPEC_8,
5510 TPACPI_THERMAL_TPEC_16,
5511};
5512
5513enum {
5514 TP_EC_THERMAL_TMP0 = 0x78,
5515 TP_EC_THERMAL_TMP8 = 0xC0,
5516 TP_EC_THERMAL_TMP_NA = -128,
5517
5518 TPACPI_THERMAL_SENSOR_NA = -128000,
5519};
5520
5521
5522#define TPACPI_MAX_THERMAL_SENSORS 16
5523struct ibm_thermal_sensors_struct {
5524 s32 temp[TPACPI_MAX_THERMAL_SENSORS];
5525};
5526
5527static enum thermal_access_mode thermal_read_mode;
5528
5529
5530static int thermal_get_sensor(int idx, s32 *value)
5531{
5532 int t;
5533 s8 tmp;
5534 char tmpi[5];
5535
5536 t = TP_EC_THERMAL_TMP0;
5537
5538 switch (thermal_read_mode) {
5539#if TPACPI_MAX_THERMAL_SENSORS >= 16
5540 case TPACPI_THERMAL_TPEC_16:
5541 if (idx >= 8 && idx <= 15) {
5542 t = TP_EC_THERMAL_TMP8;
5543 idx -= 8;
5544 }
5545
5546#endif
5547 case TPACPI_THERMAL_TPEC_8:
5548 if (idx <= 7) {
5549 if (!acpi_ec_read(t + idx, &tmp))
5550 return -EIO;
5551 *value = tmp * 1000;
5552 return 0;
5553 }
5554 break;
5555
5556 case TPACPI_THERMAL_ACPI_UPDT:
5557 if (idx <= 7) {
5558 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
5559 if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
5560 return -EIO;
5561 if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
5562 return -EIO;
5563 *value = (t - 2732) * 100;
5564 return 0;
5565 }
5566 break;
5567
5568 case TPACPI_THERMAL_ACPI_TMP07:
5569 if (idx <= 7) {
5570 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
5571 if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
5572 return -EIO;
5573 if (t > 127 || t < -127)
5574 t = TP_EC_THERMAL_TMP_NA;
5575 *value = t * 1000;
5576 return 0;
5577 }
5578 break;
5579
5580 case TPACPI_THERMAL_NONE:
5581 default:
5582 return -ENOSYS;
5583 }
5584
5585 return -EINVAL;
5586}
5587
5588static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
5589{
5590 int res, i;
5591 int n;
5592
5593 n = 8;
5594 i = 0;
5595
5596 if (!s)
5597 return -EINVAL;
5598
5599 if (thermal_read_mode == TPACPI_THERMAL_TPEC_16)
5600 n = 16;
5601
5602 for (i = 0 ; i < n; i++) {
5603 res = thermal_get_sensor(i, &s->temp[i]);
5604 if (res)
5605 return res;
5606 }
5607
5608 return n;
5609}
5610
5611static void thermal_dump_all_sensors(void)
5612{
5613 int n, i;
5614 struct ibm_thermal_sensors_struct t;
5615
5616 n = thermal_get_sensors(&t);
5617 if (n <= 0)
5618 return;
5619
5620 pr_notice("temperatures (Celsius):");
5621
5622 for (i = 0; i < n; i++) {
5623 if (t.temp[i] != TPACPI_THERMAL_SENSOR_NA)
5624 pr_cont(" %d", (int)(t.temp[i] / 1000));
5625 else
5626 pr_cont(" N/A");
5627 }
5628
5629 pr_cont("\n");
5630}
5631
5632
5633
5634static ssize_t thermal_temp_input_show(struct device *dev,
5635 struct device_attribute *attr,
5636 char *buf)
5637{
5638 struct sensor_device_attribute *sensor_attr =
5639 to_sensor_dev_attr(attr);
5640 int idx = sensor_attr->index;
5641 s32 value;
5642 int res;
5643
5644 res = thermal_get_sensor(idx, &value);
5645 if (res)
5646 return res;
5647 if (value == TPACPI_THERMAL_SENSOR_NA)
5648 return -ENXIO;
5649
5650 return snprintf(buf, PAGE_SIZE, "%d\n", value);
5651}
5652
5653#define THERMAL_SENSOR_ATTR_TEMP(_idxA, _idxB) \
5654 SENSOR_ATTR(temp##_idxA##_input, S_IRUGO, \
5655 thermal_temp_input_show, NULL, _idxB)
5656
5657static struct sensor_device_attribute sensor_dev_attr_thermal_temp_input[] = {
5658 THERMAL_SENSOR_ATTR_TEMP(1, 0),
5659 THERMAL_SENSOR_ATTR_TEMP(2, 1),
5660 THERMAL_SENSOR_ATTR_TEMP(3, 2),
5661 THERMAL_SENSOR_ATTR_TEMP(4, 3),
5662 THERMAL_SENSOR_ATTR_TEMP(5, 4),
5663 THERMAL_SENSOR_ATTR_TEMP(6, 5),
5664 THERMAL_SENSOR_ATTR_TEMP(7, 6),
5665 THERMAL_SENSOR_ATTR_TEMP(8, 7),
5666 THERMAL_SENSOR_ATTR_TEMP(9, 8),
5667 THERMAL_SENSOR_ATTR_TEMP(10, 9),
5668 THERMAL_SENSOR_ATTR_TEMP(11, 10),
5669 THERMAL_SENSOR_ATTR_TEMP(12, 11),
5670 THERMAL_SENSOR_ATTR_TEMP(13, 12),
5671 THERMAL_SENSOR_ATTR_TEMP(14, 13),
5672 THERMAL_SENSOR_ATTR_TEMP(15, 14),
5673 THERMAL_SENSOR_ATTR_TEMP(16, 15),
5674};
5675
5676#define THERMAL_ATTRS(X) \
5677 &sensor_dev_attr_thermal_temp_input[X].dev_attr.attr
5678
5679static struct attribute *thermal_temp_input_attr[] = {
5680 THERMAL_ATTRS(8),
5681 THERMAL_ATTRS(9),
5682 THERMAL_ATTRS(10),
5683 THERMAL_ATTRS(11),
5684 THERMAL_ATTRS(12),
5685 THERMAL_ATTRS(13),
5686 THERMAL_ATTRS(14),
5687 THERMAL_ATTRS(15),
5688 THERMAL_ATTRS(0),
5689 THERMAL_ATTRS(1),
5690 THERMAL_ATTRS(2),
5691 THERMAL_ATTRS(3),
5692 THERMAL_ATTRS(4),
5693 THERMAL_ATTRS(5),
5694 THERMAL_ATTRS(6),
5695 THERMAL_ATTRS(7),
5696 NULL
5697};
5698
5699static const struct attribute_group thermal_temp_input16_group = {
5700 .attrs = thermal_temp_input_attr
5701};
5702
5703static const struct attribute_group thermal_temp_input8_group = {
5704 .attrs = &thermal_temp_input_attr[8]
5705};
5706
5707#undef THERMAL_SENSOR_ATTR_TEMP
5708#undef THERMAL_ATTRS
5709
5710
5711
5712static int __init thermal_init(struct ibm_init_struct *iibm)
5713{
5714 u8 t, ta1, ta2;
5715 int i;
5716 int acpi_tmp7;
5717 int res;
5718
5719 vdbg_printk(TPACPI_DBG_INIT, "initializing thermal subdriver\n");
5720
5721 acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
5722
5723 if (thinkpad_id.ec_model) {
5724
5725
5726
5727
5728
5729
5730
5731 ta1 = ta2 = 0;
5732 for (i = 0; i < 8; i++) {
5733 if (acpi_ec_read(TP_EC_THERMAL_TMP0 + i, &t)) {
5734 ta1 |= t;
5735 } else {
5736 ta1 = 0;
5737 break;
5738 }
5739 if (acpi_ec_read(TP_EC_THERMAL_TMP8 + i, &t)) {
5740 ta2 |= t;
5741 } else {
5742 ta1 = 0;
5743 break;
5744 }
5745 }
5746 if (ta1 == 0) {
5747
5748 if (acpi_tmp7) {
5749 pr_err("ThinkPad ACPI EC access misbehaving, "
5750 "falling back to ACPI TMPx access "
5751 "mode\n");
5752 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;
5753 } else {
5754 pr_err("ThinkPad ACPI EC access misbehaving, "
5755 "disabling thermal sensors access\n");
5756 thermal_read_mode = TPACPI_THERMAL_NONE;
5757 }
5758 } else {
5759 thermal_read_mode =
5760 (ta2 != 0) ?
5761 TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8;
5762 }
5763 } else if (acpi_tmp7) {
5764 if (tpacpi_is_ibm() &&
5765 acpi_evalf(ec_handle, NULL, "UPDT", "qv")) {
5766
5767 thermal_read_mode = TPACPI_THERMAL_ACPI_UPDT;
5768 } else {
5769
5770 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;
5771 }
5772 } else {
5773
5774 thermal_read_mode = TPACPI_THERMAL_NONE;
5775 }
5776
5777 vdbg_printk(TPACPI_DBG_INIT, "thermal is %s, mode %d\n",
5778 str_supported(thermal_read_mode != TPACPI_THERMAL_NONE),
5779 thermal_read_mode);
5780
5781 switch (thermal_read_mode) {
5782 case TPACPI_THERMAL_TPEC_16:
5783 res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
5784 &thermal_temp_input16_group);
5785 if (res)
5786 return res;
5787 break;
5788 case TPACPI_THERMAL_TPEC_8:
5789 case TPACPI_THERMAL_ACPI_TMP07:
5790 case TPACPI_THERMAL_ACPI_UPDT:
5791 res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
5792 &thermal_temp_input8_group);
5793 if (res)
5794 return res;
5795 break;
5796 case TPACPI_THERMAL_NONE:
5797 default:
5798 return 1;
5799 }
5800
5801 return 0;
5802}
5803
5804static void thermal_exit(void)
5805{
5806 switch (thermal_read_mode) {
5807 case TPACPI_THERMAL_TPEC_16:
5808 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
5809 &thermal_temp_input16_group);
5810 break;
5811 case TPACPI_THERMAL_TPEC_8:
5812 case TPACPI_THERMAL_ACPI_TMP07:
5813 case TPACPI_THERMAL_ACPI_UPDT:
5814 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
5815 &thermal_temp_input8_group);
5816 break;
5817 case TPACPI_THERMAL_NONE:
5818 default:
5819 break;
5820 }
5821}
5822
5823static int thermal_read(struct seq_file *m)
5824{
5825 int n, i;
5826 struct ibm_thermal_sensors_struct t;
5827
5828 n = thermal_get_sensors(&t);
5829 if (unlikely(n < 0))
5830 return n;
5831
5832 seq_printf(m, "temperatures:\t");
5833
5834 if (n > 0) {
5835 for (i = 0; i < (n - 1); i++)
5836 seq_printf(m, "%d ", t.temp[i] / 1000);
5837 seq_printf(m, "%d\n", t.temp[i] / 1000);
5838 } else
5839 seq_printf(m, "not supported\n");
5840
5841 return 0;
5842}
5843
5844static struct ibm_struct thermal_driver_data = {
5845 .name = "thermal",
5846 .read = thermal_read,
5847 .exit = thermal_exit,
5848};
5849
5850
5851
5852
5853
5854#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874enum {
5875 TP_EC_BACKLIGHT = 0x31,
5876
5877
5878 TP_EC_BACKLIGHT_LVLMSK = 0x1F,
5879 TP_EC_BACKLIGHT_CMDMSK = 0xE0,
5880 TP_EC_BACKLIGHT_MAPSW = 0x20,
5881};
5882
5883enum tpacpi_brightness_access_mode {
5884 TPACPI_BRGHT_MODE_AUTO = 0,
5885 TPACPI_BRGHT_MODE_EC,
5886 TPACPI_BRGHT_MODE_UCMS_STEP,
5887 TPACPI_BRGHT_MODE_ECNVRAM,
5888 TPACPI_BRGHT_MODE_MAX
5889};
5890
5891static struct backlight_device *ibm_backlight_device;
5892
5893static enum tpacpi_brightness_access_mode brightness_mode =
5894 TPACPI_BRGHT_MODE_MAX;
5895
5896static unsigned int brightness_enable = 2;
5897
5898static struct mutex brightness_mutex;
5899
5900
5901
5902static unsigned int tpacpi_brightness_nvram_get(void)
5903{
5904 u8 lnvram;
5905
5906 lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
5907 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
5908 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
5909 lnvram &= bright_maxlvl;
5910
5911 return lnvram;
5912}
5913
5914static void tpacpi_brightness_checkpoint_nvram(void)
5915{
5916 u8 lec = 0;
5917 u8 b_nvram;
5918
5919 if (brightness_mode != TPACPI_BRGHT_MODE_ECNVRAM)
5920 return;
5921
5922 vdbg_printk(TPACPI_DBG_BRGHT,
5923 "trying to checkpoint backlight level to NVRAM...\n");
5924
5925 if (mutex_lock_killable(&brightness_mutex) < 0)
5926 return;
5927
5928 if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
5929 goto unlock;
5930 lec &= TP_EC_BACKLIGHT_LVLMSK;
5931 b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
5932
5933 if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
5934 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {
5935
5936 b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<
5937 TP_NVRAM_POS_LEVEL_BRIGHTNESS);
5938 b_nvram |= lec;
5939 nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
5940 dbg_printk(TPACPI_DBG_BRGHT,
5941 "updated NVRAM backlight level to %u (0x%02x)\n",
5942 (unsigned int) lec, (unsigned int) b_nvram);
5943 } else
5944 vdbg_printk(TPACPI_DBG_BRGHT,
5945 "NVRAM backlight level already is %u (0x%02x)\n",
5946 (unsigned int) lec, (unsigned int) b_nvram);
5947
5948unlock:
5949 mutex_unlock(&brightness_mutex);
5950}
5951
5952
5953
5954static int tpacpi_brightness_get_raw(int *status)
5955{
5956 u8 lec = 0;
5957
5958 switch (brightness_mode) {
5959 case TPACPI_BRGHT_MODE_UCMS_STEP:
5960 *status = tpacpi_brightness_nvram_get();
5961 return 0;
5962 case TPACPI_BRGHT_MODE_EC:
5963 case TPACPI_BRGHT_MODE_ECNVRAM:
5964 if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
5965 return -EIO;
5966 *status = lec;
5967 return 0;
5968 default:
5969 return -ENXIO;
5970 }
5971}
5972
5973
5974
5975static int tpacpi_brightness_set_ec(unsigned int value)
5976{
5977 u8 lec = 0;
5978
5979 if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
5980 return -EIO;
5981
5982 if (unlikely(!acpi_ec_write(TP_EC_BACKLIGHT,
5983 (lec & TP_EC_BACKLIGHT_CMDMSK) |
5984 (value & TP_EC_BACKLIGHT_LVLMSK))))
5985 return -EIO;
5986
5987 return 0;
5988}
5989
5990
5991static int tpacpi_brightness_set_ucmsstep(unsigned int value)
5992{
5993 int cmos_cmd, inc;
5994 unsigned int current_value, i;
5995
5996 current_value = tpacpi_brightness_nvram_get();
5997
5998 if (value == current_value)
5999 return 0;
6000
6001 cmos_cmd = (value > current_value) ?
6002 TP_CMOS_BRIGHTNESS_UP :
6003 TP_CMOS_BRIGHTNESS_DOWN;
6004 inc = (value > current_value) ? 1 : -1;
6005
6006 for (i = current_value; i != value; i += inc)
6007 if (issue_thinkpad_cmos_command(cmos_cmd))
6008 return -EIO;
6009
6010 return 0;
6011}
6012
6013
6014static int brightness_set(unsigned int value)
6015{
6016 int res;
6017
6018 if (value > bright_maxlvl || value < 0)
6019 return -EINVAL;
6020
6021 vdbg_printk(TPACPI_DBG_BRGHT,
6022 "set backlight level to %d\n", value);
6023
6024 res = mutex_lock_killable(&brightness_mutex);
6025 if (res < 0)
6026 return res;
6027
6028 switch (brightness_mode) {
6029 case TPACPI_BRGHT_MODE_EC:
6030 case TPACPI_BRGHT_MODE_ECNVRAM:
6031 res = tpacpi_brightness_set_ec(value);
6032 break;
6033 case TPACPI_BRGHT_MODE_UCMS_STEP:
6034 res = tpacpi_brightness_set_ucmsstep(value);
6035 break;
6036 default:
6037 res = -ENXIO;
6038 }
6039
6040 mutex_unlock(&brightness_mutex);
6041 return res;
6042}
6043
6044
6045
6046static int brightness_update_status(struct backlight_device *bd)
6047{
6048 unsigned int level =
6049 (bd->props.fb_blank == FB_BLANK_UNBLANK &&
6050 bd->props.power == FB_BLANK_UNBLANK) ?
6051 bd->props.brightness : 0;
6052
6053 dbg_printk(TPACPI_DBG_BRGHT,
6054 "backlight: attempt to set level to %d\n",
6055 level);
6056
6057
6058
6059 return brightness_set(level);
6060}
6061
6062static int brightness_get(struct backlight_device *bd)
6063{
6064 int status, res;
6065
6066 res = mutex_lock_killable(&brightness_mutex);
6067 if (res < 0)
6068 return 0;
6069
6070 res = tpacpi_brightness_get_raw(&status);
6071
6072 mutex_unlock(&brightness_mutex);
6073
6074 if (res < 0)
6075 return 0;
6076
6077 return status & TP_EC_BACKLIGHT_LVLMSK;
6078}
6079
6080static void tpacpi_brightness_notify_change(void)
6081{
6082 backlight_force_update(ibm_backlight_device,
6083 BACKLIGHT_UPDATE_HOTKEY);
6084}
6085
6086static const struct backlight_ops ibm_backlight_data = {
6087 .get_brightness = brightness_get,
6088 .update_status = brightness_update_status,
6089};
6090
6091
6092
6093
6094
6095
6096
6097
6098static int __init tpacpi_query_bcl_levels(acpi_handle handle)
6099{
6100 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
6101 union acpi_object *obj;
6102 struct acpi_device *device, *child;
6103 int rc;
6104
6105 if (acpi_bus_get_device(handle, &device))
6106 return 0;
6107
6108 rc = 0;
6109 list_for_each_entry(child, &device->children, node) {
6110 acpi_status status = acpi_evaluate_object(child->handle, "_BCL",
6111 NULL, &buffer);
6112 if (ACPI_FAILURE(status))
6113 continue;
6114
6115 obj = (union acpi_object *)buffer.pointer;
6116 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
6117 pr_err("Unknown _BCL data, please report this to %s\n",
6118 TPACPI_MAIL);
6119 rc = 0;
6120 } else {
6121 rc = obj->package.count;
6122 }
6123 break;
6124 }
6125
6126 kfree(buffer.pointer);
6127 return rc;
6128}
6129
6130
6131
6132
6133
6134static unsigned int __init tpacpi_check_std_acpi_brightness_support(void)
6135{
6136 acpi_handle video_device;
6137 int bcl_levels = 0;
6138
6139 tpacpi_acpi_handle_locate("video", NULL, &video_device);
6140 if (video_device)
6141 bcl_levels = tpacpi_query_bcl_levels(video_device);
6142
6143 tp_features.bright_acpimode = (bcl_levels > 0);
6144
6145 return (bcl_levels > 2) ? (bcl_levels - 2) : 0;
6146}
6147
6148
6149
6150
6151
6152
6153#define TPACPI_BRGHT_Q_NOEC 0x0001
6154#define TPACPI_BRGHT_Q_EC 0x0002
6155#define TPACPI_BRGHT_Q_ASK 0x8000
6156
6157static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
6158
6159 TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC),
6160
6161
6162 TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC),
6163 TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
6164 TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_EC),
6165 TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
6166
6167
6168 TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC),
6169 TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
6170 TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
6171
6172
6173 TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC),
6174 TPACPI_Q_IBM('7', '4', TPACPI_BRGHT_Q_NOEC),
6175 TPACPI_Q_IBM('7', '5', TPACPI_BRGHT_Q_NOEC),
6176};
6177
6178
6179
6180
6181
6182static void __init tpacpi_detect_brightness_capabilities(void)
6183{
6184 unsigned int b;
6185
6186 vdbg_printk(TPACPI_DBG_INIT,
6187 "detecting firmware brightness interface capabilities\n");
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197 b = tpacpi_check_std_acpi_brightness_support();
6198 switch (b) {
6199 case 16:
6200 bright_maxlvl = 15;
6201 pr_info("detected a 16-level brightness capable ThinkPad\n");
6202 break;
6203 case 8:
6204 case 0:
6205 bright_maxlvl = 7;
6206 pr_info("detected a 8-level brightness capable ThinkPad\n");
6207 break;
6208 default:
6209 pr_err("Unsupported brightness interface, "
6210 "please contact %s\n", TPACPI_MAIL);
6211 tp_features.bright_unkfw = 1;
6212 bright_maxlvl = b - 1;
6213 }
6214}
6215
6216static int __init brightness_init(struct ibm_init_struct *iibm)
6217{
6218 struct backlight_properties props;
6219 int b;
6220 unsigned long quirks;
6221
6222 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
6223
6224 mutex_init(&brightness_mutex);
6225
6226 quirks = tpacpi_check_quirks(brightness_quirk_table,
6227 ARRAY_SIZE(brightness_quirk_table));
6228
6229
6230
6231
6232 if (tp_features.bright_unkfw)
6233 return 1;
6234
6235 if (!brightness_enable) {
6236 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
6237 "brightness support disabled by "
6238 "module parameter\n");
6239 return 1;
6240 }
6241
6242 if (acpi_video_backlight_support()) {
6243 if (brightness_enable > 1) {
6244 pr_info("Standard ACPI backlight interface "
6245 "available, not loading native one\n");
6246 return 1;
6247 } else if (brightness_enable == 1) {
6248 pr_warn("Cannot enable backlight brightness support, "
6249 "ACPI is already handling it. Refer to the "
6250 "acpi_backlight kernel parameter.\n");
6251 return 1;
6252 }
6253 } else if (tp_features.bright_acpimode && brightness_enable > 1) {
6254 pr_notice("Standard ACPI backlight interface not "
6255 "available, thinkpad_acpi native "
6256 "brightness control enabled\n");
6257 }
6258
6259
6260
6261
6262
6263
6264 if (brightness_mode > TPACPI_BRGHT_MODE_MAX)
6265 return -EINVAL;
6266
6267
6268 if (brightness_mode == TPACPI_BRGHT_MODE_AUTO ||
6269 brightness_mode == TPACPI_BRGHT_MODE_MAX) {
6270 if (quirks & TPACPI_BRGHT_Q_EC)
6271 brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
6272 else
6273 brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
6274
6275 dbg_printk(TPACPI_DBG_BRGHT,
6276 "driver auto-selected brightness_mode=%d\n",
6277 brightness_mode);
6278 }
6279
6280
6281 if (!tpacpi_is_ibm() &&
6282 (brightness_mode == TPACPI_BRGHT_MODE_ECNVRAM ||
6283 brightness_mode == TPACPI_BRGHT_MODE_EC))
6284 return -EINVAL;
6285
6286 if (tpacpi_brightness_get_raw(&b) < 0)
6287 return 1;
6288
6289 memset(&props, 0, sizeof(struct backlight_properties));
6290 props.type = BACKLIGHT_PLATFORM;
6291 props.max_brightness = bright_maxlvl;
6292 props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
6293 ibm_backlight_device = backlight_device_register(TPACPI_BACKLIGHT_DEV_NAME,
6294 NULL, NULL,
6295 &ibm_backlight_data,
6296 &props);
6297 if (IS_ERR(ibm_backlight_device)) {
6298 int rc = PTR_ERR(ibm_backlight_device);
6299 ibm_backlight_device = NULL;
6300 pr_err("Could not register backlight device\n");
6301 return rc;
6302 }
6303 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
6304 "brightness is supported\n");
6305
6306 if (quirks & TPACPI_BRGHT_Q_ASK) {
6307 pr_notice("brightness: will use unverified default: "
6308 "brightness_mode=%d\n", brightness_mode);
6309 pr_notice("brightness: please report to %s whether it works well "
6310 "or not on your ThinkPad\n", TPACPI_MAIL);
6311 }
6312
6313
6314
6315
6316
6317 backlight_update_status(ibm_backlight_device);
6318
6319 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
6320 "brightness: registering brightness hotkeys "
6321 "as change notification\n");
6322 tpacpi_hotkey_driver_mask_set(hotkey_driver_mask
6323 | TP_ACPI_HKEY_BRGHTUP_MASK
6324 | TP_ACPI_HKEY_BRGHTDWN_MASK);
6325 return 0;
6326}
6327
6328static void brightness_suspend(void)
6329{
6330 tpacpi_brightness_checkpoint_nvram();
6331}
6332
6333static void brightness_shutdown(void)
6334{
6335 tpacpi_brightness_checkpoint_nvram();
6336}
6337
6338static void brightness_exit(void)
6339{
6340 if (ibm_backlight_device) {
6341 vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_BRGHT,
6342 "calling backlight_device_unregister()\n");
6343 backlight_device_unregister(ibm_backlight_device);
6344 }
6345
6346 tpacpi_brightness_checkpoint_nvram();
6347}
6348
6349static int brightness_read(struct seq_file *m)
6350{
6351 int level;
6352
6353 level = brightness_get(NULL);
6354 if (level < 0) {
6355 seq_printf(m, "level:\t\tunreadable\n");
6356 } else {
6357 seq_printf(m, "level:\t\t%d\n", level);
6358 seq_printf(m, "commands:\tup, down\n");
6359 seq_printf(m, "commands:\tlevel <level> (<level> is 0-%d)\n",
6360 bright_maxlvl);
6361 }
6362
6363 return 0;
6364}
6365
6366static int brightness_write(char *buf)
6367{
6368 int level;
6369 int rc;
6370 char *cmd;
6371
6372 level = brightness_get(NULL);
6373 if (level < 0)
6374 return level;
6375
6376 while ((cmd = next_cmd(&buf))) {
6377 if (strlencmp(cmd, "up") == 0) {
6378 if (level < bright_maxlvl)
6379 level++;
6380 } else if (strlencmp(cmd, "down") == 0) {
6381 if (level > 0)
6382 level--;
6383 } else if (sscanf(cmd, "level %d", &level) == 1 &&
6384 level >= 0 && level <= bright_maxlvl) {
6385
6386 } else
6387 return -EINVAL;
6388 }
6389
6390 tpacpi_disclose_usertask("procfs brightness",
6391 "set level to %d\n", level);
6392
6393
6394
6395
6396
6397 rc = brightness_set(level);
6398 if (!rc && ibm_backlight_device)
6399 backlight_force_update(ibm_backlight_device,
6400 BACKLIGHT_UPDATE_SYSFS);
6401 return (rc == -EINTR)? -ERESTARTSYS : rc;
6402}
6403
6404static struct ibm_struct brightness_driver_data = {
6405 .name = "brightness",
6406 .read = brightness_read,
6407 .write = brightness_write,
6408 .exit = brightness_exit,
6409 .suspend = brightness_suspend,
6410 .shutdown = brightness_shutdown,
6411};
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT
6436
6437#define TPACPI_ALSA_DRVNAME "ThinkPad EC"
6438#define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control"
6439#define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME
6440
6441#if SNDRV_CARDS <= 32
6442#define DEFAULT_ALSA_IDX ~((1 << (SNDRV_CARDS - 3)) - 1)
6443#else
6444#define DEFAULT_ALSA_IDX ~((1 << (32 - 3)) - 1)
6445#endif
6446static int alsa_index = DEFAULT_ALSA_IDX;
6447static char *alsa_id = "ThinkPadEC";
6448static bool alsa_enable = SNDRV_DEFAULT_ENABLE1;
6449
6450struct tpacpi_alsa_data {
6451 struct snd_card *card;
6452 struct snd_ctl_elem_id *ctl_mute_id;
6453 struct snd_ctl_elem_id *ctl_vol_id;
6454};
6455
6456static struct snd_card *alsa_card;
6457
6458enum {
6459 TP_EC_AUDIO = 0x30,
6460
6461
6462 TP_EC_AUDIO_MUTESW = 6,
6463
6464
6465 TP_EC_AUDIO_LVL_MSK = 0x0F,
6466 TP_EC_AUDIO_MUTESW_MSK = (1 << TP_EC_AUDIO_MUTESW),
6467
6468
6469 TP_EC_VOLUME_MAX = 14,
6470};
6471
6472enum tpacpi_volume_access_mode {
6473 TPACPI_VOL_MODE_AUTO = 0,
6474 TPACPI_VOL_MODE_EC,
6475 TPACPI_VOL_MODE_UCMS_STEP,
6476 TPACPI_VOL_MODE_ECNVRAM,
6477 TPACPI_VOL_MODE_MAX
6478};
6479
6480enum tpacpi_volume_capabilities {
6481 TPACPI_VOL_CAP_AUTO = 0,
6482 TPACPI_VOL_CAP_VOLMUTE,
6483 TPACPI_VOL_CAP_MUTEONLY,
6484 TPACPI_VOL_CAP_MAX
6485};
6486
6487static enum tpacpi_volume_access_mode volume_mode =
6488 TPACPI_VOL_MODE_MAX;
6489
6490static enum tpacpi_volume_capabilities volume_capabilities;
6491static bool volume_control_allowed;
6492
6493
6494
6495
6496
6497static struct mutex volume_mutex;
6498
6499static void tpacpi_volume_checkpoint_nvram(void)
6500{
6501 u8 lec = 0;
6502 u8 b_nvram;
6503 u8 ec_mask;
6504
6505 if (volume_mode != TPACPI_VOL_MODE_ECNVRAM)
6506 return;
6507 if (!volume_control_allowed)
6508 return;
6509
6510 vdbg_printk(TPACPI_DBG_MIXER,
6511 "trying to checkpoint mixer state to NVRAM...\n");
6512
6513 if (tp_features.mixer_no_level_control)
6514 ec_mask = TP_EC_AUDIO_MUTESW_MSK;
6515 else
6516 ec_mask = TP_EC_AUDIO_MUTESW_MSK | TP_EC_AUDIO_LVL_MSK;
6517
6518 if (mutex_lock_killable(&volume_mutex) < 0)
6519 return;
6520
6521 if (unlikely(!acpi_ec_read(TP_EC_AUDIO, &lec)))
6522 goto unlock;
6523 lec &= ec_mask;
6524 b_nvram = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
6525
6526 if (lec != (b_nvram & ec_mask)) {
6527
6528 b_nvram &= ~ec_mask;
6529 b_nvram |= lec;
6530 nvram_write_byte(b_nvram, TP_NVRAM_ADDR_MIXER);
6531 dbg_printk(TPACPI_DBG_MIXER,
6532 "updated NVRAM mixer status to 0x%02x (0x%02x)\n",
6533 (unsigned int) lec, (unsigned int) b_nvram);
6534 } else {
6535 vdbg_printk(TPACPI_DBG_MIXER,
6536 "NVRAM mixer status already is 0x%02x (0x%02x)\n",
6537 (unsigned int) lec, (unsigned int) b_nvram);
6538 }
6539
6540unlock:
6541 mutex_unlock(&volume_mutex);
6542}
6543
6544static int volume_get_status_ec(u8 *status)
6545{
6546 u8 s;
6547
6548 if (!acpi_ec_read(TP_EC_AUDIO, &s))
6549 return -EIO;
6550
6551 *status = s;
6552
6553 dbg_printk(TPACPI_DBG_MIXER, "status 0x%02x\n", s);
6554
6555 return 0;
6556}
6557
6558static int volume_get_status(u8 *status)
6559{
6560 return volume_get_status_ec(status);
6561}
6562
6563static int volume_set_status_ec(const u8 status)
6564{
6565 if (!acpi_ec_write(TP_EC_AUDIO, status))
6566 return -EIO;
6567
6568 dbg_printk(TPACPI_DBG_MIXER, "set EC mixer to 0x%02x\n", status);
6569
6570 return 0;
6571}
6572
6573static int volume_set_status(const u8 status)
6574{
6575 return volume_set_status_ec(status);
6576}
6577
6578
6579static int __volume_set_mute_ec(const bool mute)
6580{
6581 int rc;
6582 u8 s, n;
6583
6584 if (mutex_lock_killable(&volume_mutex) < 0)
6585 return -EINTR;
6586
6587 rc = volume_get_status_ec(&s);
6588 if (rc)
6589 goto unlock;
6590
6591 n = (mute) ? s | TP_EC_AUDIO_MUTESW_MSK :
6592 s & ~TP_EC_AUDIO_MUTESW_MSK;
6593
6594 if (n != s) {
6595 rc = volume_set_status_ec(n);
6596 if (!rc)
6597 rc = 1;
6598 }
6599
6600unlock:
6601 mutex_unlock(&volume_mutex);
6602 return rc;
6603}
6604
6605static int volume_alsa_set_mute(const bool mute)
6606{
6607 dbg_printk(TPACPI_DBG_MIXER, "ALSA: trying to %smute\n",
6608 (mute) ? "" : "un");
6609 return __volume_set_mute_ec(mute);
6610}
6611
6612static int volume_set_mute(const bool mute)
6613{
6614 int rc;
6615
6616 dbg_printk(TPACPI_DBG_MIXER, "trying to %smute\n",
6617 (mute) ? "" : "un");
6618
6619 rc = __volume_set_mute_ec(mute);
6620 return (rc < 0) ? rc : 0;
6621}
6622
6623
6624static int __volume_set_volume_ec(const u8 vol)
6625{
6626 int rc;
6627 u8 s, n;
6628
6629 if (vol > TP_EC_VOLUME_MAX)
6630 return -EINVAL;
6631
6632 if (mutex_lock_killable(&volume_mutex) < 0)
6633 return -EINTR;
6634
6635 rc = volume_get_status_ec(&s);
6636 if (rc)
6637 goto unlock;
6638
6639 n = (s & ~TP_EC_AUDIO_LVL_MSK) | vol;
6640
6641 if (n != s) {
6642 rc = volume_set_status_ec(n);
6643 if (!rc)
6644 rc = 1;
6645 }
6646
6647unlock:
6648 mutex_unlock(&volume_mutex);
6649 return rc;
6650}
6651
6652static int volume_alsa_set_volume(const u8 vol)
6653{
6654 dbg_printk(TPACPI_DBG_MIXER,
6655 "ALSA: trying to set volume level to %hu\n", vol);
6656 return __volume_set_volume_ec(vol);
6657}
6658
6659static void volume_alsa_notify_change(void)
6660{
6661 struct tpacpi_alsa_data *d;
6662
6663 if (alsa_card && alsa_card->private_data) {
6664 d = alsa_card->private_data;
6665 if (d->ctl_mute_id)
6666 snd_ctl_notify(alsa_card,
6667 SNDRV_CTL_EVENT_MASK_VALUE,
6668 d->ctl_mute_id);
6669 if (d->ctl_vol_id)
6670 snd_ctl_notify(alsa_card,
6671 SNDRV_CTL_EVENT_MASK_VALUE,
6672 d->ctl_vol_id);
6673 }
6674}
6675
6676static int volume_alsa_vol_info(struct snd_kcontrol *kcontrol,
6677 struct snd_ctl_elem_info *uinfo)
6678{
6679 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
6680 uinfo->count = 1;
6681 uinfo->value.integer.min = 0;
6682 uinfo->value.integer.max = TP_EC_VOLUME_MAX;
6683 return 0;
6684}
6685
6686static int volume_alsa_vol_get(struct snd_kcontrol *kcontrol,
6687 struct snd_ctl_elem_value *ucontrol)
6688{
6689 u8 s;
6690 int rc;
6691
6692 rc = volume_get_status(&s);
6693 if (rc < 0)
6694 return rc;
6695
6696 ucontrol->value.integer.value[0] = s & TP_EC_AUDIO_LVL_MSK;
6697 return 0;
6698}
6699
6700static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol,
6701 struct snd_ctl_elem_value *ucontrol)
6702{
6703 tpacpi_disclose_usertask("ALSA", "set volume to %ld\n",
6704 ucontrol->value.integer.value[0]);
6705 return volume_alsa_set_volume(ucontrol->value.integer.value[0]);
6706}
6707
6708#define volume_alsa_mute_info snd_ctl_boolean_mono_info
6709
6710static int volume_alsa_mute_get(struct snd_kcontrol *kcontrol,
6711 struct snd_ctl_elem_value *ucontrol)
6712{
6713 u8 s;
6714 int rc;
6715
6716 rc = volume_get_status(&s);
6717 if (rc < 0)
6718 return rc;
6719
6720 ucontrol->value.integer.value[0] =
6721 (s & TP_EC_AUDIO_MUTESW_MSK) ? 0 : 1;
6722 return 0;
6723}
6724
6725static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol,
6726 struct snd_ctl_elem_value *ucontrol)
6727{
6728 tpacpi_disclose_usertask("ALSA", "%smute\n",
6729 ucontrol->value.integer.value[0] ?
6730 "un" : "");
6731 return volume_alsa_set_mute(!ucontrol->value.integer.value[0]);
6732}
6733
6734static struct snd_kcontrol_new volume_alsa_control_vol = {
6735 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6736 .name = "Console Playback Volume",
6737 .index = 0,
6738 .access = SNDRV_CTL_ELEM_ACCESS_READ,
6739 .info = volume_alsa_vol_info,
6740 .get = volume_alsa_vol_get,
6741};
6742
6743static struct snd_kcontrol_new volume_alsa_control_mute = {
6744 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6745 .name = "Console Playback Switch",
6746 .index = 0,
6747 .access = SNDRV_CTL_ELEM_ACCESS_READ,
6748 .info = volume_alsa_mute_info,
6749 .get = volume_alsa_mute_get,
6750};
6751
6752static void volume_suspend(void)
6753{
6754 tpacpi_volume_checkpoint_nvram();
6755}
6756
6757static void volume_resume(void)
6758{
6759 volume_alsa_notify_change();
6760}
6761
6762static void volume_shutdown(void)
6763{
6764 tpacpi_volume_checkpoint_nvram();
6765}
6766
6767static void volume_exit(void)
6768{
6769 if (alsa_card) {
6770 snd_card_free(alsa_card);
6771 alsa_card = NULL;
6772 }
6773
6774 tpacpi_volume_checkpoint_nvram();
6775}
6776
6777static int __init volume_create_alsa_mixer(void)
6778{
6779 struct snd_card *card;
6780 struct tpacpi_alsa_data *data;
6781 struct snd_kcontrol *ctl_vol;
6782 struct snd_kcontrol *ctl_mute;
6783 int rc;
6784
6785 rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE,
6786 sizeof(struct tpacpi_alsa_data), &card);
6787 if (rc < 0 || !card) {
6788 pr_err("Failed to create ALSA card structures: %d\n", rc);
6789 return 1;
6790 }
6791
6792 BUG_ON(!card->private_data);
6793 data = card->private_data;
6794 data->card = card;
6795
6796 strlcpy(card->driver, TPACPI_ALSA_DRVNAME,
6797 sizeof(card->driver));
6798 strlcpy(card->shortname, TPACPI_ALSA_SHRTNAME,
6799 sizeof(card->shortname));
6800 snprintf(card->mixername, sizeof(card->mixername), "ThinkPad EC %s",
6801 (thinkpad_id.ec_version_str) ?
6802 thinkpad_id.ec_version_str : "(unknown)");
6803 snprintf(card->longname, sizeof(card->longname),
6804 "%s at EC reg 0x%02x, fw %s", card->shortname, TP_EC_AUDIO,
6805 (thinkpad_id.ec_version_str) ?
6806 thinkpad_id.ec_version_str : "unknown");
6807
6808 if (volume_control_allowed) {
6809 volume_alsa_control_vol.put = volume_alsa_vol_put;
6810 volume_alsa_control_vol.access =
6811 SNDRV_CTL_ELEM_ACCESS_READWRITE;
6812
6813 volume_alsa_control_mute.put = volume_alsa_mute_put;
6814 volume_alsa_control_mute.access =
6815 SNDRV_CTL_ELEM_ACCESS_READWRITE;
6816 }
6817
6818 if (!tp_features.mixer_no_level_control) {
6819 ctl_vol = snd_ctl_new1(&volume_alsa_control_vol, NULL);
6820 rc = snd_ctl_add(card, ctl_vol);
6821 if (rc < 0) {
6822 pr_err("Failed to create ALSA volume control: %d\n",
6823 rc);
6824 goto err_exit;
6825 }
6826 data->ctl_vol_id = &ctl_vol->id;
6827 }
6828
6829 ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL);
6830 rc = snd_ctl_add(card, ctl_mute);
6831 if (rc < 0) {
6832 pr_err("Failed to create ALSA mute control: %d\n", rc);
6833 goto err_exit;
6834 }
6835 data->ctl_mute_id = &ctl_mute->id;
6836
6837 snd_card_set_dev(card, &tpacpi_pdev->dev);
6838 rc = snd_card_register(card);
6839 if (rc < 0) {
6840 pr_err("Failed to register ALSA card: %d\n", rc);
6841 goto err_exit;
6842 }
6843
6844 alsa_card = card;
6845 return 0;
6846
6847err_exit:
6848 snd_card_free(card);
6849 return 1;
6850}
6851
6852#define TPACPI_VOL_Q_MUTEONLY 0x0001
6853#define TPACPI_VOL_Q_LEVEL 0x0002
6854
6855static const struct tpacpi_quirk volume_quirk_table[] __initconst = {
6856
6857 { .vendor = PCI_VENDOR_ID_IBM,
6858 .bios = TPACPI_MATCH_ANY,
6859 .ec = TPACPI_MATCH_ANY,
6860 .quirks = TPACPI_VOL_Q_LEVEL },
6861
6862
6863 TPACPI_QEC_LNV('7', 'C', TPACPI_VOL_Q_LEVEL),
6864 TPACPI_QEC_LNV('7', 'E', TPACPI_VOL_Q_LEVEL),
6865 TPACPI_QEC_LNV('7', '9', TPACPI_VOL_Q_LEVEL),
6866 TPACPI_QEC_LNV('7', 'B', TPACPI_VOL_Q_LEVEL),
6867 TPACPI_QEC_LNV('7', 'J', TPACPI_VOL_Q_LEVEL),
6868 TPACPI_QEC_LNV('7', '7', TPACPI_VOL_Q_LEVEL),
6869 TPACPI_QEC_LNV('7', 'F', TPACPI_VOL_Q_LEVEL),
6870
6871
6872 { .vendor = PCI_VENDOR_ID_LENOVO,
6873 .bios = TPACPI_MATCH_ANY,
6874 .ec = TPACPI_MATCH_ANY,
6875 .quirks = TPACPI_VOL_Q_MUTEONLY }
6876};
6877
6878static int __init volume_init(struct ibm_init_struct *iibm)
6879{
6880 unsigned long quirks;
6881 int rc;
6882
6883 vdbg_printk(TPACPI_DBG_INIT, "initializing volume subdriver\n");
6884
6885 mutex_init(&volume_mutex);
6886
6887
6888
6889
6890
6891
6892 if (volume_mode > TPACPI_VOL_MODE_MAX)
6893 return -EINVAL;
6894
6895 if (volume_mode == TPACPI_VOL_MODE_UCMS_STEP) {
6896 pr_err("UCMS step volume mode not implemented, "
6897 "please contact %s\n", TPACPI_MAIL);
6898 return 1;
6899 }
6900
6901 if (volume_capabilities >= TPACPI_VOL_CAP_MAX)
6902 return -EINVAL;
6903
6904
6905
6906
6907
6908 if (!alsa_enable) {
6909 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6910 "ALSA mixer disabled by parameter, "
6911 "not loading volume subdriver...\n");
6912 return 1;
6913 }
6914
6915 quirks = tpacpi_check_quirks(volume_quirk_table,
6916 ARRAY_SIZE(volume_quirk_table));
6917
6918 switch (volume_capabilities) {
6919 case TPACPI_VOL_CAP_AUTO:
6920 if (quirks & TPACPI_VOL_Q_MUTEONLY)
6921 tp_features.mixer_no_level_control = 1;
6922 else if (quirks & TPACPI_VOL_Q_LEVEL)
6923 tp_features.mixer_no_level_control = 0;
6924 else
6925 return 1;
6926 break;
6927 case TPACPI_VOL_CAP_VOLMUTE:
6928 tp_features.mixer_no_level_control = 0;
6929 break;
6930 case TPACPI_VOL_CAP_MUTEONLY:
6931 tp_features.mixer_no_level_control = 1;
6932 break;
6933 default:
6934 return 1;
6935 }
6936
6937 if (volume_capabilities != TPACPI_VOL_CAP_AUTO)
6938 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6939 "using user-supplied volume_capabilities=%d\n",
6940 volume_capabilities);
6941
6942 if (volume_mode == TPACPI_VOL_MODE_AUTO ||
6943 volume_mode == TPACPI_VOL_MODE_MAX) {
6944 volume_mode = TPACPI_VOL_MODE_ECNVRAM;
6945
6946 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6947 "driver auto-selected volume_mode=%d\n",
6948 volume_mode);
6949 } else {
6950 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6951 "using user-supplied volume_mode=%d\n",
6952 volume_mode);
6953 }
6954
6955 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6956 "mute is supported, volume control is %s\n",
6957 str_supported(!tp_features.mixer_no_level_control));
6958
6959 rc = volume_create_alsa_mixer();
6960 if (rc) {
6961 pr_err("Could not create the ALSA mixer interface\n");
6962 return rc;
6963 }
6964
6965 pr_info("Console audio control enabled, mode: %s\n",
6966 (volume_control_allowed) ?
6967 "override (read/write)" :
6968 "monitor (read only)");
6969
6970 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6971 "registering volume hotkeys as change notification\n");
6972 tpacpi_hotkey_driver_mask_set(hotkey_driver_mask
6973 | TP_ACPI_HKEY_VOLUP_MASK
6974 | TP_ACPI_HKEY_VOLDWN_MASK
6975 | TP_ACPI_HKEY_MUTE_MASK);
6976
6977 return 0;
6978}
6979
6980static int volume_read(struct seq_file *m)
6981{
6982 u8 status;
6983
6984 if (volume_get_status(&status) < 0) {
6985 seq_printf(m, "level:\t\tunreadable\n");
6986 } else {
6987 if (tp_features.mixer_no_level_control)
6988 seq_printf(m, "level:\t\tunsupported\n");
6989 else
6990 seq_printf(m, "level:\t\t%d\n",
6991 status & TP_EC_AUDIO_LVL_MSK);
6992
6993 seq_printf(m, "mute:\t\t%s\n",
6994 onoff(status, TP_EC_AUDIO_MUTESW));
6995
6996 if (volume_control_allowed) {
6997 seq_printf(m, "commands:\tunmute, mute\n");
6998 if (!tp_features.mixer_no_level_control) {
6999 seq_printf(m,
7000 "commands:\tup, down\n");
7001 seq_printf(m,
7002 "commands:\tlevel <level>"
7003 " (<level> is 0-%d)\n",
7004 TP_EC_VOLUME_MAX);
7005 }
7006 }
7007 }
7008
7009 return 0;
7010}
7011
7012static int volume_write(char *buf)
7013{
7014 u8 s;
7015 u8 new_level, new_mute;
7016 int l;
7017 char *cmd;
7018 int rc;
7019
7020
7021
7022
7023
7024 if (!volume_control_allowed && tpacpi_lifecycle != TPACPI_LIFE_INIT) {
7025 if (unlikely(!tp_warned.volume_ctrl_forbidden)) {
7026 tp_warned.volume_ctrl_forbidden = 1;
7027 pr_notice("Console audio control in monitor mode, "
7028 "changes are not allowed\n");
7029 pr_notice("Use the volume_control=1 module parameter "
7030 "to enable volume control\n");
7031 }
7032 return -EPERM;
7033 }
7034
7035 rc = volume_get_status(&s);
7036 if (rc < 0)
7037 return rc;
7038
7039 new_level = s & TP_EC_AUDIO_LVL_MSK;
7040 new_mute = s & TP_EC_AUDIO_MUTESW_MSK;
7041
7042 while ((cmd = next_cmd(&buf))) {
7043 if (!tp_features.mixer_no_level_control) {
7044 if (strlencmp(cmd, "up") == 0) {
7045 if (new_mute)
7046 new_mute = 0;
7047 else if (new_level < TP_EC_VOLUME_MAX)
7048 new_level++;
7049 continue;
7050 } else if (strlencmp(cmd, "down") == 0) {
7051 if (new_mute)
7052 new_mute = 0;
7053 else if (new_level > 0)
7054 new_level--;
7055 continue;
7056 } else if (sscanf(cmd, "level %u", &l) == 1 &&
7057 l >= 0 && l <= TP_EC_VOLUME_MAX) {
7058 new_level = l;
7059 continue;
7060 }
7061 }
7062 if (strlencmp(cmd, "mute") == 0)
7063 new_mute = TP_EC_AUDIO_MUTESW_MSK;
7064 else if (strlencmp(cmd, "unmute") == 0)
7065 new_mute = 0;
7066 else
7067 return -EINVAL;
7068 }
7069
7070 if (tp_features.mixer_no_level_control) {
7071 tpacpi_disclose_usertask("procfs volume", "%smute\n",
7072 new_mute ? "" : "un");
7073 rc = volume_set_mute(!!new_mute);
7074 } else {
7075 tpacpi_disclose_usertask("procfs volume",
7076 "%smute and set level to %d\n",
7077 new_mute ? "" : "un", new_level);
7078 rc = volume_set_status(new_mute | new_level);
7079 }
7080 volume_alsa_notify_change();
7081
7082 return (rc == -EINTR) ? -ERESTARTSYS : rc;
7083}
7084
7085static struct ibm_struct volume_driver_data = {
7086 .name = "volume",
7087 .read = volume_read,
7088 .write = volume_write,
7089 .exit = volume_exit,
7090 .suspend = volume_suspend,
7091 .resume = volume_resume,
7092 .shutdown = volume_shutdown,
7093};
7094
7095#else
7096
7097#define alsa_card NULL
7098
7099static void inline volume_alsa_notify_change(void)
7100{
7101}
7102
7103static int __init volume_init(struct ibm_init_struct *iibm)
7104{
7105 pr_info("volume: disabled as there is no ALSA support in this kernel\n");
7106
7107 return 1;
7108}
7109
7110static struct ibm_struct volume_driver_data = {
7111 .name = "volume",
7112};
7113
7114#endif
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236enum {
7237 fan_status_offset = 0x2f,
7238 fan_rpm_offset = 0x84,
7239
7240 fan_select_offset = 0x31,
7241
7242
7243 TP_EC_FAN_FULLSPEED = 0x40,
7244 TP_EC_FAN_AUTO = 0x80,
7245
7246 TPACPI_FAN_LAST_LEVEL = 0x100,
7247};
7248
7249enum fan_status_access_mode {
7250 TPACPI_FAN_NONE = 0,
7251 TPACPI_FAN_RD_ACPI_GFAN,
7252 TPACPI_FAN_RD_TPEC,
7253};
7254
7255enum fan_control_access_mode {
7256 TPACPI_FAN_WR_NONE = 0,
7257 TPACPI_FAN_WR_ACPI_SFAN,
7258 TPACPI_FAN_WR_TPEC,
7259 TPACPI_FAN_WR_ACPI_FANS,
7260};
7261
7262enum fan_control_commands {
7263 TPACPI_FAN_CMD_SPEED = 0x0001,
7264 TPACPI_FAN_CMD_LEVEL = 0x0002,
7265 TPACPI_FAN_CMD_ENABLE = 0x0004,
7266
7267};
7268
7269static bool fan_control_allowed;
7270
7271static enum fan_status_access_mode fan_status_access_mode;
7272static enum fan_control_access_mode fan_control_access_mode;
7273static enum fan_control_commands fan_control_commands;
7274
7275static u8 fan_control_initial_status;
7276static u8 fan_control_desired_level;
7277static u8 fan_control_resume_level;
7278static int fan_watchdog_maxinterval;
7279
7280static struct mutex fan_mutex;
7281
7282static void fan_watchdog_fire(struct work_struct *ignored);
7283static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire);
7284
7285TPACPI_HANDLE(fans, ec, "FANS");
7286TPACPI_HANDLE(gfan, ec, "GFAN",
7287 "\\FSPD",
7288 );
7289TPACPI_HANDLE(sfan, ec, "SFAN",
7290 "JFNS",
7291 );
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309static void fan_quirk1_setup(void)
7310{
7311 if (fan_control_initial_status == 0x07) {
7312 pr_notice("fan_init: initial fan status is unknown, "
7313 "assuming it is in auto mode\n");
7314 tp_features.fan_ctrl_status_undef = 1;
7315 }
7316}
7317
7318static void fan_quirk1_handle(u8 *fan_status)
7319{
7320 if (unlikely(tp_features.fan_ctrl_status_undef)) {
7321 if (*fan_status != fan_control_initial_status) {
7322
7323
7324
7325 tp_features.fan_ctrl_status_undef = 0;
7326 } else {
7327
7328
7329 *fan_status = TP_EC_FAN_AUTO;
7330 }
7331 }
7332}
7333
7334
7335static bool fan_select_fan1(void)
7336{
7337 if (tp_features.second_fan) {
7338 u8 val;
7339
7340 if (ec_read(fan_select_offset, &val) < 0)
7341 return false;
7342 val &= 0xFEU;
7343 if (ec_write(fan_select_offset, val) < 0)
7344 return false;
7345 }
7346 return true;
7347}
7348
7349
7350static bool fan_select_fan2(void)
7351{
7352 u8 val;
7353
7354 if (!tp_features.second_fan)
7355 return false;
7356
7357 if (ec_read(fan_select_offset, &val) < 0)
7358 return false;
7359 val |= 0x01U;
7360 if (ec_write(fan_select_offset, val) < 0)
7361 return false;
7362
7363 return true;
7364}
7365
7366
7367
7368
7369static void fan_update_desired_level(u8 status)
7370{
7371 if ((status &
7372 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
7373 if (status > 7)
7374 fan_control_desired_level = 7;
7375 else
7376 fan_control_desired_level = status;
7377 }
7378}
7379
7380static int fan_get_status(u8 *status)
7381{
7382 u8 s;
7383
7384
7385
7386
7387 switch (fan_status_access_mode) {
7388 case TPACPI_FAN_RD_ACPI_GFAN: {
7389
7390 int res;
7391
7392 if (unlikely(!acpi_evalf(gfan_handle, &res, NULL, "d")))
7393 return -EIO;
7394
7395 if (likely(status))
7396 *status = res & 0x07;
7397
7398 break;
7399 }
7400 case TPACPI_FAN_RD_TPEC:
7401
7402 if (unlikely(!acpi_ec_read(fan_status_offset, &s)))
7403 return -EIO;
7404
7405 if (likely(status)) {
7406 *status = s;
7407 fan_quirk1_handle(status);
7408 }
7409
7410 break;
7411
7412 default:
7413 return -ENXIO;
7414 }
7415
7416 return 0;
7417}
7418
7419static int fan_get_status_safe(u8 *status)
7420{
7421 int rc;
7422 u8 s;
7423
7424 if (mutex_lock_killable(&fan_mutex))
7425 return -ERESTARTSYS;
7426 rc = fan_get_status(&s);
7427 if (!rc)
7428 fan_update_desired_level(s);
7429 mutex_unlock(&fan_mutex);
7430
7431 if (status)
7432 *status = s;
7433
7434 return rc;
7435}
7436
7437static int fan_get_speed(unsigned int *speed)
7438{
7439 u8 hi, lo;
7440
7441 switch (fan_status_access_mode) {
7442 case TPACPI_FAN_RD_TPEC:
7443
7444 if (unlikely(!fan_select_fan1()))
7445 return -EIO;
7446 if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) ||
7447 !acpi_ec_read(fan_rpm_offset + 1, &hi)))
7448 return -EIO;
7449
7450 if (likely(speed))
7451 *speed = (hi << 8) | lo;
7452
7453 break;
7454
7455 default:
7456 return -ENXIO;
7457 }
7458
7459 return 0;
7460}
7461
7462static int fan2_get_speed(unsigned int *speed)
7463{
7464 u8 hi, lo;
7465 bool rc;
7466
7467 switch (fan_status_access_mode) {
7468 case TPACPI_FAN_RD_TPEC:
7469
7470 if (unlikely(!fan_select_fan2()))
7471 return -EIO;
7472 rc = !acpi_ec_read(fan_rpm_offset, &lo) ||
7473 !acpi_ec_read(fan_rpm_offset + 1, &hi);
7474 fan_select_fan1();
7475 if (rc)
7476 return -EIO;
7477
7478 if (likely(speed))
7479 *speed = (hi << 8) | lo;
7480
7481 break;
7482
7483 default:
7484 return -ENXIO;
7485 }
7486
7487 return 0;
7488}
7489
7490static int fan_set_level(int level)
7491{
7492 if (!fan_control_allowed)
7493 return -EPERM;
7494
7495 switch (fan_control_access_mode) {
7496 case TPACPI_FAN_WR_ACPI_SFAN:
7497 if (level >= 0 && level <= 7) {
7498 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
7499 return -EIO;
7500 } else
7501 return -EINVAL;
7502 break;
7503
7504 case TPACPI_FAN_WR_ACPI_FANS:
7505 case TPACPI_FAN_WR_TPEC:
7506 if (!(level & TP_EC_FAN_AUTO) &&
7507 !(level & TP_EC_FAN_FULLSPEED) &&
7508 ((level < 0) || (level > 7)))
7509 return -EINVAL;
7510
7511
7512
7513 if (level & TP_EC_FAN_FULLSPEED)
7514 level |= 7;
7515 else if (level & TP_EC_FAN_AUTO)
7516 level |= 4;
7517
7518 if (!acpi_ec_write(fan_status_offset, level))
7519 return -EIO;
7520 else
7521 tp_features.fan_ctrl_status_undef = 0;
7522 break;
7523
7524 default:
7525 return -ENXIO;
7526 }
7527
7528 vdbg_printk(TPACPI_DBG_FAN,
7529 "fan control: set fan control register to 0x%02x\n", level);
7530 return 0;
7531}
7532
7533static int fan_set_level_safe(int level)
7534{
7535 int rc;
7536
7537 if (!fan_control_allowed)
7538 return -EPERM;
7539
7540 if (mutex_lock_killable(&fan_mutex))
7541 return -ERESTARTSYS;
7542
7543 if (level == TPACPI_FAN_LAST_LEVEL)
7544 level = fan_control_desired_level;
7545
7546 rc = fan_set_level(level);
7547 if (!rc)
7548 fan_update_desired_level(level);
7549
7550 mutex_unlock(&fan_mutex);
7551 return rc;
7552}
7553
7554static int fan_set_enable(void)
7555{
7556 u8 s;
7557 int rc;
7558
7559 if (!fan_control_allowed)
7560 return -EPERM;
7561
7562 if (mutex_lock_killable(&fan_mutex))
7563 return -ERESTARTSYS;
7564
7565 switch (fan_control_access_mode) {
7566 case TPACPI_FAN_WR_ACPI_FANS:
7567 case TPACPI_FAN_WR_TPEC:
7568 rc = fan_get_status(&s);
7569 if (rc < 0)
7570 break;
7571
7572
7573 if (s != 7) {
7574 s &= 0x07;
7575 s |= TP_EC_FAN_AUTO | 4;
7576 }
7577
7578 if (!acpi_ec_write(fan_status_offset, s))
7579 rc = -EIO;
7580 else {
7581 tp_features.fan_ctrl_status_undef = 0;
7582 rc = 0;
7583 }
7584 break;
7585
7586 case TPACPI_FAN_WR_ACPI_SFAN:
7587 rc = fan_get_status(&s);
7588 if (rc < 0)
7589 break;
7590
7591 s &= 0x07;
7592
7593
7594 s |= 4;
7595
7596 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s))
7597 rc = -EIO;
7598 else
7599 rc = 0;
7600 break;
7601
7602 default:
7603 rc = -ENXIO;
7604 }
7605
7606 mutex_unlock(&fan_mutex);
7607
7608 if (!rc)
7609 vdbg_printk(TPACPI_DBG_FAN,
7610 "fan control: set fan control register to 0x%02x\n",
7611 s);
7612 return rc;
7613}
7614
7615static int fan_set_disable(void)
7616{
7617 int rc;
7618
7619 if (!fan_control_allowed)
7620 return -EPERM;
7621
7622 if (mutex_lock_killable(&fan_mutex))
7623 return -ERESTARTSYS;
7624
7625 rc = 0;
7626 switch (fan_control_access_mode) {
7627 case TPACPI_FAN_WR_ACPI_FANS:
7628 case TPACPI_FAN_WR_TPEC:
7629 if (!acpi_ec_write(fan_status_offset, 0x00))
7630 rc = -EIO;
7631 else {
7632 fan_control_desired_level = 0;
7633 tp_features.fan_ctrl_status_undef = 0;
7634 }
7635 break;
7636
7637 case TPACPI_FAN_WR_ACPI_SFAN:
7638 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))
7639 rc = -EIO;
7640 else
7641 fan_control_desired_level = 0;
7642 break;
7643
7644 default:
7645 rc = -ENXIO;
7646 }
7647
7648 if (!rc)
7649 vdbg_printk(TPACPI_DBG_FAN,
7650 "fan control: set fan control register to 0\n");
7651
7652 mutex_unlock(&fan_mutex);
7653 return rc;
7654}
7655
7656static int fan_set_speed(int speed)
7657{
7658 int rc;
7659
7660 if (!fan_control_allowed)
7661 return -EPERM;
7662
7663 if (mutex_lock_killable(&fan_mutex))
7664 return -ERESTARTSYS;
7665
7666 rc = 0;
7667 switch (fan_control_access_mode) {
7668 case TPACPI_FAN_WR_ACPI_FANS:
7669 if (speed >= 0 && speed <= 65535) {
7670 if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
7671 speed, speed, speed))
7672 rc = -EIO;
7673 } else
7674 rc = -EINVAL;
7675 break;
7676
7677 default:
7678 rc = -ENXIO;
7679 }
7680
7681 mutex_unlock(&fan_mutex);
7682 return rc;
7683}
7684
7685static void fan_watchdog_reset(void)
7686{
7687 if (fan_control_access_mode == TPACPI_FAN_WR_NONE)
7688 return;
7689
7690 if (fan_watchdog_maxinterval > 0 &&
7691 tpacpi_lifecycle != TPACPI_LIFE_EXITING)
7692 mod_delayed_work(tpacpi_wq, &fan_watchdog_task,
7693 msecs_to_jiffies(fan_watchdog_maxinterval * 1000));
7694 else
7695 cancel_delayed_work(&fan_watchdog_task);
7696}
7697
7698static void fan_watchdog_fire(struct work_struct *ignored)
7699{
7700 int rc;
7701
7702 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
7703 return;
7704
7705 pr_notice("fan watchdog: enabling fan\n");
7706 rc = fan_set_enable();
7707 if (rc < 0) {
7708 pr_err("fan watchdog: error %d while enabling fan, "
7709 "will try again later...\n", -rc);
7710
7711 fan_watchdog_reset();
7712 }
7713}
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737static ssize_t fan_pwm1_enable_show(struct device *dev,
7738 struct device_attribute *attr,
7739 char *buf)
7740{
7741 int res, mode;
7742 u8 status;
7743
7744 res = fan_get_status_safe(&status);
7745 if (res)
7746 return res;
7747
7748 if (status & TP_EC_FAN_FULLSPEED) {
7749 mode = 0;
7750 } else if (status & TP_EC_FAN_AUTO) {
7751 mode = 2;
7752 } else
7753 mode = 1;
7754
7755 return snprintf(buf, PAGE_SIZE, "%d\n", mode);
7756}
7757
7758static ssize_t fan_pwm1_enable_store(struct device *dev,
7759 struct device_attribute *attr,
7760 const char *buf, size_t count)
7761{
7762 unsigned long t;
7763 int res, level;
7764
7765 if (parse_strtoul(buf, 2, &t))
7766 return -EINVAL;
7767
7768 tpacpi_disclose_usertask("hwmon pwm1_enable",
7769 "set fan mode to %lu\n", t);
7770
7771 switch (t) {
7772 case 0:
7773 level = TP_EC_FAN_FULLSPEED;
7774 break;
7775 case 1:
7776 level = TPACPI_FAN_LAST_LEVEL;
7777 break;
7778 case 2:
7779 level = TP_EC_FAN_AUTO;
7780 break;
7781 case 3:
7782
7783 return -ENOSYS;
7784 default:
7785 return -EINVAL;
7786 }
7787
7788 res = fan_set_level_safe(level);
7789 if (res == -ENXIO)
7790 return -EINVAL;
7791 else if (res < 0)
7792 return res;
7793
7794 fan_watchdog_reset();
7795
7796 return count;
7797}
7798
7799static struct device_attribute dev_attr_fan_pwm1_enable =
7800 __ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
7801 fan_pwm1_enable_show, fan_pwm1_enable_store);
7802
7803
7804static ssize_t fan_pwm1_show(struct device *dev,
7805 struct device_attribute *attr,
7806 char *buf)
7807{
7808 int res;
7809 u8 status;
7810
7811 res = fan_get_status_safe(&status);
7812 if (res)
7813 return res;
7814
7815 if ((status &
7816 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0)
7817 status = fan_control_desired_level;
7818
7819 if (status > 7)
7820 status = 7;
7821
7822 return snprintf(buf, PAGE_SIZE, "%u\n", (status * 255) / 7);
7823}
7824
7825static ssize_t fan_pwm1_store(struct device *dev,
7826 struct device_attribute *attr,
7827 const char *buf, size_t count)
7828{
7829 unsigned long s;
7830 int rc;
7831 u8 status, newlevel;
7832
7833 if (parse_strtoul(buf, 255, &s))
7834 return -EINVAL;
7835
7836 tpacpi_disclose_usertask("hwmon pwm1",
7837 "set fan speed to %lu\n", s);
7838
7839
7840 newlevel = (s >> 5) & 0x07;
7841
7842 if (mutex_lock_killable(&fan_mutex))
7843 return -ERESTARTSYS;
7844
7845 rc = fan_get_status(&status);
7846 if (!rc && (status &
7847 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
7848 rc = fan_set_level(newlevel);
7849 if (rc == -ENXIO)
7850 rc = -EINVAL;
7851 else if (!rc) {
7852 fan_update_desired_level(newlevel);
7853 fan_watchdog_reset();
7854 }
7855 }
7856
7857 mutex_unlock(&fan_mutex);
7858 return (rc)? rc : count;
7859}
7860
7861static struct device_attribute dev_attr_fan_pwm1 =
7862 __ATTR(pwm1, S_IWUSR | S_IRUGO,
7863 fan_pwm1_show, fan_pwm1_store);
7864
7865
7866static ssize_t fan_fan1_input_show(struct device *dev,
7867 struct device_attribute *attr,
7868 char *buf)
7869{
7870 int res;
7871 unsigned int speed;
7872
7873 res = fan_get_speed(&speed);
7874 if (res < 0)
7875 return res;
7876
7877 return snprintf(buf, PAGE_SIZE, "%u\n", speed);
7878}
7879
7880static struct device_attribute dev_attr_fan_fan1_input =
7881 __ATTR(fan1_input, S_IRUGO,
7882 fan_fan1_input_show, NULL);
7883
7884
7885static ssize_t fan_fan2_input_show(struct device *dev,
7886 struct device_attribute *attr,
7887 char *buf)
7888{
7889 int res;
7890 unsigned int speed;
7891
7892 res = fan2_get_speed(&speed);
7893 if (res < 0)
7894 return res;
7895
7896 return snprintf(buf, PAGE_SIZE, "%u\n", speed);
7897}
7898
7899static struct device_attribute dev_attr_fan_fan2_input =
7900 __ATTR(fan2_input, S_IRUGO,
7901 fan_fan2_input_show, NULL);
7902
7903
7904static ssize_t fan_fan_watchdog_show(struct device_driver *drv,
7905 char *buf)
7906{
7907 return snprintf(buf, PAGE_SIZE, "%u\n", fan_watchdog_maxinterval);
7908}
7909
7910static ssize_t fan_fan_watchdog_store(struct device_driver *drv,
7911 const char *buf, size_t count)
7912{
7913 unsigned long t;
7914
7915 if (parse_strtoul(buf, 120, &t))
7916 return -EINVAL;
7917
7918 if (!fan_control_allowed)
7919 return -EPERM;
7920
7921 fan_watchdog_maxinterval = t;
7922 fan_watchdog_reset();
7923
7924 tpacpi_disclose_usertask("fan_watchdog", "set to %lu\n", t);
7925
7926 return count;
7927}
7928
7929static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO,
7930 fan_fan_watchdog_show, fan_fan_watchdog_store);
7931
7932
7933static struct attribute *fan_attributes[] = {
7934 &dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr,
7935 &dev_attr_fan_fan1_input.attr,
7936 NULL,
7937 NULL
7938};
7939
7940static const struct attribute_group fan_attr_group = {
7941 .attrs = fan_attributes,
7942};
7943
7944#define TPACPI_FAN_Q1 0x0001
7945#define TPACPI_FAN_2FAN 0x0002
7946
7947#define TPACPI_FAN_QI(__id1, __id2, __quirks) \
7948 { .vendor = PCI_VENDOR_ID_IBM, \
7949 .bios = TPACPI_MATCH_ANY, \
7950 .ec = TPID(__id1, __id2), \
7951 .quirks = __quirks }
7952
7953#define TPACPI_FAN_QL(__id1, __id2, __quirks) \
7954 { .vendor = PCI_VENDOR_ID_LENOVO, \
7955 .bios = TPACPI_MATCH_ANY, \
7956 .ec = TPID(__id1, __id2), \
7957 .quirks = __quirks }
7958
7959static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
7960 TPACPI_FAN_QI('1', 'Y', TPACPI_FAN_Q1),
7961 TPACPI_FAN_QI('7', '8', TPACPI_FAN_Q1),
7962 TPACPI_FAN_QI('7', '6', TPACPI_FAN_Q1),
7963 TPACPI_FAN_QI('7', '0', TPACPI_FAN_Q1),
7964 TPACPI_FAN_QL('7', 'M', TPACPI_FAN_2FAN),
7965};
7966
7967#undef TPACPI_FAN_QL
7968#undef TPACPI_FAN_QI
7969
7970static int __init fan_init(struct ibm_init_struct *iibm)
7971{
7972 int rc;
7973 unsigned long quirks;
7974
7975 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
7976 "initializing fan subdriver\n");
7977
7978 mutex_init(&fan_mutex);
7979 fan_status_access_mode = TPACPI_FAN_NONE;
7980 fan_control_access_mode = TPACPI_FAN_WR_NONE;
7981 fan_control_commands = 0;
7982 fan_watchdog_maxinterval = 0;
7983 tp_features.fan_ctrl_status_undef = 0;
7984 tp_features.second_fan = 0;
7985 fan_control_desired_level = 7;
7986
7987 if (tpacpi_is_ibm()) {
7988 TPACPI_ACPIHANDLE_INIT(fans);
7989 TPACPI_ACPIHANDLE_INIT(gfan);
7990 TPACPI_ACPIHANDLE_INIT(sfan);
7991 }
7992
7993 quirks = tpacpi_check_quirks(fan_quirk_table,
7994 ARRAY_SIZE(fan_quirk_table));
7995
7996 if (gfan_handle) {
7997
7998 fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN;
7999 } else {
8000
8001
8002 if (likely(acpi_ec_read(fan_status_offset,
8003 &fan_control_initial_status))) {
8004 fan_status_access_mode = TPACPI_FAN_RD_TPEC;
8005 if (quirks & TPACPI_FAN_Q1)
8006 fan_quirk1_setup();
8007 if (quirks & TPACPI_FAN_2FAN) {
8008 tp_features.second_fan = 1;
8009 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
8010 "secondary fan support enabled\n");
8011 }
8012 } else {
8013 pr_err("ThinkPad ACPI EC access misbehaving, "
8014 "fan status and control unavailable\n");
8015 return 1;
8016 }
8017 }
8018
8019 if (sfan_handle) {
8020
8021 fan_control_access_mode = TPACPI_FAN_WR_ACPI_SFAN;
8022 fan_control_commands |=
8023 TPACPI_FAN_CMD_LEVEL | TPACPI_FAN_CMD_ENABLE;
8024 } else {
8025 if (!gfan_handle) {
8026
8027
8028
8029 if (fans_handle) {
8030
8031 fan_control_access_mode =
8032 TPACPI_FAN_WR_ACPI_FANS;
8033 fan_control_commands |=
8034 TPACPI_FAN_CMD_SPEED |
8035 TPACPI_FAN_CMD_LEVEL |
8036 TPACPI_FAN_CMD_ENABLE;
8037 } else {
8038 fan_control_access_mode = TPACPI_FAN_WR_TPEC;
8039 fan_control_commands |=
8040 TPACPI_FAN_CMD_LEVEL |
8041 TPACPI_FAN_CMD_ENABLE;
8042 }
8043 }
8044 }
8045
8046 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
8047 "fan is %s, modes %d, %d\n",
8048 str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||
8049 fan_control_access_mode != TPACPI_FAN_WR_NONE),
8050 fan_status_access_mode, fan_control_access_mode);
8051
8052
8053 if (!fan_control_allowed) {
8054 fan_control_access_mode = TPACPI_FAN_WR_NONE;
8055 fan_control_commands = 0;
8056 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
8057 "fan control features disabled by parameter\n");
8058 }
8059
8060
8061 if (fan_status_access_mode != TPACPI_FAN_NONE)
8062 fan_get_status_safe(NULL);
8063
8064 if (fan_status_access_mode != TPACPI_FAN_NONE ||
8065 fan_control_access_mode != TPACPI_FAN_WR_NONE) {
8066 if (tp_features.second_fan) {
8067
8068 fan_attributes[ARRAY_SIZE(fan_attributes)-2] =
8069 &dev_attr_fan_fan2_input.attr;
8070 }
8071 rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
8072 &fan_attr_group);
8073 if (rc < 0)
8074 return rc;
8075
8076 rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
8077 &driver_attr_fan_watchdog);
8078 if (rc < 0) {
8079 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
8080 &fan_attr_group);
8081 return rc;
8082 }
8083 return 0;
8084 } else
8085 return 1;
8086}
8087
8088static void fan_exit(void)
8089{
8090 vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_FAN,
8091 "cancelling any pending fan watchdog tasks\n");
8092
8093
8094 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group);
8095 driver_remove_file(&tpacpi_hwmon_pdriver.driver,
8096 &driver_attr_fan_watchdog);
8097
8098 cancel_delayed_work(&fan_watchdog_task);
8099 flush_workqueue(tpacpi_wq);
8100}
8101
8102static void fan_suspend(void)
8103{
8104 int rc;
8105
8106 if (!fan_control_allowed)
8107 return;
8108
8109
8110 fan_control_resume_level = 0;
8111 rc = fan_get_status_safe(&fan_control_resume_level);
8112 if (rc < 0)
8113 pr_notice("failed to read fan level for later "
8114 "restore during resume: %d\n", rc);
8115
8116
8117
8118 if (tp_features.fan_ctrl_status_undef)
8119 fan_control_resume_level = 0;
8120}
8121
8122static void fan_resume(void)
8123{
8124 u8 current_level = 7;
8125 bool do_set = false;
8126 int rc;
8127
8128
8129 tp_features.fan_ctrl_status_undef = 0;
8130
8131 if (!fan_control_allowed ||
8132 !fan_control_resume_level ||
8133 (fan_get_status_safe(¤t_level) < 0))
8134 return;
8135
8136 switch (fan_control_access_mode) {
8137 case TPACPI_FAN_WR_ACPI_SFAN:
8138
8139 do_set = (fan_control_resume_level > current_level);
8140 break;
8141 case TPACPI_FAN_WR_ACPI_FANS:
8142 case TPACPI_FAN_WR_TPEC:
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158 if (fan_control_resume_level != 7 &&
8159 !(fan_control_resume_level & TP_EC_FAN_FULLSPEED))
8160 return;
8161 else
8162 do_set = !(current_level & TP_EC_FAN_FULLSPEED) &&
8163 (current_level != fan_control_resume_level);
8164 break;
8165 default:
8166 return;
8167 }
8168 if (do_set) {
8169 pr_notice("restoring fan level to 0x%02x\n",
8170 fan_control_resume_level);
8171 rc = fan_set_level_safe(fan_control_resume_level);
8172 if (rc < 0)
8173 pr_notice("failed to restore fan level: %d\n", rc);
8174 }
8175}
8176
8177static int fan_read(struct seq_file *m)
8178{
8179 int rc;
8180 u8 status;
8181 unsigned int speed = 0;
8182
8183 switch (fan_status_access_mode) {
8184 case TPACPI_FAN_RD_ACPI_GFAN:
8185
8186 rc = fan_get_status_safe(&status);
8187 if (rc < 0)
8188 return rc;
8189
8190 seq_printf(m, "status:\t\t%s\n"
8191 "level:\t\t%d\n",
8192 (status != 0) ? "enabled" : "disabled", status);
8193 break;
8194
8195 case TPACPI_FAN_RD_TPEC:
8196
8197 rc = fan_get_status_safe(&status);
8198 if (rc < 0)
8199 return rc;
8200
8201 seq_printf(m, "status:\t\t%s\n",
8202 (status != 0) ? "enabled" : "disabled");
8203
8204 rc = fan_get_speed(&speed);
8205 if (rc < 0)
8206 return rc;
8207
8208 seq_printf(m, "speed:\t\t%d\n", speed);
8209
8210 if (status & TP_EC_FAN_FULLSPEED)
8211
8212 seq_printf(m, "level:\t\tdisengaged\n");
8213 else if (status & TP_EC_FAN_AUTO)
8214 seq_printf(m, "level:\t\tauto\n");
8215 else
8216 seq_printf(m, "level:\t\t%d\n", status);
8217 break;
8218
8219 case TPACPI_FAN_NONE:
8220 default:
8221 seq_printf(m, "status:\t\tnot supported\n");
8222 }
8223
8224 if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) {
8225 seq_printf(m, "commands:\tlevel <level>");
8226
8227 switch (fan_control_access_mode) {
8228 case TPACPI_FAN_WR_ACPI_SFAN:
8229 seq_printf(m, " (<level> is 0-7)\n");
8230 break;
8231
8232 default:
8233 seq_printf(m, " (<level> is 0-7, "
8234 "auto, disengaged, full-speed)\n");
8235 break;
8236 }
8237 }
8238
8239 if (fan_control_commands & TPACPI_FAN_CMD_ENABLE)
8240 seq_printf(m, "commands:\tenable, disable\n"
8241 "commands:\twatchdog <timeout> (<timeout> "
8242 "is 0 (off), 1-120 (seconds))\n");
8243
8244 if (fan_control_commands & TPACPI_FAN_CMD_SPEED)
8245 seq_printf(m, "commands:\tspeed <speed>"
8246 " (<speed> is 0-65535)\n");
8247
8248 return 0;
8249}
8250
8251static int fan_write_cmd_level(const char *cmd, int *rc)
8252{
8253 int level;
8254
8255 if (strlencmp(cmd, "level auto") == 0)
8256 level = TP_EC_FAN_AUTO;
8257 else if ((strlencmp(cmd, "level disengaged") == 0) |
8258 (strlencmp(cmd, "level full-speed") == 0))
8259 level = TP_EC_FAN_FULLSPEED;
8260 else if (sscanf(cmd, "level %d", &level) != 1)
8261 return 0;
8262
8263 *rc = fan_set_level_safe(level);
8264 if (*rc == -ENXIO)
8265 pr_err("level command accepted for unsupported access mode %d\n",
8266 fan_control_access_mode);
8267 else if (!*rc)
8268 tpacpi_disclose_usertask("procfs fan",
8269 "set level to %d\n", level);
8270
8271 return 1;
8272}
8273
8274static int fan_write_cmd_enable(const char *cmd, int *rc)
8275{
8276 if (strlencmp(cmd, "enable") != 0)
8277 return 0;
8278
8279 *rc = fan_set_enable();
8280 if (*rc == -ENXIO)
8281 pr_err("enable command accepted for unsupported access mode %d\n",
8282 fan_control_access_mode);
8283 else if (!*rc)
8284 tpacpi_disclose_usertask("procfs fan", "enable\n");
8285
8286 return 1;
8287}
8288
8289static int fan_write_cmd_disable(const char *cmd, int *rc)
8290{
8291 if (strlencmp(cmd, "disable") != 0)
8292 return 0;
8293
8294 *rc = fan_set_disable();
8295 if (*rc == -ENXIO)
8296 pr_err("disable command accepted for unsupported access mode %d\n",
8297 fan_control_access_mode);
8298 else if (!*rc)
8299 tpacpi_disclose_usertask("procfs fan", "disable\n");
8300
8301 return 1;
8302}
8303
8304static int fan_write_cmd_speed(const char *cmd, int *rc)
8305{
8306 int speed;
8307
8308
8309
8310
8311 if (sscanf(cmd, "speed %d", &speed) != 1)
8312 return 0;
8313
8314 *rc = fan_set_speed(speed);
8315 if (*rc == -ENXIO)
8316 pr_err("speed command accepted for unsupported access mode %d\n",
8317 fan_control_access_mode);
8318 else if (!*rc)
8319 tpacpi_disclose_usertask("procfs fan",
8320 "set speed to %d\n", speed);
8321
8322 return 1;
8323}
8324
8325static int fan_write_cmd_watchdog(const char *cmd, int *rc)
8326{
8327 int interval;
8328
8329 if (sscanf(cmd, "watchdog %d", &interval) != 1)
8330 return 0;
8331
8332 if (interval < 0 || interval > 120)
8333 *rc = -EINVAL;
8334 else {
8335 fan_watchdog_maxinterval = interval;
8336 tpacpi_disclose_usertask("procfs fan",
8337 "set watchdog timer to %d\n",
8338 interval);
8339 }
8340
8341 return 1;
8342}
8343
8344static int fan_write(char *buf)
8345{
8346 char *cmd;
8347 int rc = 0;
8348
8349 while (!rc && (cmd = next_cmd(&buf))) {
8350 if (!((fan_control_commands & TPACPI_FAN_CMD_LEVEL) &&
8351 fan_write_cmd_level(cmd, &rc)) &&
8352 !((fan_control_commands & TPACPI_FAN_CMD_ENABLE) &&
8353 (fan_write_cmd_enable(cmd, &rc) ||
8354 fan_write_cmd_disable(cmd, &rc) ||
8355 fan_write_cmd_watchdog(cmd, &rc))) &&
8356 !((fan_control_commands & TPACPI_FAN_CMD_SPEED) &&
8357 fan_write_cmd_speed(cmd, &rc))
8358 )
8359 rc = -EINVAL;
8360 else if (!rc)
8361 fan_watchdog_reset();
8362 }
8363
8364 return rc;
8365}
8366
8367static struct ibm_struct fan_driver_data = {
8368 .name = "fan",
8369 .read = fan_read,
8370 .write = fan_write,
8371 .exit = fan_exit,
8372 .suspend = fan_suspend,
8373 .resume = fan_resume,
8374};
8375
8376
8377
8378
8379
8380
8381struct tp_led_table {
8382 acpi_string name;
8383 int on_value;
8384 int off_value;
8385 int state;
8386};
8387
8388static struct tp_led_table led_tables[] = {
8389 [TPACPI_LED_MUTE] = {
8390 .name = "SSMS",
8391 .on_value = 1,
8392 .off_value = 0,
8393 },
8394 [TPACPI_LED_MICMUTE] = {
8395 .name = "MMTS",
8396 .on_value = 2,
8397 .off_value = 0,
8398 },
8399};
8400
8401static int mute_led_on_off(struct tp_led_table *t, bool state)
8402{
8403 acpi_handle temp;
8404 int output;
8405
8406 if (!ACPI_SUCCESS(acpi_get_handle(hkey_handle, t->name, &temp))) {
8407 pr_warn("Thinkpad ACPI has no %s interface.\n", t->name);
8408 return -EIO;
8409 }
8410
8411 if (!acpi_evalf(hkey_handle, &output, t->name, "dd",
8412 state ? t->on_value : t->off_value))
8413 return -EIO;
8414
8415 t->state = state;
8416 return state;
8417}
8418
8419int tpacpi_led_set(int whichled, bool on)
8420{
8421 struct tp_led_table *t;
8422
8423 if (whichled < 0 || whichled >= TPACPI_LED_MAX)
8424 return -EINVAL;
8425
8426 t = &led_tables[whichled];
8427 if (t->state < 0 || t->state == on)
8428 return t->state;
8429 return mute_led_on_off(t, on);
8430}
8431EXPORT_SYMBOL_GPL(tpacpi_led_set);
8432
8433static int mute_led_init(struct ibm_init_struct *iibm)
8434{
8435 acpi_handle temp;
8436 int i;
8437
8438 for (i = 0; i < TPACPI_LED_MAX; i++) {
8439 struct tp_led_table *t = &led_tables[i];
8440 if (ACPI_SUCCESS(acpi_get_handle(hkey_handle, t->name, &temp)))
8441 mute_led_on_off(t, false);
8442 else
8443 t->state = -ENODEV;
8444 }
8445 return 0;
8446}
8447
8448static void mute_led_exit(void)
8449{
8450 int i;
8451
8452 for (i = 0; i < TPACPI_LED_MAX; i++)
8453 tpacpi_led_set(i, false);
8454}
8455
8456static struct ibm_struct mute_led_driver_data = {
8457 .name = "mute_led",
8458 .exit = mute_led_exit,
8459};
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473static void tpacpi_driver_event(const unsigned int hkey_event)
8474{
8475 if (ibm_backlight_device) {
8476 switch (hkey_event) {
8477 case TP_HKEY_EV_BRGHT_UP:
8478 case TP_HKEY_EV_BRGHT_DOWN:
8479 tpacpi_brightness_notify_change();
8480 }
8481 }
8482 if (alsa_card) {
8483 switch (hkey_event) {
8484 case TP_HKEY_EV_VOL_UP:
8485 case TP_HKEY_EV_VOL_DOWN:
8486 case TP_HKEY_EV_VOL_MUTE:
8487 volume_alsa_notify_change();
8488 }
8489 }
8490}
8491
8492static void hotkey_driver_event(const unsigned int scancode)
8493{
8494 tpacpi_driver_event(TP_HKEY_EV_HOTKEY_BASE + scancode);
8495}
8496
8497
8498static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev,
8499 struct device_attribute *attr,
8500 char *buf)
8501{
8502 return snprintf(buf, PAGE_SIZE, "%s\n", TPACPI_NAME);
8503}
8504
8505static struct device_attribute dev_attr_thinkpad_acpi_pdev_name =
8506 __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL);
8507
8508
8509
8510
8511static struct proc_dir_entry *proc_dir;
8512
8513
8514
8515
8516
8517static bool force_load;
8518
8519#ifdef CONFIG_THINKPAD_ACPI_DEBUG
8520static const char * __init str_supported(int is_supported)
8521{
8522 static char text_unsupported[] __initdata = "not supported";
8523
8524 return (is_supported)? &text_unsupported[4] : &text_unsupported[0];
8525}
8526#endif
8527
8528static void ibm_exit(struct ibm_struct *ibm)
8529{
8530 dbg_printk(TPACPI_DBG_EXIT, "removing %s\n", ibm->name);
8531
8532 list_del_init(&ibm->all_drivers);
8533
8534 if (ibm->flags.acpi_notify_installed) {
8535 dbg_printk(TPACPI_DBG_EXIT,
8536 "%s: acpi_remove_notify_handler\n", ibm->name);
8537 BUG_ON(!ibm->acpi);
8538 acpi_remove_notify_handler(*ibm->acpi->handle,
8539 ibm->acpi->type,
8540 dispatch_acpi_notify);
8541 ibm->flags.acpi_notify_installed = 0;
8542 }
8543
8544 if (ibm->flags.proc_created) {
8545 dbg_printk(TPACPI_DBG_EXIT,
8546 "%s: remove_proc_entry\n", ibm->name);
8547 remove_proc_entry(ibm->name, proc_dir);
8548 ibm->flags.proc_created = 0;
8549 }
8550
8551 if (ibm->flags.acpi_driver_registered) {
8552 dbg_printk(TPACPI_DBG_EXIT,
8553 "%s: acpi_bus_unregister_driver\n", ibm->name);
8554 BUG_ON(!ibm->acpi);
8555 acpi_bus_unregister_driver(ibm->acpi->driver);
8556 kfree(ibm->acpi->driver);
8557 ibm->acpi->driver = NULL;
8558 ibm->flags.acpi_driver_registered = 0;
8559 }
8560
8561 if (ibm->flags.init_called && ibm->exit) {
8562 ibm->exit();
8563 ibm->flags.init_called = 0;
8564 }
8565
8566 dbg_printk(TPACPI_DBG_INIT, "finished removing %s\n", ibm->name);
8567}
8568
8569static int __init ibm_init(struct ibm_init_struct *iibm)
8570{
8571 int ret;
8572 struct ibm_struct *ibm = iibm->data;
8573 struct proc_dir_entry *entry;
8574
8575 BUG_ON(ibm == NULL);
8576
8577 INIT_LIST_HEAD(&ibm->all_drivers);
8578
8579 if (ibm->flags.experimental && !experimental)
8580 return 0;
8581
8582 dbg_printk(TPACPI_DBG_INIT,
8583 "probing for %s\n", ibm->name);
8584
8585 if (iibm->init) {
8586 ret = iibm->init(iibm);
8587 if (ret > 0)
8588 return 0;
8589 if (ret)
8590 return ret;
8591
8592 ibm->flags.init_called = 1;
8593 }
8594
8595 if (ibm->acpi) {
8596 if (ibm->acpi->hid) {
8597 ret = register_tpacpi_subdriver(ibm);
8598 if (ret)
8599 goto err_out;
8600 }
8601
8602 if (ibm->acpi->notify) {
8603 ret = setup_acpi_notify(ibm);
8604 if (ret == -ENODEV) {
8605 pr_notice("disabling subdriver %s\n",
8606 ibm->name);
8607 ret = 0;
8608 goto err_out;
8609 }
8610 if (ret < 0)
8611 goto err_out;
8612 }
8613 }
8614
8615 dbg_printk(TPACPI_DBG_INIT,
8616 "%s installed\n", ibm->name);
8617
8618 if (ibm->read) {
8619 umode_t mode = iibm->base_procfs_mode;
8620
8621 if (!mode)
8622 mode = S_IRUGO;
8623 if (ibm->write)
8624 mode |= S_IWUSR;
8625 entry = proc_create_data(ibm->name, mode, proc_dir,
8626 &dispatch_proc_fops, ibm);
8627 if (!entry) {
8628 pr_err("unable to create proc entry %s\n", ibm->name);
8629 ret = -ENODEV;
8630 goto err_out;
8631 }
8632 ibm->flags.proc_created = 1;
8633 }
8634
8635 list_add_tail(&ibm->all_drivers, &tpacpi_all_drivers);
8636
8637 return 0;
8638
8639err_out:
8640 dbg_printk(TPACPI_DBG_INIT,
8641 "%s: at error exit path with result %d\n",
8642 ibm->name, ret);
8643
8644 ibm_exit(ibm);
8645 return (ret < 0)? ret : 0;
8646}
8647
8648
8649
8650static bool __pure __init tpacpi_is_fw_digit(const char c)
8651{
8652 return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z');
8653}
8654
8655
8656static bool __pure __init tpacpi_is_valid_fw_id(const char* const s,
8657 const char t)
8658{
8659 return s && strlen(s) >= 8 &&
8660 tpacpi_is_fw_digit(s[0]) &&
8661 tpacpi_is_fw_digit(s[1]) &&
8662 s[2] == t &&
8663 (s[3] == 'T' || s[3] == 'N') &&
8664 tpacpi_is_fw_digit(s[4]) &&
8665 tpacpi_is_fw_digit(s[5]);
8666}
8667
8668
8669
8670
8671static int __must_check __init get_thinkpad_model_data(
8672 struct thinkpad_id_data *tp)
8673{
8674 const struct dmi_device *dev = NULL;
8675 char ec_fw_string[18];
8676 char const *s;
8677
8678 if (!tp)
8679 return -EINVAL;
8680
8681 memset(tp, 0, sizeof(*tp));
8682
8683 if (dmi_name_in_vendors("IBM"))
8684 tp->vendor = PCI_VENDOR_ID_IBM;
8685 else if (dmi_name_in_vendors("LENOVO"))
8686 tp->vendor = PCI_VENDOR_ID_LENOVO;
8687 else
8688 return 0;
8689
8690 s = dmi_get_system_info(DMI_BIOS_VERSION);
8691 tp->bios_version_str = kstrdup(s, GFP_KERNEL);
8692 if (s && !tp->bios_version_str)
8693 return -ENOMEM;
8694
8695
8696 if (!(tpacpi_is_valid_fw_id(tp->bios_version_str, 'E') ||
8697 tpacpi_is_valid_fw_id(tp->bios_version_str, 'C')))
8698 return 0;
8699
8700 tp->bios_model = tp->bios_version_str[0]
8701 | (tp->bios_version_str[1] << 8);
8702 tp->bios_release = (tp->bios_version_str[4] << 8)
8703 | tp->bios_version_str[5];
8704
8705
8706
8707
8708
8709
8710
8711
8712 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
8713 if (sscanf(dev->name,
8714 "IBM ThinkPad Embedded Controller -[%17c",
8715 ec_fw_string) == 1) {
8716 ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
8717 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
8718
8719 tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL);
8720 if (!tp->ec_version_str)
8721 return -ENOMEM;
8722
8723 if (tpacpi_is_valid_fw_id(ec_fw_string, 'H')) {
8724 tp->ec_model = ec_fw_string[0]
8725 | (ec_fw_string[1] << 8);
8726 tp->ec_release = (ec_fw_string[4] << 8)
8727 | ec_fw_string[5];
8728 } else {
8729 pr_notice("ThinkPad firmware release %s "
8730 "doesn't match the known patterns\n",
8731 ec_fw_string);
8732 pr_notice("please report this to %s\n",
8733 TPACPI_MAIL);
8734 }
8735 break;
8736 }
8737 }
8738
8739 s = dmi_get_system_info(DMI_PRODUCT_VERSION);
8740 if (s && !(strnicmp(s, "ThinkPad", 8) && strnicmp(s, "Lenovo", 6))) {
8741 tp->model_str = kstrdup(s, GFP_KERNEL);
8742 if (!tp->model_str)
8743 return -ENOMEM;
8744 } else {
8745 s = dmi_get_system_info(DMI_BIOS_VENDOR);
8746 if (s && !(strnicmp(s, "Lenovo", 6))) {
8747 tp->model_str = kstrdup(s, GFP_KERNEL);
8748 if (!tp->model_str)
8749 return -ENOMEM;
8750 }
8751 }
8752
8753 s = dmi_get_system_info(DMI_PRODUCT_NAME);
8754 tp->nummodel_str = kstrdup(s, GFP_KERNEL);
8755 if (s && !tp->nummodel_str)
8756 return -ENOMEM;
8757
8758 return 0;
8759}
8760
8761static int __init probe_for_thinkpad(void)
8762{
8763 int is_thinkpad;
8764
8765 if (acpi_disabled)
8766 return -ENODEV;
8767
8768
8769 if (!tpacpi_is_ibm() && !tpacpi_is_lenovo())
8770 return -ENODEV;
8771
8772
8773
8774
8775
8776 is_thinkpad = (thinkpad_id.model_str != NULL) ||
8777 (thinkpad_id.ec_model != 0) ||
8778 tpacpi_is_fw_known();
8779
8780
8781 tpacpi_acpi_handle_locate("ec", TPACPI_ACPI_EC_HID, &ec_handle);
8782 if (!ec_handle) {
8783 if (is_thinkpad)
8784 pr_err("Not yet supported ThinkPad detected!\n");
8785 return -ENODEV;
8786 }
8787
8788 if (!is_thinkpad && !force_load)
8789 return -ENODEV;
8790
8791 return 0;
8792}
8793
8794static void __init thinkpad_acpi_init_banner(void)
8795{
8796 pr_info("%s v%s\n", TPACPI_DESC, TPACPI_VERSION);
8797 pr_info("%s\n", TPACPI_URL);
8798
8799 pr_info("ThinkPad BIOS %s, EC %s\n",
8800 (thinkpad_id.bios_version_str) ?
8801 thinkpad_id.bios_version_str : "unknown",
8802 (thinkpad_id.ec_version_str) ?
8803 thinkpad_id.ec_version_str : "unknown");
8804
8805 BUG_ON(!thinkpad_id.vendor);
8806
8807 if (thinkpad_id.model_str)
8808 pr_info("%s %s, model %s\n",
8809 (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
8810 "IBM" : ((thinkpad_id.vendor ==
8811 PCI_VENDOR_ID_LENOVO) ?
8812 "Lenovo" : "Unknown vendor"),
8813 thinkpad_id.model_str,
8814 (thinkpad_id.nummodel_str) ?
8815 thinkpad_id.nummodel_str : "unknown");
8816}
8817
8818
8819
8820static struct ibm_init_struct ibms_init[] __initdata = {
8821 {
8822 .data = &thinkpad_acpi_driver_data,
8823 },
8824 {
8825 .init = hotkey_init,
8826 .data = &hotkey_driver_data,
8827 },
8828 {
8829 .init = bluetooth_init,
8830 .data = &bluetooth_driver_data,
8831 },
8832 {
8833 .init = wan_init,
8834 .data = &wan_driver_data,
8835 },
8836 {
8837 .init = uwb_init,
8838 .data = &uwb_driver_data,
8839 },
8840#ifdef CONFIG_THINKPAD_ACPI_VIDEO
8841 {
8842 .init = video_init,
8843 .base_procfs_mode = S_IRUSR,
8844 .data = &video_driver_data,
8845 },
8846#endif
8847 {
8848 .init = light_init,
8849 .data = &light_driver_data,
8850 },
8851 {
8852 .init = cmos_init,
8853 .data = &cmos_driver_data,
8854 },
8855 {
8856 .init = led_init,
8857 .data = &led_driver_data,
8858 },
8859 {
8860 .init = beep_init,
8861 .data = &beep_driver_data,
8862 },
8863 {
8864 .init = thermal_init,
8865 .data = &thermal_driver_data,
8866 },
8867 {
8868 .init = brightness_init,
8869 .data = &brightness_driver_data,
8870 },
8871 {
8872 .init = volume_init,
8873 .data = &volume_driver_data,
8874 },
8875 {
8876 .init = fan_init,
8877 .data = &fan_driver_data,
8878 },
8879 {
8880 .init = mute_led_init,
8881 .data = &mute_led_driver_data,
8882 },
8883};
8884
8885static int __init set_ibm_param(const char *val, struct kernel_param *kp)
8886{
8887 unsigned int i;
8888 struct ibm_struct *ibm;
8889
8890 if (!kp || !kp->name || !val)
8891 return -EINVAL;
8892
8893 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
8894 ibm = ibms_init[i].data;
8895 WARN_ON(ibm == NULL);
8896
8897 if (!ibm || !ibm->name)
8898 continue;
8899
8900 if (strcmp(ibm->name, kp->name) == 0 && ibm->write) {
8901 if (strlen(val) > sizeof(ibms_init[i].param) - 2)
8902 return -ENOSPC;
8903 strcpy(ibms_init[i].param, val);
8904 strcat(ibms_init[i].param, ",");
8905 return 0;
8906 }
8907 }
8908
8909 return -EINVAL;
8910}
8911
8912module_param(experimental, int, 0444);
8913MODULE_PARM_DESC(experimental,
8914 "Enables experimental features when non-zero");
8915
8916module_param_named(debug, dbg_level, uint, 0);
8917MODULE_PARM_DESC(debug, "Sets debug level bit-mask");
8918
8919module_param(force_load, bool, 0444);
8920MODULE_PARM_DESC(force_load,
8921 "Attempts to load the driver even on a "
8922 "mis-identified ThinkPad when true");
8923
8924module_param_named(fan_control, fan_control_allowed, bool, 0444);
8925MODULE_PARM_DESC(fan_control,
8926 "Enables setting fan parameters features when true");
8927
8928module_param_named(brightness_mode, brightness_mode, uint, 0444);
8929MODULE_PARM_DESC(brightness_mode,
8930 "Selects brightness control strategy: "
8931 "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM");
8932
8933module_param(brightness_enable, uint, 0444);
8934MODULE_PARM_DESC(brightness_enable,
8935 "Enables backlight control when 1, disables when 0");
8936
8937#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT
8938module_param_named(volume_mode, volume_mode, uint, 0444);
8939MODULE_PARM_DESC(volume_mode,
8940 "Selects volume control strategy: "
8941 "0=auto, 1=EC, 2=N/A, 3=EC+NVRAM");
8942
8943module_param_named(volume_capabilities, volume_capabilities, uint, 0444);
8944MODULE_PARM_DESC(volume_capabilities,
8945 "Selects the mixer capabilites: "
8946 "0=auto, 1=volume and mute, 2=mute only");
8947
8948module_param_named(volume_control, volume_control_allowed, bool, 0444);
8949MODULE_PARM_DESC(volume_control,
8950 "Enables software override for the console audio "
8951 "control when true");
8952
8953
8954module_param_named(index, alsa_index, int, 0444);
8955MODULE_PARM_DESC(index, "ALSA index for the ACPI EC Mixer");
8956module_param_named(id, alsa_id, charp, 0444);
8957MODULE_PARM_DESC(id, "ALSA id for the ACPI EC Mixer");
8958module_param_named(enable, alsa_enable, bool, 0444);
8959MODULE_PARM_DESC(enable, "Enable the ALSA interface for the ACPI EC Mixer");
8960#endif
8961
8962#define TPACPI_PARAM(feature) \
8963 module_param_call(feature, set_ibm_param, NULL, NULL, 0); \
8964 MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command " \
8965 "at module load, see documentation")
8966
8967TPACPI_PARAM(hotkey);
8968TPACPI_PARAM(bluetooth);
8969TPACPI_PARAM(video);
8970TPACPI_PARAM(light);
8971TPACPI_PARAM(cmos);
8972TPACPI_PARAM(led);
8973TPACPI_PARAM(beep);
8974TPACPI_PARAM(brightness);
8975TPACPI_PARAM(volume);
8976TPACPI_PARAM(fan);
8977
8978#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
8979module_param(dbg_wlswemul, uint, 0444);
8980MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation");
8981module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0);
8982MODULE_PARM_DESC(wlsw_state,
8983 "Initial state of the emulated WLSW switch");
8984
8985module_param(dbg_bluetoothemul, uint, 0444);
8986MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation");
8987module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0);
8988MODULE_PARM_DESC(bluetooth_state,
8989 "Initial state of the emulated bluetooth switch");
8990
8991module_param(dbg_wwanemul, uint, 0444);
8992MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation");
8993module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0);
8994MODULE_PARM_DESC(wwan_state,
8995 "Initial state of the emulated WWAN switch");
8996
8997module_param(dbg_uwbemul, uint, 0444);
8998MODULE_PARM_DESC(dbg_uwbemul, "Enables UWB switch emulation");
8999module_param_named(uwb_state, tpacpi_uwb_emulstate, bool, 0);
9000MODULE_PARM_DESC(uwb_state,
9001 "Initial state of the emulated UWB switch");
9002#endif
9003
9004static void thinkpad_acpi_module_exit(void)
9005{
9006 struct ibm_struct *ibm, *itmp;
9007
9008 tpacpi_lifecycle = TPACPI_LIFE_EXITING;
9009
9010 list_for_each_entry_safe_reverse(ibm, itmp,
9011 &tpacpi_all_drivers,
9012 all_drivers) {
9013 ibm_exit(ibm);
9014 }
9015
9016 dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
9017
9018 if (tpacpi_inputdev) {
9019 if (tp_features.input_device_registered)
9020 input_unregister_device(tpacpi_inputdev);
9021 else
9022 input_free_device(tpacpi_inputdev);
9023 kfree(hotkey_keycode_map);
9024 }
9025
9026 if (tpacpi_hwmon)
9027 hwmon_device_unregister(tpacpi_hwmon);
9028
9029 if (tp_features.sensors_pdev_attrs_registered)
9030 device_remove_file(&tpacpi_sensors_pdev->dev,
9031 &dev_attr_thinkpad_acpi_pdev_name);
9032 if (tpacpi_sensors_pdev)
9033 platform_device_unregister(tpacpi_sensors_pdev);
9034 if (tpacpi_pdev)
9035 platform_device_unregister(tpacpi_pdev);
9036
9037 if (tp_features.sensors_pdrv_attrs_registered)
9038 tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver);
9039 if (tp_features.platform_drv_attrs_registered)
9040 tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
9041
9042 if (tp_features.sensors_pdrv_registered)
9043 platform_driver_unregister(&tpacpi_hwmon_pdriver);
9044
9045 if (tp_features.platform_drv_registered)
9046 platform_driver_unregister(&tpacpi_pdriver);
9047
9048 if (proc_dir)
9049 remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir);
9050
9051 if (tpacpi_wq)
9052 destroy_workqueue(tpacpi_wq);
9053
9054 kfree(thinkpad_id.bios_version_str);
9055 kfree(thinkpad_id.ec_version_str);
9056 kfree(thinkpad_id.model_str);
9057 kfree(thinkpad_id.nummodel_str);
9058}
9059
9060
9061static int __init thinkpad_acpi_module_init(void)
9062{
9063 int ret, i;
9064
9065 tpacpi_lifecycle = TPACPI_LIFE_INIT;
9066
9067
9068
9069 ret = get_thinkpad_model_data(&thinkpad_id);
9070 if (ret) {
9071 pr_err("unable to get DMI data: %d\n", ret);
9072 thinkpad_acpi_module_exit();
9073 return ret;
9074 }
9075 ret = probe_for_thinkpad();
9076 if (ret) {
9077 thinkpad_acpi_module_exit();
9078 return ret;
9079 }
9080
9081
9082
9083 thinkpad_acpi_init_banner();
9084 tpacpi_check_outdated_fw();
9085
9086 TPACPI_ACPIHANDLE_INIT(ecrd);
9087 TPACPI_ACPIHANDLE_INIT(ecwr);
9088
9089 tpacpi_wq = create_singlethread_workqueue(TPACPI_WORKQUEUE_NAME);
9090 if (!tpacpi_wq) {
9091 thinkpad_acpi_module_exit();
9092 return -ENOMEM;
9093 }
9094
9095 proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir);
9096 if (!proc_dir) {
9097 pr_err("unable to create proc dir " TPACPI_PROC_DIR "\n");
9098 thinkpad_acpi_module_exit();
9099 return -ENODEV;
9100 }
9101
9102 ret = platform_driver_register(&tpacpi_pdriver);
9103 if (ret) {
9104 pr_err("unable to register main platform driver\n");
9105 thinkpad_acpi_module_exit();
9106 return ret;
9107 }
9108 tp_features.platform_drv_registered = 1;
9109
9110 ret = platform_driver_register(&tpacpi_hwmon_pdriver);
9111 if (ret) {
9112 pr_err("unable to register hwmon platform driver\n");
9113 thinkpad_acpi_module_exit();
9114 return ret;
9115 }
9116 tp_features.sensors_pdrv_registered = 1;
9117
9118 ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
9119 if (!ret) {
9120 tp_features.platform_drv_attrs_registered = 1;
9121 ret = tpacpi_create_driver_attributes(
9122 &tpacpi_hwmon_pdriver.driver);
9123 }
9124 if (ret) {
9125 pr_err("unable to create sysfs driver attributes\n");
9126 thinkpad_acpi_module_exit();
9127 return ret;
9128 }
9129 tp_features.sensors_pdrv_attrs_registered = 1;
9130
9131
9132
9133 tpacpi_pdev = platform_device_register_simple(TPACPI_DRVR_NAME, -1,
9134 NULL, 0);
9135 if (IS_ERR(tpacpi_pdev)) {
9136 ret = PTR_ERR(tpacpi_pdev);
9137 tpacpi_pdev = NULL;
9138 pr_err("unable to register platform device\n");
9139 thinkpad_acpi_module_exit();
9140 return ret;
9141 }
9142 tpacpi_sensors_pdev = platform_device_register_simple(
9143 TPACPI_HWMON_DRVR_NAME,
9144 -1, NULL, 0);
9145 if (IS_ERR(tpacpi_sensors_pdev)) {
9146 ret = PTR_ERR(tpacpi_sensors_pdev);
9147 tpacpi_sensors_pdev = NULL;
9148 pr_err("unable to register hwmon platform device\n");
9149 thinkpad_acpi_module_exit();
9150 return ret;
9151 }
9152 ret = device_create_file(&tpacpi_sensors_pdev->dev,
9153 &dev_attr_thinkpad_acpi_pdev_name);
9154 if (ret) {
9155 pr_err("unable to create sysfs hwmon device attributes\n");
9156 thinkpad_acpi_module_exit();
9157 return ret;
9158 }
9159 tp_features.sensors_pdev_attrs_registered = 1;
9160 tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev);
9161 if (IS_ERR(tpacpi_hwmon)) {
9162 ret = PTR_ERR(tpacpi_hwmon);
9163 tpacpi_hwmon = NULL;
9164 pr_err("unable to register hwmon device\n");
9165 thinkpad_acpi_module_exit();
9166 return ret;
9167 }
9168 mutex_init(&tpacpi_inputdev_send_mutex);
9169 tpacpi_inputdev = input_allocate_device();
9170 if (!tpacpi_inputdev) {
9171 thinkpad_acpi_module_exit();
9172 return -ENOMEM;
9173 } else {
9174
9175 tpacpi_inputdev->name = "ThinkPad Extra Buttons";
9176 tpacpi_inputdev->phys = TPACPI_DRVR_NAME "/input0";
9177 tpacpi_inputdev->id.bustype = BUS_HOST;
9178 tpacpi_inputdev->id.vendor = thinkpad_id.vendor;
9179 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
9180 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
9181 tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev;
9182 }
9183
9184
9185 tpacpi_detect_brightness_capabilities();
9186
9187
9188 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
9189 ret = ibm_init(&ibms_init[i]);
9190 if (ret >= 0 && *ibms_init[i].param)
9191 ret = ibms_init[i].data->write(ibms_init[i].param);
9192 if (ret < 0) {
9193 thinkpad_acpi_module_exit();
9194 return ret;
9195 }
9196 }
9197
9198 tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
9199
9200 ret = input_register_device(tpacpi_inputdev);
9201 if (ret < 0) {
9202 pr_err("unable to register input device\n");
9203 thinkpad_acpi_module_exit();
9204 return ret;
9205 } else {
9206 tp_features.input_device_registered = 1;
9207 }
9208
9209 return 0;
9210}
9211
9212MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
9213
9214
9215
9216
9217
9218
9219
9220
9221MODULE_DEVICE_TABLE(acpi, ibm_htk_device_ids);
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232#define IBM_BIOS_MODULE_ALIAS(__type) \
9233 MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW*")
9234
9235
9236
9237
9238IBM_BIOS_MODULE_ALIAS("I[MU]");
9239
9240MODULE_AUTHOR("Borislav Deianov <borislav@users.sf.net>");
9241MODULE_AUTHOR("Henrique de Moraes Holschuh <hmh@hmh.eng.br>");
9242MODULE_DESCRIPTION(TPACPI_DESC);
9243MODULE_VERSION(TPACPI_VERSION);
9244MODULE_LICENSE("GPL");
9245
9246module_init(thinkpad_acpi_module_init);
9247module_exit(thinkpad_acpi_module_exit);
9248