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