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