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