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