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