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