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