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