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