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