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