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 mode_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 int tpacpi_wlsw_emulstate;
382static int dbg_bluetoothemul;
383static int tpacpi_bluetooth_emulstate;
384static int dbg_wwanemul;
385static int tpacpi_wwan_emulstate;
386static int dbg_uwbemul;
387static int 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, must_reset;
2460 unsigned int poll_freq;
2461
2462 mutex_lock(&hotkey_thread_mutex);
2463
2464 if (tpacpi_lifecycle == TPACPI_LIFE_EXITING)
2465 goto exit;
2466
2467 set_freezable();
2468
2469 so = 0;
2470 si = 1;
2471 t = 0;
2472
2473
2474 mutex_lock(&hotkey_thread_data_mutex);
2475 change_detector = hotkey_config_change;
2476 poll_mask = hotkey_source_mask;
2477 event_mask = hotkey_source_mask &
2478 (hotkey_driver_mask | hotkey_user_mask);
2479 poll_freq = hotkey_poll_freq;
2480 mutex_unlock(&hotkey_thread_data_mutex);
2481 hotkey_read_nvram(&s[so], poll_mask);
2482
2483 while (!kthread_should_stop()) {
2484 if (t == 0) {
2485 if (likely(poll_freq))
2486 t = 1000/poll_freq;
2487 else
2488 t = 100;
2489 }
2490 t = msleep_interruptible(t);
2491 if (unlikely(kthread_should_stop()))
2492 break;
2493 must_reset = try_to_freeze();
2494 if (t > 0 && !must_reset)
2495 continue;
2496
2497 mutex_lock(&hotkey_thread_data_mutex);
2498 if (must_reset || hotkey_config_change != change_detector) {
2499
2500 si = so;
2501 t = 0;
2502 change_detector = hotkey_config_change;
2503 }
2504 poll_mask = hotkey_source_mask;
2505 event_mask = hotkey_source_mask &
2506 (hotkey_driver_mask | hotkey_user_mask);
2507 poll_freq = hotkey_poll_freq;
2508 mutex_unlock(&hotkey_thread_data_mutex);
2509
2510 if (likely(poll_mask)) {
2511 hotkey_read_nvram(&s[si], poll_mask);
2512 if (likely(si != so)) {
2513 hotkey_compare_and_issue_event(&s[so], &s[si],
2514 event_mask);
2515 }
2516 }
2517
2518 so = si;
2519 si ^= 1;
2520 }
2521
2522exit:
2523 mutex_unlock(&hotkey_thread_mutex);
2524 return 0;
2525}
2526
2527
2528static void hotkey_poll_stop_sync(void)
2529{
2530 if (tpacpi_hotkey_task) {
2531 if (frozen(tpacpi_hotkey_task) ||
2532 freezing(tpacpi_hotkey_task))
2533 thaw_process(tpacpi_hotkey_task);
2534
2535 kthread_stop(tpacpi_hotkey_task);
2536 tpacpi_hotkey_task = NULL;
2537 mutex_lock(&hotkey_thread_mutex);
2538
2539 mutex_unlock(&hotkey_thread_mutex);
2540 }
2541}
2542
2543
2544static void hotkey_poll_setup(const bool may_warn)
2545{
2546 const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask;
2547 const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask;
2548
2549 if (hotkey_poll_freq > 0 &&
2550 (poll_driver_mask ||
2551 (poll_user_mask && tpacpi_inputdev->users > 0))) {
2552 if (!tpacpi_hotkey_task) {
2553 tpacpi_hotkey_task = kthread_run(hotkey_kthread,
2554 NULL, TPACPI_NVRAM_KTHREAD_NAME);
2555 if (IS_ERR(tpacpi_hotkey_task)) {
2556 tpacpi_hotkey_task = NULL;
2557 pr_err("could not create kernel thread "
2558 "for hotkey polling\n");
2559 }
2560 }
2561 } else {
2562 hotkey_poll_stop_sync();
2563 if (may_warn && (poll_driver_mask || poll_user_mask) &&
2564 hotkey_poll_freq == 0) {
2565 pr_notice("hot keys 0x%08x and/or events 0x%08x "
2566 "require polling, which is currently "
2567 "disabled\n",
2568 poll_user_mask, poll_driver_mask);
2569 }
2570 }
2571}
2572
2573static void hotkey_poll_setup_safe(const bool may_warn)
2574{
2575 mutex_lock(&hotkey_mutex);
2576 hotkey_poll_setup(may_warn);
2577 mutex_unlock(&hotkey_mutex);
2578}
2579
2580
2581static void hotkey_poll_set_freq(unsigned int freq)
2582{
2583 if (!freq)
2584 hotkey_poll_stop_sync();
2585
2586 hotkey_poll_freq = freq;
2587}
2588
2589#else
2590
2591static void hotkey_poll_setup(const bool __unused)
2592{
2593}
2594
2595static void hotkey_poll_setup_safe(const bool __unused)
2596{
2597}
2598
2599#endif
2600
2601static int hotkey_inputdev_open(struct input_dev *dev)
2602{
2603 switch (tpacpi_lifecycle) {
2604 case TPACPI_LIFE_INIT:
2605 case TPACPI_LIFE_RUNNING:
2606 hotkey_poll_setup_safe(false);
2607 return 0;
2608 case TPACPI_LIFE_EXITING:
2609 return -EBUSY;
2610 }
2611
2612
2613 BUG();
2614 return -EBUSY;
2615}
2616
2617static void hotkey_inputdev_close(struct input_dev *dev)
2618{
2619
2620 if (tpacpi_lifecycle != TPACPI_LIFE_EXITING &&
2621 !(hotkey_source_mask & hotkey_driver_mask))
2622 hotkey_poll_setup_safe(false);
2623}
2624
2625
2626static ssize_t hotkey_enable_show(struct device *dev,
2627 struct device_attribute *attr,
2628 char *buf)
2629{
2630 int res, status;
2631
2632 printk_deprecated_attribute("hotkey_enable",
2633 "Hotkey reporting is always enabled");
2634
2635 res = hotkey_status_get(&status);
2636 if (res)
2637 return res;
2638
2639 return snprintf(buf, PAGE_SIZE, "%d\n", status);
2640}
2641
2642static ssize_t hotkey_enable_store(struct device *dev,
2643 struct device_attribute *attr,
2644 const char *buf, size_t count)
2645{
2646 unsigned long t;
2647
2648 printk_deprecated_attribute("hotkey_enable",
2649 "Hotkeys can be disabled through hotkey_mask");
2650
2651 if (parse_strtoul(buf, 1, &t))
2652 return -EINVAL;
2653
2654 if (t == 0)
2655 return -EPERM;
2656
2657 return count;
2658}
2659
2660static struct device_attribute dev_attr_hotkey_enable =
2661 __ATTR(hotkey_enable, S_IWUSR | S_IRUGO,
2662 hotkey_enable_show, hotkey_enable_store);
2663
2664
2665static ssize_t hotkey_mask_show(struct device *dev,
2666 struct device_attribute *attr,
2667 char *buf)
2668{
2669 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_user_mask);
2670}
2671
2672static ssize_t hotkey_mask_store(struct device *dev,
2673 struct device_attribute *attr,
2674 const char *buf, size_t count)
2675{
2676 unsigned long t;
2677 int res;
2678
2679 if (parse_strtoul(buf, 0xffffffffUL, &t))
2680 return -EINVAL;
2681
2682 if (mutex_lock_killable(&hotkey_mutex))
2683 return -ERESTARTSYS;
2684
2685 res = hotkey_user_mask_set(t);
2686
2687#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2688 hotkey_poll_setup(true);
2689#endif
2690
2691 mutex_unlock(&hotkey_mutex);
2692
2693 tpacpi_disclose_usertask("hotkey_mask", "set to 0x%08lx\n", t);
2694
2695 return (res) ? res : count;
2696}
2697
2698static struct device_attribute dev_attr_hotkey_mask =
2699 __ATTR(hotkey_mask, S_IWUSR | S_IRUGO,
2700 hotkey_mask_show, hotkey_mask_store);
2701
2702
2703static ssize_t hotkey_bios_enabled_show(struct device *dev,
2704 struct device_attribute *attr,
2705 char *buf)
2706{
2707 return sprintf(buf, "0\n");
2708}
2709
2710static struct device_attribute dev_attr_hotkey_bios_enabled =
2711 __ATTR(hotkey_bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL);
2712
2713
2714static ssize_t hotkey_bios_mask_show(struct device *dev,
2715 struct device_attribute *attr,
2716 char *buf)
2717{
2718 printk_deprecated_attribute("hotkey_bios_mask",
2719 "This attribute is useless.");
2720 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask);
2721}
2722
2723static struct device_attribute dev_attr_hotkey_bios_mask =
2724 __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL);
2725
2726
2727static ssize_t hotkey_all_mask_show(struct device *dev,
2728 struct device_attribute *attr,
2729 char *buf)
2730{
2731 return snprintf(buf, PAGE_SIZE, "0x%08x\n",
2732 hotkey_all_mask | hotkey_source_mask);
2733}
2734
2735static struct device_attribute dev_attr_hotkey_all_mask =
2736 __ATTR(hotkey_all_mask, S_IRUGO, hotkey_all_mask_show, NULL);
2737
2738
2739static ssize_t hotkey_recommended_mask_show(struct device *dev,
2740 struct device_attribute *attr,
2741 char *buf)
2742{
2743 return snprintf(buf, PAGE_SIZE, "0x%08x\n",
2744 (hotkey_all_mask | hotkey_source_mask)
2745 & ~hotkey_reserved_mask);
2746}
2747
2748static struct device_attribute dev_attr_hotkey_recommended_mask =
2749 __ATTR(hotkey_recommended_mask, S_IRUGO,
2750 hotkey_recommended_mask_show, NULL);
2751
2752#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2753
2754
2755static ssize_t hotkey_source_mask_show(struct device *dev,
2756 struct device_attribute *attr,
2757 char *buf)
2758{
2759 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_source_mask);
2760}
2761
2762static ssize_t hotkey_source_mask_store(struct device *dev,
2763 struct device_attribute *attr,
2764 const char *buf, size_t count)
2765{
2766 unsigned long t;
2767 u32 r_ev;
2768 int rc;
2769
2770 if (parse_strtoul(buf, 0xffffffffUL, &t) ||
2771 ((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0))
2772 return -EINVAL;
2773
2774 if (mutex_lock_killable(&hotkey_mutex))
2775 return -ERESTARTSYS;
2776
2777 HOTKEY_CONFIG_CRITICAL_START
2778 hotkey_source_mask = t;
2779 HOTKEY_CONFIG_CRITICAL_END
2780
2781 rc = hotkey_mask_set((hotkey_user_mask | hotkey_driver_mask) &
2782 ~hotkey_source_mask);
2783 hotkey_poll_setup(true);
2784
2785
2786 r_ev = hotkey_driver_mask & ~(hotkey_acpi_mask & hotkey_all_mask)
2787 & ~hotkey_source_mask & TPACPI_HKEY_NVRAM_KNOWN_MASK;
2788
2789 mutex_unlock(&hotkey_mutex);
2790
2791 if (rc < 0)
2792 pr_err("hotkey_source_mask: "
2793 "failed to update the firmware event mask!\n");
2794
2795 if (r_ev)
2796 pr_notice("hotkey_source_mask: "
2797 "some important events were disabled: 0x%04x\n",
2798 r_ev);
2799
2800 tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t);
2801
2802 return (rc < 0) ? rc : count;
2803}
2804
2805static struct device_attribute dev_attr_hotkey_source_mask =
2806 __ATTR(hotkey_source_mask, S_IWUSR | S_IRUGO,
2807 hotkey_source_mask_show, hotkey_source_mask_store);
2808
2809
2810static ssize_t hotkey_poll_freq_show(struct device *dev,
2811 struct device_attribute *attr,
2812 char *buf)
2813{
2814 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_poll_freq);
2815}
2816
2817static ssize_t hotkey_poll_freq_store(struct device *dev,
2818 struct device_attribute *attr,
2819 const char *buf, size_t count)
2820{
2821 unsigned long t;
2822
2823 if (parse_strtoul(buf, 25, &t))
2824 return -EINVAL;
2825
2826 if (mutex_lock_killable(&hotkey_mutex))
2827 return -ERESTARTSYS;
2828
2829 hotkey_poll_set_freq(t);
2830 hotkey_poll_setup(true);
2831
2832 mutex_unlock(&hotkey_mutex);
2833
2834 tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t);
2835
2836 return count;
2837}
2838
2839static struct device_attribute dev_attr_hotkey_poll_freq =
2840 __ATTR(hotkey_poll_freq, S_IWUSR | S_IRUGO,
2841 hotkey_poll_freq_show, hotkey_poll_freq_store);
2842
2843#endif
2844
2845
2846static ssize_t hotkey_radio_sw_show(struct device *dev,
2847 struct device_attribute *attr,
2848 char *buf)
2849{
2850 int res;
2851 res = hotkey_get_wlsw();
2852 if (res < 0)
2853 return res;
2854
2855
2856 tpacpi_rfk_update_hwblock_state((res == TPACPI_RFK_RADIO_OFF));
2857
2858 return snprintf(buf, PAGE_SIZE, "%d\n",
2859 (res == TPACPI_RFK_RADIO_OFF) ? 0 : 1);
2860}
2861
2862static struct device_attribute dev_attr_hotkey_radio_sw =
2863 __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL);
2864
2865static void hotkey_radio_sw_notify_change(void)
2866{
2867 if (tp_features.hotkey_wlsw)
2868 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
2869 "hotkey_radio_sw");
2870}
2871
2872
2873static ssize_t hotkey_tablet_mode_show(struct device *dev,
2874 struct device_attribute *attr,
2875 char *buf)
2876{
2877 int res, s;
2878 res = hotkey_get_tablet_mode(&s);
2879 if (res < 0)
2880 return res;
2881
2882 return snprintf(buf, PAGE_SIZE, "%d\n", !!s);
2883}
2884
2885static struct device_attribute dev_attr_hotkey_tablet_mode =
2886 __ATTR(hotkey_tablet_mode, S_IRUGO, hotkey_tablet_mode_show, NULL);
2887
2888static void hotkey_tablet_mode_notify_change(void)
2889{
2890 if (tp_features.hotkey_tablet)
2891 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
2892 "hotkey_tablet_mode");
2893}
2894
2895
2896static ssize_t hotkey_report_mode_show(struct device *dev,
2897 struct device_attribute *attr,
2898 char *buf)
2899{
2900 return snprintf(buf, PAGE_SIZE, "%d\n",
2901 (hotkey_report_mode != 0) ? hotkey_report_mode : 1);
2902}
2903
2904static struct device_attribute dev_attr_hotkey_report_mode =
2905 __ATTR(hotkey_report_mode, S_IRUGO, hotkey_report_mode_show, NULL);
2906
2907
2908static ssize_t hotkey_wakeup_reason_show(struct device *dev,
2909 struct device_attribute *attr,
2910 char *buf)
2911{
2912 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_wakeup_reason);
2913}
2914
2915static struct device_attribute dev_attr_hotkey_wakeup_reason =
2916 __ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL);
2917
2918static void hotkey_wakeup_reason_notify_change(void)
2919{
2920 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
2921 "wakeup_reason");
2922}
2923
2924
2925static ssize_t hotkey_wakeup_hotunplug_complete_show(struct device *dev,
2926 struct device_attribute *attr,
2927 char *buf)
2928{
2929 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_autosleep_ack);
2930}
2931
2932static struct device_attribute dev_attr_hotkey_wakeup_hotunplug_complete =
2933 __ATTR(wakeup_hotunplug_complete, S_IRUGO,
2934 hotkey_wakeup_hotunplug_complete_show, NULL);
2935
2936static void hotkey_wakeup_hotunplug_complete_notify_change(void)
2937{
2938 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
2939 "wakeup_hotunplug_complete");
2940}
2941
2942
2943
2944static struct attribute *hotkey_attributes[] __initdata = {
2945 &dev_attr_hotkey_enable.attr,
2946 &dev_attr_hotkey_bios_enabled.attr,
2947 &dev_attr_hotkey_bios_mask.attr,
2948 &dev_attr_hotkey_report_mode.attr,
2949 &dev_attr_hotkey_wakeup_reason.attr,
2950 &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
2951 &dev_attr_hotkey_mask.attr,
2952 &dev_attr_hotkey_all_mask.attr,
2953 &dev_attr_hotkey_recommended_mask.attr,
2954#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2955 &dev_attr_hotkey_source_mask.attr,
2956 &dev_attr_hotkey_poll_freq.attr,
2957#endif
2958};
2959
2960
2961
2962
2963static void tpacpi_send_radiosw_update(void)
2964{
2965 int wlsw;
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978 wlsw = hotkey_get_wlsw();
2979
2980
2981 if (wlsw == TPACPI_RFK_RADIO_OFF)
2982 tpacpi_rfk_update_hwblock_state(true);
2983
2984
2985 tpacpi_rfk_update_swstate_all();
2986
2987
2988 if (wlsw == TPACPI_RFK_RADIO_ON)
2989 tpacpi_rfk_update_hwblock_state(false);
2990
2991
2992 if (!(wlsw < 0)) {
2993 mutex_lock(&tpacpi_inputdev_send_mutex);
2994
2995 input_report_switch(tpacpi_inputdev,
2996 SW_RFKILL_ALL, (wlsw > 0));
2997 input_sync(tpacpi_inputdev);
2998
2999 mutex_unlock(&tpacpi_inputdev_send_mutex);
3000 }
3001
3002
3003
3004
3005
3006 hotkey_radio_sw_notify_change();
3007}
3008
3009static void hotkey_exit(void)
3010{
3011#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
3012 mutex_lock(&hotkey_mutex);
3013 hotkey_poll_stop_sync();
3014 mutex_unlock(&hotkey_mutex);
3015#endif
3016
3017 if (hotkey_dev_attributes)
3018 delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
3019
3020 kfree(hotkey_keycode_map);
3021
3022 dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,
3023 "restoring original HKEY status and mask\n");
3024
3025
3026 if (((tp_features.hotkey_mask &&
3027 hotkey_mask_set(hotkey_orig_mask)) |
3028 hotkey_status_set(false)) != 0)
3029 pr_err("failed to restore hot key mask "
3030 "to BIOS defaults\n");
3031}
3032
3033static void __init hotkey_unmap(const unsigned int scancode)
3034{
3035 if (hotkey_keycode_map[scancode] != KEY_RESERVED) {
3036 clear_bit(hotkey_keycode_map[scancode],
3037 tpacpi_inputdev->keybit);
3038 hotkey_keycode_map[scancode] = KEY_RESERVED;
3039 }
3040}
3041
3042
3043
3044
3045
3046
3047#define TPACPI_HK_Q_INIMASK 0x0001
3048
3049static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = {
3050 TPACPI_Q_IBM('I', 'H', TPACPI_HK_Q_INIMASK),
3051 TPACPI_Q_IBM('I', 'N', TPACPI_HK_Q_INIMASK),
3052 TPACPI_Q_IBM('I', 'D', TPACPI_HK_Q_INIMASK),
3053 TPACPI_Q_IBM('I', 'W', TPACPI_HK_Q_INIMASK),
3054 TPACPI_Q_IBM('I', 'V', TPACPI_HK_Q_INIMASK),
3055 TPACPI_Q_IBM('1', '0', TPACPI_HK_Q_INIMASK),
3056 TPACPI_Q_IBM('K', 'U', TPACPI_HK_Q_INIMASK),
3057 TPACPI_Q_IBM('K', 'X', TPACPI_HK_Q_INIMASK),
3058 TPACPI_Q_IBM('K', 'Y', TPACPI_HK_Q_INIMASK),
3059 TPACPI_Q_IBM('1', 'B', TPACPI_HK_Q_INIMASK),
3060 TPACPI_Q_IBM('1', '3', TPACPI_HK_Q_INIMASK),
3061 TPACPI_Q_IBM('1', 'E', TPACPI_HK_Q_INIMASK),
3062 TPACPI_Q_IBM('1', 'C', TPACPI_HK_Q_INIMASK),
3063 TPACPI_Q_IBM('1', 'F', TPACPI_HK_Q_INIMASK),
3064 TPACPI_Q_IBM('I', 'Y', TPACPI_HK_Q_INIMASK),
3065 TPACPI_Q_IBM('K', 'Z', TPACPI_HK_Q_INIMASK),
3066 TPACPI_Q_IBM('1', '6', TPACPI_HK_Q_INIMASK),
3067 TPACPI_Q_IBM('I', 'Z', TPACPI_HK_Q_INIMASK),
3068 TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK),
3069};
3070
3071typedef u16 tpacpi_keymap_entry_t;
3072typedef tpacpi_keymap_entry_t tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN];
3073
3074static int __init hotkey_init(struct ibm_init_struct *iibm)
3075{
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106 enum keymap_index {
3107 TPACPI_KEYMAP_IBM_GENERIC = 0,
3108 TPACPI_KEYMAP_LENOVO_GENERIC,
3109 };
3110
3111 static const tpacpi_keymap_t tpacpi_keymaps[] __initconst = {
3112
3113 [TPACPI_KEYMAP_IBM_GENERIC] = {
3114
3115 KEY_FN_F1, KEY_BATTERY, KEY_COFFEE, KEY_SLEEP,
3116 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
3117 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
3118
3119
3120 KEY_UNKNOWN,
3121 KEY_UNKNOWN,
3122 KEY_UNKNOWN,
3123
3124
3125 KEY_RESERVED,
3126 KEY_RESERVED,
3127
3128
3129 KEY_RESERVED,
3130
3131 KEY_UNKNOWN,
3132 KEY_ZOOM,
3133
3134
3135
3136
3137 KEY_RESERVED,
3138 KEY_RESERVED,
3139 KEY_RESERVED,
3140
3141 KEY_VENDOR,
3142
3143
3144 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
3145 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
3146 },
3147
3148
3149 [TPACPI_KEYMAP_LENOVO_GENERIC] = {
3150
3151 KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP,
3152 KEY_WLAN, KEY_CAMERA, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
3153 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
3154
3155
3156 KEY_UNKNOWN,
3157 KEY_UNKNOWN,
3158 KEY_UNKNOWN,
3159
3160
3161
3162
3163 KEY_BRIGHTNESSUP,
3164 KEY_BRIGHTNESSDOWN,
3165
3166 KEY_RESERVED,
3167
3168 KEY_UNKNOWN,
3169 KEY_ZOOM,
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182 KEY_RESERVED,
3183 KEY_RESERVED,
3184 KEY_RESERVED,
3185
3186 KEY_VENDOR,
3187
3188
3189 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
3190 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
3191 },
3192 };
3193
3194 static const struct tpacpi_quirk tpacpi_keymap_qtable[] __initconst = {
3195
3196 {
3197 .vendor = PCI_VENDOR_ID_IBM,
3198 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
3199 .quirks = TPACPI_KEYMAP_IBM_GENERIC,
3200 },
3201 {
3202 .vendor = PCI_VENDOR_ID_LENOVO,
3203 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
3204 .quirks = TPACPI_KEYMAP_LENOVO_GENERIC,
3205 },
3206 };
3207
3208#define TPACPI_HOTKEY_MAP_SIZE sizeof(tpacpi_keymap_t)
3209#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(tpacpi_keymap_entry_t)
3210
3211 int res, i;
3212 int status;
3213 int hkeyv;
3214 bool radiosw_state = false;
3215 bool tabletsw_state = false;
3216
3217 unsigned long quirks;
3218 unsigned long keymap_id;
3219
3220 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3221 "initializing hotkey subdriver\n");
3222
3223 BUG_ON(!tpacpi_inputdev);
3224 BUG_ON(tpacpi_inputdev->open != NULL ||
3225 tpacpi_inputdev->close != NULL);
3226
3227 TPACPI_ACPIHANDLE_INIT(hkey);
3228 mutex_init(&hotkey_mutex);
3229
3230#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
3231 mutex_init(&hotkey_thread_mutex);
3232 mutex_init(&hotkey_thread_data_mutex);
3233#endif
3234
3235
3236 tp_features.hotkey = hkey_handle != NULL;
3237
3238 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3239 "hotkeys are %s\n",
3240 str_supported(tp_features.hotkey));
3241
3242 if (!tp_features.hotkey)
3243 return 1;
3244
3245 quirks = tpacpi_check_quirks(tpacpi_hotkey_qtable,
3246 ARRAY_SIZE(tpacpi_hotkey_qtable));
3247
3248 tpacpi_disable_brightness_delay();
3249
3250
3251
3252 hotkey_dev_attributes = create_attr_set(
3253 ARRAY_SIZE(hotkey_attributes) + 2,
3254 NULL);
3255 if (!hotkey_dev_attributes)
3256 return -ENOMEM;
3257 res = add_many_to_attr_set(hotkey_dev_attributes,
3258 hotkey_attributes,
3259 ARRAY_SIZE(hotkey_attributes));
3260 if (res)
3261 goto err_exit;
3262
3263
3264
3265
3266 if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
3267 if ((hkeyv >> 8) != 1) {
3268 pr_err("unknown version of the HKEY interface: 0x%x\n",
3269 hkeyv);
3270 pr_err("please report this to %s\n", TPACPI_MAIL);
3271 } else {
3272
3273
3274
3275
3276 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3277 "firmware HKEY interface version: 0x%x\n",
3278 hkeyv);
3279
3280
3281 if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
3282 "MHKA", "qd")) {
3283 pr_err("missing MHKA handler, "
3284 "please report this to %s\n",
3285 TPACPI_MAIL);
3286
3287 hotkey_all_mask = 0x080cU;
3288 } else {
3289 tp_features.hotkey_mask = 1;
3290 }
3291 }
3292 }
3293
3294 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3295 "hotkey masks are %s\n",
3296 str_supported(tp_features.hotkey_mask));
3297
3298
3299 if (!tp_features.hotkey_mask && !hotkey_all_mask &&
3300 (quirks & TPACPI_HK_Q_INIMASK))
3301 hotkey_all_mask = 0x080cU;
3302
3303
3304 if (tp_features.hotkey_mask) {
3305
3306
3307 res = hotkey_mask_get();
3308 if (res)
3309 goto err_exit;
3310
3311 hotkey_orig_mask = hotkey_acpi_mask;
3312 } else {
3313 hotkey_orig_mask = hotkey_all_mask;
3314 hotkey_acpi_mask = hotkey_all_mask;
3315 }
3316
3317#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3318 if (dbg_wlswemul) {
3319 tp_features.hotkey_wlsw = 1;
3320 radiosw_state = !!tpacpi_wlsw_emulstate;
3321 pr_info("radio switch emulation enabled\n");
3322 } else
3323#endif
3324
3325 if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
3326 tp_features.hotkey_wlsw = 1;
3327 radiosw_state = !!status;
3328 pr_info("radio switch found; radios are %s\n",
3329 enabled(status, 0));
3330 }
3331 if (tp_features.hotkey_wlsw)
3332 res = add_to_attr_set(hotkey_dev_attributes,
3333 &dev_attr_hotkey_radio_sw.attr);
3334
3335
3336 if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) {
3337 tp_features.hotkey_tablet = 1;
3338 tabletsw_state = !!(status & TP_HOTKEY_TABLET_MASK);
3339 pr_info("possible tablet mode switch found; "
3340 "ThinkPad in %s mode\n",
3341 (tabletsw_state) ? "tablet" : "laptop");
3342 res = add_to_attr_set(hotkey_dev_attributes,
3343 &dev_attr_hotkey_tablet_mode.attr);
3344 }
3345
3346 if (!res)
3347 res = register_attr_set_with_sysfs(
3348 hotkey_dev_attributes,
3349 &tpacpi_pdev->dev.kobj);
3350 if (res)
3351 goto err_exit;
3352
3353
3354 hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
3355 GFP_KERNEL);
3356 if (!hotkey_keycode_map) {
3357 pr_err("failed to allocate memory for key map\n");
3358 res = -ENOMEM;
3359 goto err_exit;
3360 }
3361
3362 keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable,
3363 ARRAY_SIZE(tpacpi_keymap_qtable));
3364 BUG_ON(keymap_id >= ARRAY_SIZE(tpacpi_keymaps));
3365 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3366 "using keymap number %lu\n", keymap_id);
3367
3368 memcpy(hotkey_keycode_map, &tpacpi_keymaps[keymap_id],
3369 TPACPI_HOTKEY_MAP_SIZE);
3370
3371 input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN);
3372 tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
3373 tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN;
3374 tpacpi_inputdev->keycode = hotkey_keycode_map;
3375 for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) {
3376 if (hotkey_keycode_map[i] != KEY_RESERVED) {
3377 input_set_capability(tpacpi_inputdev, EV_KEY,
3378 hotkey_keycode_map[i]);
3379 } else {
3380 if (i < sizeof(hotkey_reserved_mask)*8)
3381 hotkey_reserved_mask |= 1 << i;
3382 }
3383 }
3384
3385 if (tp_features.hotkey_wlsw) {
3386 input_set_capability(tpacpi_inputdev, EV_SW, SW_RFKILL_ALL);
3387 input_report_switch(tpacpi_inputdev,
3388 SW_RFKILL_ALL, radiosw_state);
3389 }
3390 if (tp_features.hotkey_tablet) {
3391 input_set_capability(tpacpi_inputdev, EV_SW, SW_TABLET_MODE);
3392 input_report_switch(tpacpi_inputdev,
3393 SW_TABLET_MODE, tabletsw_state);
3394 }
3395
3396
3397
3398
3399 if (tp_features.bright_acpimode && acpi_video_backlight_support()) {
3400 pr_info("This ThinkPad has standard ACPI backlight "
3401 "brightness control, supported by the ACPI "
3402 "video driver\n");
3403 pr_notice("Disabling thinkpad-acpi brightness events "
3404 "by default...\n");
3405
3406
3407
3408
3409 hotkey_reserved_mask |=
3410 (1 << TP_ACPI_HOTKEYSCAN_FNHOME)
3411 | (1 << TP_ACPI_HOTKEYSCAN_FNEND);
3412 hotkey_unmap(TP_ACPI_HOTKEYSCAN_FNHOME);
3413 hotkey_unmap(TP_ACPI_HOTKEYSCAN_FNEND);
3414 }
3415
3416#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
3417 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
3418 & ~hotkey_all_mask
3419 & ~hotkey_reserved_mask;
3420
3421 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3422 "hotkey source mask 0x%08x, polling freq %u\n",
3423 hotkey_source_mask, hotkey_poll_freq);
3424#endif
3425
3426 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3427 "enabling firmware HKEY event interface...\n");
3428 res = hotkey_status_set(true);
3429 if (res) {
3430 hotkey_exit();
3431 return res;
3432 }
3433 res = hotkey_mask_set(((hotkey_all_mask & ~hotkey_reserved_mask)
3434 | hotkey_driver_mask)
3435 & ~hotkey_source_mask);
3436 if (res < 0 && res != -ENXIO) {
3437 hotkey_exit();
3438 return res;
3439 }
3440 hotkey_user_mask = (hotkey_acpi_mask | hotkey_source_mask)
3441 & ~hotkey_reserved_mask;
3442 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3443 "initial masks: user=0x%08x, fw=0x%08x, poll=0x%08x\n",
3444 hotkey_user_mask, hotkey_acpi_mask, hotkey_source_mask);
3445
3446 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3447 "legacy ibm/hotkey event reporting over procfs %s\n",
3448 (hotkey_report_mode < 2) ?
3449 "enabled" : "disabled");
3450
3451 tpacpi_inputdev->open = &hotkey_inputdev_open;
3452 tpacpi_inputdev->close = &hotkey_inputdev_close;
3453
3454 hotkey_poll_setup_safe(true);
3455
3456 return 0;
3457
3458err_exit:
3459 delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
3460 hotkey_dev_attributes = NULL;
3461
3462 return (res < 0)? res : 1;
3463}
3464
3465static bool hotkey_notify_hotkey(const u32 hkey,
3466 bool *send_acpi_ev,
3467 bool *ignore_acpi_ev)
3468{
3469
3470 unsigned int scancode = hkey & 0xfff;
3471 *send_acpi_ev = true;
3472 *ignore_acpi_ev = false;
3473
3474
3475 if (scancode > 0 && scancode <= TPACPI_HOTKEY_MAP_LEN) {
3476 scancode--;
3477 if (!(hotkey_source_mask & (1 << scancode))) {
3478 tpacpi_input_send_key_masked(scancode);
3479 *send_acpi_ev = false;
3480 } else {
3481 *ignore_acpi_ev = true;
3482 }
3483 return true;
3484 }
3485 return false;
3486}
3487
3488static bool hotkey_notify_wakeup(const u32 hkey,
3489 bool *send_acpi_ev,
3490 bool *ignore_acpi_ev)
3491{
3492
3493 *send_acpi_ev = true;
3494 *ignore_acpi_ev = false;
3495
3496 switch (hkey) {
3497 case TP_HKEY_EV_WKUP_S3_UNDOCK:
3498 case TP_HKEY_EV_WKUP_S4_UNDOCK:
3499 hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK;
3500 *ignore_acpi_ev = true;
3501 break;
3502
3503 case TP_HKEY_EV_WKUP_S3_BAYEJ:
3504 case TP_HKEY_EV_WKUP_S4_BAYEJ:
3505 hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ;
3506 *ignore_acpi_ev = true;
3507 break;
3508
3509 case TP_HKEY_EV_WKUP_S3_BATLOW:
3510 case TP_HKEY_EV_WKUP_S4_BATLOW:
3511 pr_alert("EMERGENCY WAKEUP: battery almost empty\n");
3512
3513
3514
3515 break;
3516
3517 default:
3518 return false;
3519 }
3520
3521 if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) {
3522 pr_info("woke up due to a hot-unplug request...\n");
3523 hotkey_wakeup_reason_notify_change();
3524 }
3525 return true;
3526}
3527
3528static bool hotkey_notify_dockevent(const u32 hkey,
3529 bool *send_acpi_ev,
3530 bool *ignore_acpi_ev)
3531{
3532
3533 *send_acpi_ev = true;
3534 *ignore_acpi_ev = false;
3535
3536 switch (hkey) {
3537 case TP_HKEY_EV_UNDOCK_ACK:
3538
3539 hotkey_autosleep_ack = 1;
3540 pr_info("undocked\n");
3541 hotkey_wakeup_hotunplug_complete_notify_change();
3542 return true;
3543
3544 case TP_HKEY_EV_HOTPLUG_DOCK:
3545 pr_info("docked into hotplug port replicator\n");
3546 return true;
3547 case TP_HKEY_EV_HOTPLUG_UNDOCK:
3548 pr_info("undocked from hotplug port replicator\n");
3549 return true;
3550
3551 default:
3552 return false;
3553 }
3554}
3555
3556static bool hotkey_notify_usrevent(const u32 hkey,
3557 bool *send_acpi_ev,
3558 bool *ignore_acpi_ev)
3559{
3560
3561 *send_acpi_ev = true;
3562 *ignore_acpi_ev = false;
3563
3564 switch (hkey) {
3565 case TP_HKEY_EV_PEN_INSERTED:
3566 case TP_HKEY_EV_PEN_REMOVED:
3567 return true;
3568
3569 case TP_HKEY_EV_TABLET_TABLET:
3570 case TP_HKEY_EV_TABLET_NOTEBOOK:
3571 tpacpi_input_send_tabletsw();
3572 hotkey_tablet_mode_notify_change();
3573 *send_acpi_ev = false;
3574 return true;
3575
3576 case TP_HKEY_EV_LID_CLOSE:
3577 case TP_HKEY_EV_LID_OPEN:
3578 case TP_HKEY_EV_BRGHT_CHANGED:
3579
3580 *ignore_acpi_ev = true;
3581 return true;
3582
3583 default:
3584 return false;
3585 }
3586}
3587
3588static void thermal_dump_all_sensors(void);
3589
3590static bool hotkey_notify_6xxx(const u32 hkey,
3591 bool *send_acpi_ev,
3592 bool *ignore_acpi_ev)
3593{
3594 bool known = true;
3595
3596
3597 *send_acpi_ev = true;
3598 *ignore_acpi_ev = false;
3599
3600 switch (hkey) {
3601 case TP_HKEY_EV_THM_TABLE_CHANGED:
3602 pr_info("EC reports that Thermal Table has changed\n");
3603
3604
3605 return true;
3606 case TP_HKEY_EV_ALARM_BAT_HOT:
3607 pr_crit("THERMAL ALARM: battery is too hot!\n");
3608
3609 break;
3610 case TP_HKEY_EV_ALARM_BAT_XHOT:
3611 pr_alert("THERMAL EMERGENCY: battery is extremely hot!\n");
3612
3613 break;
3614 case TP_HKEY_EV_ALARM_SENSOR_HOT:
3615 pr_crit("THERMAL ALARM: "
3616 "a sensor reports something is too hot!\n");
3617
3618
3619 break;
3620 case TP_HKEY_EV_ALARM_SENSOR_XHOT:
3621 pr_alert("THERMAL EMERGENCY: "
3622 "a sensor reports something is extremely hot!\n");
3623
3624 break;
3625
3626 case TP_HKEY_EV_KEY_NUMLOCK:
3627 case TP_HKEY_EV_KEY_FN:
3628
3629
3630 *send_acpi_ev = false;
3631 *ignore_acpi_ev = true;
3632 return true;
3633
3634 default:
3635 pr_warn("unknown possible thermal alarm or keyboard event received\n");
3636 known = false;
3637 }
3638
3639 thermal_dump_all_sensors();
3640
3641 return known;
3642}
3643
3644static void hotkey_notify(struct ibm_struct *ibm, u32 event)
3645{
3646 u32 hkey;
3647 bool send_acpi_ev;
3648 bool ignore_acpi_ev;
3649 bool known_ev;
3650
3651 if (event != 0x80) {
3652 pr_err("unknown HKEY notification event %d\n", event);
3653
3654 acpi_bus_generate_netlink_event(
3655 ibm->acpi->device->pnp.device_class,
3656 dev_name(&ibm->acpi->device->dev),
3657 event, 0);
3658 return;
3659 }
3660
3661 while (1) {
3662 if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
3663 pr_err("failed to retrieve HKEY event\n");
3664 return;
3665 }
3666
3667 if (hkey == 0) {
3668
3669 return;
3670 }
3671
3672 send_acpi_ev = true;
3673 ignore_acpi_ev = false;
3674
3675 switch (hkey >> 12) {
3676 case 1:
3677
3678 known_ev = hotkey_notify_hotkey(hkey, &send_acpi_ev,
3679 &ignore_acpi_ev);
3680 break;
3681 case 2:
3682
3683 known_ev = hotkey_notify_wakeup(hkey, &send_acpi_ev,
3684 &ignore_acpi_ev);
3685 break;
3686 case 3:
3687
3688 switch (hkey) {
3689 case TP_HKEY_EV_BAYEJ_ACK:
3690 hotkey_autosleep_ack = 1;
3691 pr_info("bay ejected\n");
3692 hotkey_wakeup_hotunplug_complete_notify_change();
3693 known_ev = true;
3694 break;
3695 case TP_HKEY_EV_OPTDRV_EJ:
3696
3697 known_ev = true;
3698 break;
3699 default:
3700 known_ev = false;
3701 }
3702 break;
3703 case 4:
3704
3705 known_ev = hotkey_notify_dockevent(hkey, &send_acpi_ev,
3706 &ignore_acpi_ev);
3707 break;
3708 case 5:
3709
3710 known_ev = hotkey_notify_usrevent(hkey, &send_acpi_ev,
3711 &ignore_acpi_ev);
3712 break;
3713 case 6:
3714
3715
3716 known_ev = hotkey_notify_6xxx(hkey, &send_acpi_ev,
3717 &ignore_acpi_ev);
3718 break;
3719 case 7:
3720
3721 if (tp_features.hotkey_wlsw &&
3722 hkey == TP_HKEY_EV_RFKILL_CHANGED) {
3723 tpacpi_send_radiosw_update();
3724 send_acpi_ev = 0;
3725 known_ev = true;
3726 break;
3727 }
3728
3729 default:
3730 known_ev = false;
3731 }
3732 if (!known_ev) {
3733 pr_notice("unhandled HKEY event 0x%04x\n", hkey);
3734 pr_notice("please report the conditions when this "
3735 "event happened to %s\n", TPACPI_MAIL);
3736 }
3737
3738
3739 if (!ignore_acpi_ev &&
3740 (send_acpi_ev || hotkey_report_mode < 2)) {
3741 acpi_bus_generate_proc_event(ibm->acpi->device,
3742 event, hkey);
3743 }
3744
3745
3746 if (!ignore_acpi_ev && send_acpi_ev) {
3747 acpi_bus_generate_netlink_event(
3748 ibm->acpi->device->pnp.device_class,
3749 dev_name(&ibm->acpi->device->dev),
3750 event, hkey);
3751 }
3752 }
3753}
3754
3755static void hotkey_suspend(pm_message_t state)
3756{
3757
3758 hotkey_wakeup_reason = TP_ACPI_WAKEUP_NONE;
3759 hotkey_autosleep_ack = 0;
3760}
3761
3762static void hotkey_resume(void)
3763{
3764 tpacpi_disable_brightness_delay();
3765
3766 if (hotkey_status_set(true) < 0 ||
3767 hotkey_mask_set(hotkey_acpi_mask) < 0)
3768 pr_err("error while attempting to reset the event "
3769 "firmware interface\n");
3770
3771 tpacpi_send_radiosw_update();
3772 hotkey_tablet_mode_notify_change();
3773 hotkey_wakeup_reason_notify_change();
3774 hotkey_wakeup_hotunplug_complete_notify_change();
3775 hotkey_poll_setup_safe(false);
3776}
3777
3778
3779static int hotkey_read(struct seq_file *m)
3780{
3781 int res, status;
3782
3783 if (!tp_features.hotkey) {
3784 seq_printf(m, "status:\t\tnot supported\n");
3785 return 0;
3786 }
3787
3788 if (mutex_lock_killable(&hotkey_mutex))
3789 return -ERESTARTSYS;
3790 res = hotkey_status_get(&status);
3791 if (!res)
3792 res = hotkey_mask_get();
3793 mutex_unlock(&hotkey_mutex);
3794 if (res)
3795 return res;
3796
3797 seq_printf(m, "status:\t\t%s\n", enabled(status, 0));
3798 if (hotkey_all_mask) {
3799 seq_printf(m, "mask:\t\t0x%08x\n", hotkey_user_mask);
3800 seq_printf(m, "commands:\tenable, disable, reset, <mask>\n");
3801 } else {
3802 seq_printf(m, "mask:\t\tnot supported\n");
3803 seq_printf(m, "commands:\tenable, disable, reset\n");
3804 }
3805
3806 return 0;
3807}
3808
3809static void hotkey_enabledisable_warn(bool enable)
3810{
3811 tpacpi_log_usertask("procfs hotkey enable/disable");
3812 if (!WARN((tpacpi_lifecycle == TPACPI_LIFE_RUNNING || !enable),
3813 pr_fmt("hotkey enable/disable functionality has been "
3814 "removed from the driver. "
3815 "Hotkeys are always enabled.\n")))
3816 pr_err("Please remove the hotkey=enable module "
3817 "parameter, it is deprecated. "
3818 "Hotkeys are always enabled.\n");
3819}
3820
3821static int hotkey_write(char *buf)
3822{
3823 int res;
3824 u32 mask;
3825 char *cmd;
3826
3827 if (!tp_features.hotkey)
3828 return -ENODEV;
3829
3830 if (mutex_lock_killable(&hotkey_mutex))
3831 return -ERESTARTSYS;
3832
3833 mask = hotkey_user_mask;
3834
3835 res = 0;
3836 while ((cmd = next_cmd(&buf))) {
3837 if (strlencmp(cmd, "enable") == 0) {
3838 hotkey_enabledisable_warn(1);
3839 } else if (strlencmp(cmd, "disable") == 0) {
3840 hotkey_enabledisable_warn(0);
3841 res = -EPERM;
3842 } else if (strlencmp(cmd, "reset") == 0) {
3843 mask = (hotkey_all_mask | hotkey_source_mask)
3844 & ~hotkey_reserved_mask;
3845 } else if (sscanf(cmd, "0x%x", &mask) == 1) {
3846
3847 } else if (sscanf(cmd, "%x", &mask) == 1) {
3848
3849 } else {
3850 res = -EINVAL;
3851 goto errexit;
3852 }
3853 }
3854
3855 if (!res) {
3856 tpacpi_disclose_usertask("procfs hotkey",
3857 "set mask to 0x%08x\n", mask);
3858 res = hotkey_user_mask_set(mask);
3859 }
3860
3861errexit:
3862 mutex_unlock(&hotkey_mutex);
3863 return res;
3864}
3865
3866static const struct acpi_device_id ibm_htk_device_ids[] = {
3867 {TPACPI_ACPI_IBM_HKEY_HID, 0},
3868 {TPACPI_ACPI_LENOVO_HKEY_HID, 0},
3869 {"", 0},
3870};
3871
3872static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = {
3873 .hid = ibm_htk_device_ids,
3874 .notify = hotkey_notify,
3875 .handle = &hkey_handle,
3876 .type = ACPI_DEVICE_NOTIFY,
3877};
3878
3879static struct ibm_struct hotkey_driver_data = {
3880 .name = "hotkey",
3881 .read = hotkey_read,
3882 .write = hotkey_write,
3883 .exit = hotkey_exit,
3884 .resume = hotkey_resume,
3885 .suspend = hotkey_suspend,
3886 .acpi = &ibm_hotkey_acpidriver,
3887};
3888
3889
3890
3891
3892
3893enum {
3894
3895 TP_ACPI_BLUETOOTH_HWPRESENT = 0x01,
3896 TP_ACPI_BLUETOOTH_RADIOSSW = 0x02,
3897 TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04,
3898
3899};
3900
3901enum {
3902
3903 TP_ACPI_BLTH_GET_ULTRAPORT_ID = 0x00,
3904 TP_ACPI_BLTH_GET_PWR_ON_RESUME = 0x01,
3905 TP_ACPI_BLTH_PWR_ON_ON_RESUME = 0x02,
3906 TP_ACPI_BLTH_PWR_OFF_ON_RESUME = 0x03,
3907 TP_ACPI_BLTH_SAVE_STATE = 0x05,
3908};
3909
3910#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw"
3911
3912static int bluetooth_get_status(void)
3913{
3914 int status;
3915
3916#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3917 if (dbg_bluetoothemul)
3918 return (tpacpi_bluetooth_emulstate) ?
3919 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3920#endif
3921
3922 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
3923 return -EIO;
3924
3925 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ?
3926 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3927}
3928
3929static int bluetooth_set_status(enum tpacpi_rfkill_state state)
3930{
3931 int status;
3932
3933 vdbg_printk(TPACPI_DBG_RFKILL,
3934 "will attempt to %s bluetooth\n",
3935 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
3936
3937#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3938 if (dbg_bluetoothemul) {
3939 tpacpi_bluetooth_emulstate = (state == TPACPI_RFK_RADIO_ON);
3940 return 0;
3941 }
3942#endif
3943
3944 if (state == TPACPI_RFK_RADIO_ON)
3945 status = TP_ACPI_BLUETOOTH_RADIOSSW
3946 | TP_ACPI_BLUETOOTH_RESUMECTRL;
3947 else
3948 status = 0;
3949
3950 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
3951 return -EIO;
3952
3953 return 0;
3954}
3955
3956
3957static ssize_t bluetooth_enable_show(struct device *dev,
3958 struct device_attribute *attr,
3959 char *buf)
3960{
3961 return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_BLUETOOTH_SW_ID,
3962 attr, buf);
3963}
3964
3965static ssize_t bluetooth_enable_store(struct device *dev,
3966 struct device_attribute *attr,
3967 const char *buf, size_t count)
3968{
3969 return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_BLUETOOTH_SW_ID,
3970 attr, buf, count);
3971}
3972
3973static struct device_attribute dev_attr_bluetooth_enable =
3974 __ATTR(bluetooth_enable, S_IWUSR | S_IRUGO,
3975 bluetooth_enable_show, bluetooth_enable_store);
3976
3977
3978
3979static struct attribute *bluetooth_attributes[] = {
3980 &dev_attr_bluetooth_enable.attr,
3981 NULL
3982};
3983
3984static const struct attribute_group bluetooth_attr_group = {
3985 .attrs = bluetooth_attributes,
3986};
3987
3988static const struct tpacpi_rfk_ops bluetooth_tprfk_ops = {
3989 .get_status = bluetooth_get_status,
3990 .set_status = bluetooth_set_status,
3991};
3992
3993static void bluetooth_shutdown(void)
3994{
3995
3996 if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
3997 TP_ACPI_BLTH_SAVE_STATE))
3998 pr_notice("failed to save bluetooth state to NVRAM\n");
3999 else
4000 vdbg_printk(TPACPI_DBG_RFKILL,
4001 "bluestooth state saved to NVRAM\n");
4002}
4003
4004static void bluetooth_exit(void)
4005{
4006 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
4007 &bluetooth_attr_group);
4008
4009 tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);
4010
4011 bluetooth_shutdown();
4012}
4013
4014static int __init bluetooth_init(struct ibm_init_struct *iibm)
4015{
4016 int res;
4017 int status = 0;
4018
4019 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4020 "initializing bluetooth subdriver\n");
4021
4022 TPACPI_ACPIHANDLE_INIT(hkey);
4023
4024
4025
4026 tp_features.bluetooth = hkey_handle &&
4027 acpi_evalf(hkey_handle, &status, "GBDC", "qd");
4028
4029 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4030 "bluetooth is %s, status 0x%02x\n",
4031 str_supported(tp_features.bluetooth),
4032 status);
4033
4034#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
4035 if (dbg_bluetoothemul) {
4036 tp_features.bluetooth = 1;
4037 pr_info("bluetooth switch emulation enabled\n");
4038 } else
4039#endif
4040 if (tp_features.bluetooth &&
4041 !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
4042
4043 tp_features.bluetooth = 0;
4044 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4045 "bluetooth hardware not installed\n");
4046 }
4047
4048 if (!tp_features.bluetooth)
4049 return 1;
4050
4051 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
4052 &bluetooth_tprfk_ops,
4053 RFKILL_TYPE_BLUETOOTH,
4054 TPACPI_RFK_BLUETOOTH_SW_NAME,
4055 true);
4056 if (res)
4057 return res;
4058
4059 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
4060 &bluetooth_attr_group);
4061 if (res) {
4062 tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);
4063 return res;
4064 }
4065
4066 return 0;
4067}
4068
4069
4070static int bluetooth_read(struct seq_file *m)
4071{
4072 return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, m);
4073}
4074
4075static int bluetooth_write(char *buf)
4076{
4077 return tpacpi_rfk_procfs_write(TPACPI_RFK_BLUETOOTH_SW_ID, buf);
4078}
4079
4080static struct ibm_struct bluetooth_driver_data = {
4081 .name = "bluetooth",
4082 .read = bluetooth_read,
4083 .write = bluetooth_write,
4084 .exit = bluetooth_exit,
4085 .shutdown = bluetooth_shutdown,
4086};
4087
4088
4089
4090
4091
4092enum {
4093
4094 TP_ACPI_WANCARD_HWPRESENT = 0x01,
4095 TP_ACPI_WANCARD_RADIOSSW = 0x02,
4096 TP_ACPI_WANCARD_RESUMECTRL = 0x04,
4097
4098};
4099
4100#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
4101
4102static int wan_get_status(void)
4103{
4104 int status;
4105
4106#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
4107 if (dbg_wwanemul)
4108 return (tpacpi_wwan_emulstate) ?
4109 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
4110#endif
4111
4112 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
4113 return -EIO;
4114
4115 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ?
4116 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
4117}
4118
4119static int wan_set_status(enum tpacpi_rfkill_state state)
4120{
4121 int status;
4122
4123 vdbg_printk(TPACPI_DBG_RFKILL,
4124 "will attempt to %s wwan\n",
4125 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
4126
4127#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
4128 if (dbg_wwanemul) {
4129 tpacpi_wwan_emulstate = (state == TPACPI_RFK_RADIO_ON);
4130 return 0;
4131 }
4132#endif
4133
4134 if (state == TPACPI_RFK_RADIO_ON)
4135 status = TP_ACPI_WANCARD_RADIOSSW
4136 | TP_ACPI_WANCARD_RESUMECTRL;
4137 else
4138 status = 0;
4139
4140 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
4141 return -EIO;
4142
4143 return 0;
4144}
4145
4146
4147static ssize_t wan_enable_show(struct device *dev,
4148 struct device_attribute *attr,
4149 char *buf)
4150{
4151 return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_WWAN_SW_ID,
4152 attr, buf);
4153}
4154
4155static ssize_t wan_enable_store(struct device *dev,
4156 struct device_attribute *attr,
4157 const char *buf, size_t count)
4158{
4159 return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_WWAN_SW_ID,
4160 attr, buf, count);
4161}
4162
4163static struct device_attribute dev_attr_wan_enable =
4164 __ATTR(wwan_enable, S_IWUSR | S_IRUGO,
4165 wan_enable_show, wan_enable_store);
4166
4167
4168
4169static struct attribute *wan_attributes[] = {
4170 &dev_attr_wan_enable.attr,
4171 NULL
4172};
4173
4174static const struct attribute_group wan_attr_group = {
4175 .attrs = wan_attributes,
4176};
4177
4178static const struct tpacpi_rfk_ops wan_tprfk_ops = {
4179 .get_status = wan_get_status,
4180 .set_status = wan_set_status,
4181};
4182
4183static void wan_shutdown(void)
4184{
4185
4186 if (!acpi_evalf(NULL, NULL, "\\WGSV", "vd",
4187 TP_ACPI_WGSV_SAVE_STATE))
4188 pr_notice("failed to save WWAN state to NVRAM\n");
4189 else
4190 vdbg_printk(TPACPI_DBG_RFKILL,
4191 "WWAN state saved to NVRAM\n");
4192}
4193
4194static void wan_exit(void)
4195{
4196 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
4197 &wan_attr_group);
4198
4199 tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);
4200
4201 wan_shutdown();
4202}
4203
4204static int __init wan_init(struct ibm_init_struct *iibm)
4205{
4206 int res;
4207 int status = 0;
4208
4209 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4210 "initializing wan subdriver\n");
4211
4212 TPACPI_ACPIHANDLE_INIT(hkey);
4213
4214 tp_features.wan = hkey_handle &&
4215 acpi_evalf(hkey_handle, &status, "GWAN", "qd");
4216
4217 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4218 "wan is %s, status 0x%02x\n",
4219 str_supported(tp_features.wan),
4220 status);
4221
4222#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
4223 if (dbg_wwanemul) {
4224 tp_features.wan = 1;
4225 pr_info("wwan switch emulation enabled\n");
4226 } else
4227#endif
4228 if (tp_features.wan &&
4229 !(status & TP_ACPI_WANCARD_HWPRESENT)) {
4230
4231 tp_features.wan = 0;
4232 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4233 "wan hardware not installed\n");
4234 }
4235
4236 if (!tp_features.wan)
4237 return 1;
4238
4239 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
4240 &wan_tprfk_ops,
4241 RFKILL_TYPE_WWAN,
4242 TPACPI_RFK_WWAN_SW_NAME,
4243 true);
4244 if (res)
4245 return res;
4246
4247 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
4248 &wan_attr_group);
4249
4250 if (res) {
4251 tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);
4252 return res;
4253 }
4254
4255 return 0;
4256}
4257
4258
4259static int wan_read(struct seq_file *m)
4260{
4261 return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, m);
4262}
4263
4264static int wan_write(char *buf)
4265{
4266 return tpacpi_rfk_procfs_write(TPACPI_RFK_WWAN_SW_ID, buf);
4267}
4268
4269static struct ibm_struct wan_driver_data = {
4270 .name = "wan",
4271 .read = wan_read,
4272 .write = wan_write,
4273 .exit = wan_exit,
4274 .shutdown = wan_shutdown,
4275};
4276
4277
4278
4279
4280
4281enum {
4282
4283 TP_ACPI_UWB_HWPRESENT = 0x01,
4284 TP_ACPI_UWB_RADIOSSW = 0x02,
4285};
4286
4287#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw"
4288
4289static int uwb_get_status(void)
4290{
4291 int status;
4292
4293#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
4294 if (dbg_uwbemul)
4295 return (tpacpi_uwb_emulstate) ?
4296 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
4297#endif
4298
4299 if (!acpi_evalf(hkey_handle, &status, "GUWB", "d"))
4300 return -EIO;
4301
4302 return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ?
4303 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
4304}
4305
4306static int uwb_set_status(enum tpacpi_rfkill_state state)
4307{
4308 int status;
4309
4310 vdbg_printk(TPACPI_DBG_RFKILL,
4311 "will attempt to %s UWB\n",
4312 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
4313
4314#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
4315 if (dbg_uwbemul) {
4316 tpacpi_uwb_emulstate = (state == TPACPI_RFK_RADIO_ON);
4317 return 0;
4318 }
4319#endif
4320
4321 if (state == TPACPI_RFK_RADIO_ON)
4322 status = TP_ACPI_UWB_RADIOSSW;
4323 else
4324 status = 0;
4325
4326 if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status))
4327 return -EIO;
4328
4329 return 0;
4330}
4331
4332
4333
4334static const struct tpacpi_rfk_ops uwb_tprfk_ops = {
4335 .get_status = uwb_get_status,
4336 .set_status = uwb_set_status,
4337};
4338
4339static void uwb_exit(void)
4340{
4341 tpacpi_destroy_rfkill(TPACPI_RFK_UWB_SW_ID);
4342}
4343
4344static int __init uwb_init(struct ibm_init_struct *iibm)
4345{
4346 int res;
4347 int status = 0;
4348
4349 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4350 "initializing uwb subdriver\n");
4351
4352 TPACPI_ACPIHANDLE_INIT(hkey);
4353
4354 tp_features.uwb = hkey_handle &&
4355 acpi_evalf(hkey_handle, &status, "GUWB", "qd");
4356
4357 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
4358 "uwb is %s, status 0x%02x\n",
4359 str_supported(tp_features.uwb),
4360 status);
4361
4362#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
4363 if (dbg_uwbemul) {
4364 tp_features.uwb = 1;
4365 pr_info("uwb switch emulation enabled\n");
4366 } else
4367#endif
4368 if (tp_features.uwb &&
4369 !(status & TP_ACPI_UWB_HWPRESENT)) {
4370
4371 tp_features.uwb = 0;
4372 dbg_printk(TPACPI_DBG_INIT,
4373 "uwb hardware not installed\n");
4374 }
4375
4376 if (!tp_features.uwb)
4377 return 1;
4378
4379 res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
4380 &uwb_tprfk_ops,
4381 RFKILL_TYPE_UWB,
4382 TPACPI_RFK_UWB_SW_NAME,
4383 false);
4384 return res;
4385}
4386
4387static struct ibm_struct uwb_driver_data = {
4388 .name = "uwb",
4389 .exit = uwb_exit,
4390 .flags.experimental = 1,
4391};
4392
4393
4394
4395
4396
4397#ifdef CONFIG_THINKPAD_ACPI_VIDEO
4398
4399enum video_access_mode {
4400 TPACPI_VIDEO_NONE = 0,
4401 TPACPI_VIDEO_570,
4402 TPACPI_VIDEO_770,
4403 TPACPI_VIDEO_NEW,
4404};
4405
4406enum {
4407 TP_ACPI_VIDEO_S_LCD = 0x01,
4408 TP_ACPI_VIDEO_S_CRT = 0x02,
4409 TP_ACPI_VIDEO_S_DVI = 0x08,
4410};
4411
4412enum {
4413 TP_ACPI_VIDEO_570_PHSCMD = 0x87,
4414 TP_ACPI_VIDEO_570_PHSMASK = 0x03,
4415
4416 TP_ACPI_VIDEO_570_PHS2CMD = 0x8b,
4417 TP_ACPI_VIDEO_570_PHS2SET = 0x80,
4418};
4419
4420static enum video_access_mode video_supported;
4421static int video_orig_autosw;
4422
4423static int video_autosw_get(void);
4424static int video_autosw_set(int enable);
4425
4426TPACPI_HANDLE(vid, root,
4427 "\\_SB.PCI.AGP.VGA",
4428 "\\_SB.PCI0.AGP0.VID0",
4429 "\\_SB.PCI0.VID0",
4430 "\\_SB.PCI0.VID",
4431 "\\_SB.PCI0.AGP.VGA",
4432 "\\_SB.PCI0.AGP.VID",
4433 );
4434
4435TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID");
4436
4437static int __init video_init(struct ibm_init_struct *iibm)
4438{
4439 int ivga;
4440
4441 vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n");
4442
4443 TPACPI_ACPIHANDLE_INIT(vid);
4444 if (tpacpi_is_ibm())
4445 TPACPI_ACPIHANDLE_INIT(vid2);
4446
4447 if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga)
4448
4449 vid_handle = vid2_handle;
4450
4451 if (!vid_handle)
4452
4453 video_supported = TPACPI_VIDEO_NONE;
4454 else if (tpacpi_is_ibm() &&
4455 acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd"))
4456
4457 video_supported = TPACPI_VIDEO_570;
4458 else if (tpacpi_is_ibm() &&
4459 acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd"))
4460
4461 video_supported = TPACPI_VIDEO_770;
4462 else
4463
4464 video_supported = TPACPI_VIDEO_NEW;
4465
4466 vdbg_printk(TPACPI_DBG_INIT, "video is %s, mode %d\n",
4467 str_supported(video_supported != TPACPI_VIDEO_NONE),
4468 video_supported);
4469
4470 return (video_supported != TPACPI_VIDEO_NONE)? 0 : 1;
4471}
4472
4473static void video_exit(void)
4474{
4475 dbg_printk(TPACPI_DBG_EXIT,
4476 "restoring original video autoswitch mode\n");
4477 if (video_autosw_set(video_orig_autosw))
4478 pr_err("error while trying to restore original "
4479 "video autoswitch mode\n");
4480}
4481
4482static int video_outputsw_get(void)
4483{
4484 int status = 0;
4485 int i;
4486
4487 switch (video_supported) {
4488 case TPACPI_VIDEO_570:
4489 if (!acpi_evalf(NULL, &i, "\\_SB.PHS", "dd",
4490 TP_ACPI_VIDEO_570_PHSCMD))
4491 return -EIO;
4492 status = i & TP_ACPI_VIDEO_570_PHSMASK;
4493 break;
4494 case TPACPI_VIDEO_770:
4495 if (!acpi_evalf(NULL, &i, "\\VCDL", "d"))
4496 return -EIO;
4497 if (i)
4498 status |= TP_ACPI_VIDEO_S_LCD;
4499 if (!acpi_evalf(NULL, &i, "\\VCDC", "d"))
4500 return -EIO;
4501 if (i)
4502 status |= TP_ACPI_VIDEO_S_CRT;
4503 break;
4504 case TPACPI_VIDEO_NEW:
4505 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1) ||
4506 !acpi_evalf(NULL, &i, "\\VCDC", "d"))
4507 return -EIO;
4508 if (i)
4509 status |= TP_ACPI_VIDEO_S_CRT;
4510
4511 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0) ||
4512 !acpi_evalf(NULL, &i, "\\VCDL", "d"))
4513 return -EIO;
4514 if (i)
4515 status |= TP_ACPI_VIDEO_S_LCD;
4516 if (!acpi_evalf(NULL, &i, "\\VCDD", "d"))
4517 return -EIO;
4518 if (i)
4519 status |= TP_ACPI_VIDEO_S_DVI;
4520 break;
4521 default:
4522 return -ENOSYS;
4523 }
4524
4525 return status;
4526}
4527
4528static int video_outputsw_set(int status)
4529{
4530 int autosw;
4531 int res = 0;
4532
4533 switch (video_supported) {
4534 case TPACPI_VIDEO_570:
4535 res = acpi_evalf(NULL, NULL,
4536 "\\_SB.PHS2", "vdd",
4537 TP_ACPI_VIDEO_570_PHS2CMD,
4538 status | TP_ACPI_VIDEO_570_PHS2SET);
4539 break;
4540 case TPACPI_VIDEO_770:
4541 autosw = video_autosw_get();
4542 if (autosw < 0)
4543 return autosw;
4544
4545 res = video_autosw_set(1);
4546 if (res)
4547 return res;
4548 res = acpi_evalf(vid_handle, NULL,
4549 "ASWT", "vdd", status * 0x100, 0);
4550 if (!autosw && video_autosw_set(autosw)) {
4551 pr_err("video auto-switch left enabled due to error\n");
4552 return -EIO;
4553 }
4554 break;
4555 case TPACPI_VIDEO_NEW:
4556 res = acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80) &&
4557 acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1);
4558 break;
4559 default:
4560 return -ENOSYS;
4561 }
4562
4563 return (res)? 0 : -EIO;
4564}
4565
4566static int video_autosw_get(void)
4567{
4568 int autosw = 0;
4569
4570 switch (video_supported) {
4571 case TPACPI_VIDEO_570:
4572 if (!acpi_evalf(vid_handle, &autosw, "SWIT", "d"))
4573 return -EIO;
4574 break;
4575 case TPACPI_VIDEO_770:
4576 case TPACPI_VIDEO_NEW:
4577 if (!acpi_evalf(vid_handle, &autosw, "^VDEE", "d"))
4578 return -EIO;
4579 break;
4580 default:
4581 return -ENOSYS;
4582 }
4583
4584 return autosw & 1;
4585}
4586
4587static int video_autosw_set(int enable)
4588{
4589 if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", (enable)? 1 : 0))
4590 return -EIO;
4591 return 0;
4592}
4593
4594static int video_outputsw_cycle(void)
4595{
4596 int autosw = video_autosw_get();
4597 int res;
4598
4599 if (autosw < 0)
4600 return autosw;
4601
4602 switch (video_supported) {
4603 case TPACPI_VIDEO_570:
4604 res = video_autosw_set(1);
4605 if (res)
4606 return res;
4607 res = acpi_evalf(ec_handle, NULL, "_Q16", "v");
4608 break;
4609 case TPACPI_VIDEO_770:
4610 case TPACPI_VIDEO_NEW:
4611 res = video_autosw_set(1);
4612 if (res)
4613 return res;
4614 res = acpi_evalf(vid_handle, NULL, "VSWT", "v");
4615 break;
4616 default:
4617 return -ENOSYS;
4618 }
4619 if (!autosw && video_autosw_set(autosw)) {
4620 pr_err("video auto-switch left enabled due to error\n");
4621 return -EIO;
4622 }
4623
4624 return (res)? 0 : -EIO;
4625}
4626
4627static int video_expand_toggle(void)
4628{
4629 switch (video_supported) {
4630 case TPACPI_VIDEO_570:
4631 return acpi_evalf(ec_handle, NULL, "_Q17", "v")?
4632 0 : -EIO;
4633 case TPACPI_VIDEO_770:
4634 return acpi_evalf(vid_handle, NULL, "VEXP", "v")?
4635 0 : -EIO;
4636 case TPACPI_VIDEO_NEW:
4637 return acpi_evalf(NULL, NULL, "\\VEXP", "v")?
4638 0 : -EIO;
4639 default:
4640 return -ENOSYS;
4641 }
4642
4643}
4644
4645static int video_read(struct seq_file *m)
4646{
4647 int status, autosw;
4648
4649 if (video_supported == TPACPI_VIDEO_NONE) {
4650 seq_printf(m, "status:\t\tnot supported\n");
4651 return 0;
4652 }
4653
4654
4655 if (!capable(CAP_SYS_ADMIN))
4656 return -EPERM;
4657
4658 status = video_outputsw_get();
4659 if (status < 0)
4660 return status;
4661
4662 autosw = video_autosw_get();
4663 if (autosw < 0)
4664 return autosw;
4665
4666 seq_printf(m, "status:\t\tsupported\n");
4667 seq_printf(m, "lcd:\t\t%s\n", enabled(status, 0));
4668 seq_printf(m, "crt:\t\t%s\n", enabled(status, 1));
4669 if (video_supported == TPACPI_VIDEO_NEW)
4670 seq_printf(m, "dvi:\t\t%s\n", enabled(status, 3));
4671 seq_printf(m, "auto:\t\t%s\n", enabled(autosw, 0));
4672 seq_printf(m, "commands:\tlcd_enable, lcd_disable\n");
4673 seq_printf(m, "commands:\tcrt_enable, crt_disable\n");
4674 if (video_supported == TPACPI_VIDEO_NEW)
4675 seq_printf(m, "commands:\tdvi_enable, dvi_disable\n");
4676 seq_printf(m, "commands:\tauto_enable, auto_disable\n");
4677 seq_printf(m, "commands:\tvideo_switch, expand_toggle\n");
4678
4679 return 0;
4680}
4681
4682static int video_write(char *buf)
4683{
4684 char *cmd;
4685 int enable, disable, status;
4686 int res;
4687
4688 if (video_supported == TPACPI_VIDEO_NONE)
4689 return -ENODEV;
4690
4691
4692 if (!capable(CAP_SYS_ADMIN))
4693 return -EPERM;
4694
4695 enable = 0;
4696 disable = 0;
4697
4698 while ((cmd = next_cmd(&buf))) {
4699 if (strlencmp(cmd, "lcd_enable") == 0) {
4700 enable |= TP_ACPI_VIDEO_S_LCD;
4701 } else if (strlencmp(cmd, "lcd_disable") == 0) {
4702 disable |= TP_ACPI_VIDEO_S_LCD;
4703 } else if (strlencmp(cmd, "crt_enable") == 0) {
4704 enable |= TP_ACPI_VIDEO_S_CRT;
4705 } else if (strlencmp(cmd, "crt_disable") == 0) {
4706 disable |= TP_ACPI_VIDEO_S_CRT;
4707 } else if (video_supported == TPACPI_VIDEO_NEW &&
4708 strlencmp(cmd, "dvi_enable") == 0) {
4709 enable |= TP_ACPI_VIDEO_S_DVI;
4710 } else if (video_supported == TPACPI_VIDEO_NEW &&
4711 strlencmp(cmd, "dvi_disable") == 0) {
4712 disable |= TP_ACPI_VIDEO_S_DVI;
4713 } else if (strlencmp(cmd, "auto_enable") == 0) {
4714 res = video_autosw_set(1);
4715 if (res)
4716 return res;
4717 } else if (strlencmp(cmd, "auto_disable") == 0) {
4718 res = video_autosw_set(0);
4719 if (res)
4720 return res;
4721 } else if (strlencmp(cmd, "video_switch") == 0) {
4722 res = video_outputsw_cycle();
4723 if (res)
4724 return res;
4725 } else if (strlencmp(cmd, "expand_toggle") == 0) {
4726 res = video_expand_toggle();
4727 if (res)
4728 return res;
4729 } else
4730 return -EINVAL;
4731 }
4732
4733 if (enable || disable) {
4734 status = video_outputsw_get();
4735 if (status < 0)
4736 return status;
4737 res = video_outputsw_set((status & ~disable) | enable);
4738 if (res)
4739 return res;
4740 }
4741
4742 return 0;
4743}
4744
4745static struct ibm_struct video_driver_data = {
4746 .name = "video",
4747 .read = video_read,
4748 .write = video_write,
4749 .exit = video_exit,
4750};
4751
4752#endif
4753
4754
4755
4756
4757
4758TPACPI_HANDLE(lght, root, "\\LGHT");
4759TPACPI_HANDLE(ledb, ec, "LEDB");
4760
4761static int light_get_status(void)
4762{
4763 int status = 0;
4764
4765 if (tp_features.light_status) {
4766 if (!acpi_evalf(ec_handle, &status, "KBLT", "d"))
4767 return -EIO;
4768 return (!!status);
4769 }
4770
4771 return -ENXIO;
4772}
4773
4774static int light_set_status(int status)
4775{
4776 int rc;
4777
4778 if (tp_features.light) {
4779 if (cmos_handle) {
4780 rc = acpi_evalf(cmos_handle, NULL, NULL, "vd",
4781 (status)?
4782 TP_CMOS_THINKLIGHT_ON :
4783 TP_CMOS_THINKLIGHT_OFF);
4784 } else {
4785 rc = acpi_evalf(lght_handle, NULL, NULL, "vd",
4786 (status)? 1 : 0);
4787 }
4788 return (rc)? 0 : -EIO;
4789 }
4790
4791 return -ENXIO;
4792}
4793
4794static void light_set_status_worker(struct work_struct *work)
4795{
4796 struct tpacpi_led_classdev *data =
4797 container_of(work, struct tpacpi_led_classdev, work);
4798
4799 if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
4800 light_set_status((data->new_state != TPACPI_LED_OFF));
4801}
4802
4803static void light_sysfs_set(struct led_classdev *led_cdev,
4804 enum led_brightness brightness)
4805{
4806 struct tpacpi_led_classdev *data =
4807 container_of(led_cdev,
4808 struct tpacpi_led_classdev,
4809 led_classdev);
4810 data->new_state = (brightness != LED_OFF) ?
4811 TPACPI_LED_ON : TPACPI_LED_OFF;
4812 queue_work(tpacpi_wq, &data->work);
4813}
4814
4815static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev)
4816{
4817 return (light_get_status() == 1)? LED_FULL : LED_OFF;
4818}
4819
4820static struct tpacpi_led_classdev tpacpi_led_thinklight = {
4821 .led_classdev = {
4822 .name = "tpacpi::thinklight",
4823 .brightness_set = &light_sysfs_set,
4824 .brightness_get = &light_sysfs_get,
4825 }
4826};
4827
4828static int __init light_init(struct ibm_init_struct *iibm)
4829{
4830 int rc;
4831
4832 vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
4833
4834 if (tpacpi_is_ibm()) {
4835 TPACPI_ACPIHANDLE_INIT(ledb);
4836 TPACPI_ACPIHANDLE_INIT(lght);
4837 }
4838 TPACPI_ACPIHANDLE_INIT(cmos);
4839 INIT_WORK(&tpacpi_led_thinklight.work, light_set_status_worker);
4840
4841
4842 tp_features.light = (cmos_handle || lght_handle) && !ledb_handle;
4843
4844 if (tp_features.light)
4845
4846
4847 tp_features.light_status =
4848 acpi_evalf(ec_handle, NULL, "KBLT", "qv");
4849
4850 vdbg_printk(TPACPI_DBG_INIT, "light is %s, light status is %s\n",
4851 str_supported(tp_features.light),
4852 str_supported(tp_features.light_status));
4853
4854 if (!tp_features.light)
4855 return 1;
4856
4857 rc = led_classdev_register(&tpacpi_pdev->dev,
4858 &tpacpi_led_thinklight.led_classdev);
4859
4860 if (rc < 0) {
4861 tp_features.light = 0;
4862 tp_features.light_status = 0;
4863 } else {
4864 rc = 0;
4865 }
4866
4867 return rc;
4868}
4869
4870static void light_exit(void)
4871{
4872 led_classdev_unregister(&tpacpi_led_thinklight.led_classdev);
4873 if (work_pending(&tpacpi_led_thinklight.work))
4874 flush_workqueue(tpacpi_wq);
4875}
4876
4877static int light_read(struct seq_file *m)
4878{
4879 int status;
4880
4881 if (!tp_features.light) {
4882 seq_printf(m, "status:\t\tnot supported\n");
4883 } else if (!tp_features.light_status) {
4884 seq_printf(m, "status:\t\tunknown\n");
4885 seq_printf(m, "commands:\ton, off\n");
4886 } else {
4887 status = light_get_status();
4888 if (status < 0)
4889 return status;
4890 seq_printf(m, "status:\t\t%s\n", onoff(status, 0));
4891 seq_printf(m, "commands:\ton, off\n");
4892 }
4893
4894 return 0;
4895}
4896
4897static int light_write(char *buf)
4898{
4899 char *cmd;
4900 int newstatus = 0;
4901
4902 if (!tp_features.light)
4903 return -ENODEV;
4904
4905 while ((cmd = next_cmd(&buf))) {
4906 if (strlencmp(cmd, "on") == 0) {
4907 newstatus = 1;
4908 } else if (strlencmp(cmd, "off") == 0) {
4909 newstatus = 0;
4910 } else
4911 return -EINVAL;
4912 }
4913
4914 return light_set_status(newstatus);
4915}
4916
4917static struct ibm_struct light_driver_data = {
4918 .name = "light",
4919 .read = light_read,
4920 .write = light_write,
4921 .exit = light_exit,
4922};
4923
4924
4925
4926
4927
4928
4929static ssize_t cmos_command_store(struct device *dev,
4930 struct device_attribute *attr,
4931 const char *buf, size_t count)
4932{
4933 unsigned long cmos_cmd;
4934 int res;
4935
4936 if (parse_strtoul(buf, 21, &cmos_cmd))
4937 return -EINVAL;
4938
4939 res = issue_thinkpad_cmos_command(cmos_cmd);
4940 return (res)? res : count;
4941}
4942
4943static struct device_attribute dev_attr_cmos_command =
4944 __ATTR(cmos_command, S_IWUSR, NULL, cmos_command_store);
4945
4946
4947
4948static int __init cmos_init(struct ibm_init_struct *iibm)
4949{
4950 int res;
4951
4952 vdbg_printk(TPACPI_DBG_INIT,
4953 "initializing cmos commands subdriver\n");
4954
4955 TPACPI_ACPIHANDLE_INIT(cmos);
4956
4957 vdbg_printk(TPACPI_DBG_INIT, "cmos commands are %s\n",
4958 str_supported(cmos_handle != NULL));
4959
4960 res = device_create_file(&tpacpi_pdev->dev, &dev_attr_cmos_command);
4961 if (res)
4962 return res;
4963
4964 return (cmos_handle)? 0 : 1;
4965}
4966
4967static void cmos_exit(void)
4968{
4969 device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command);
4970}
4971
4972static int cmos_read(struct seq_file *m)
4973{
4974
4975
4976 if (!cmos_handle)
4977 seq_printf(m, "status:\t\tnot supported\n");
4978 else {
4979 seq_printf(m, "status:\t\tsupported\n");
4980 seq_printf(m, "commands:\t<cmd> (<cmd> is 0-21)\n");
4981 }
4982
4983 return 0;
4984}
4985
4986static int cmos_write(char *buf)
4987{
4988 char *cmd;
4989 int cmos_cmd, res;
4990
4991 while ((cmd = next_cmd(&buf))) {
4992 if (sscanf(cmd, "%u", &cmos_cmd) == 1 &&
4993 cmos_cmd >= 0 && cmos_cmd <= 21) {
4994
4995 } else
4996 return -EINVAL;
4997
4998 res = issue_thinkpad_cmos_command(cmos_cmd);
4999 if (res)
5000 return res;
5001 }
5002
5003 return 0;
5004}
5005
5006static struct ibm_struct cmos_driver_data = {
5007 .name = "cmos",
5008 .read = cmos_read,
5009 .write = cmos_write,
5010 .exit = cmos_exit,
5011};
5012
5013
5014
5015
5016
5017enum led_access_mode {
5018 TPACPI_LED_NONE = 0,
5019 TPACPI_LED_570,
5020 TPACPI_LED_OLD,
5021 TPACPI_LED_NEW,
5022};
5023
5024enum {
5025 TPACPI_LED_EC_HLCL = 0x0c,
5026 TPACPI_LED_EC_HLBL = 0x0d,
5027 TPACPI_LED_EC_HLMS = 0x0e,
5028};
5029
5030static enum led_access_mode led_supported;
5031
5032static acpi_handle led_handle;
5033
5034#define TPACPI_LED_NUMLEDS 16
5035static struct tpacpi_led_classdev *tpacpi_leds;
5036static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS];
5037static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = {
5038
5039 "tpacpi::power",
5040 "tpacpi:orange:batt",
5041 "tpacpi:green:batt",
5042 "tpacpi::dock_active",
5043 "tpacpi::bay_active",
5044 "tpacpi::dock_batt",
5045 "tpacpi::unknown_led",
5046 "tpacpi::standby",
5047 "tpacpi::dock_status1",
5048 "tpacpi::dock_status2",
5049 "tpacpi::unknown_led2",
5050 "tpacpi::unknown_led3",
5051 "tpacpi::thinkvantage",
5052};
5053#define TPACPI_SAFE_LEDS 0x1081U
5054
5055static inline bool tpacpi_is_led_restricted(const unsigned int led)
5056{
5057#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
5058 return false;
5059#else
5060 return (1U & (TPACPI_SAFE_LEDS >> led)) == 0;
5061#endif
5062}
5063
5064static int led_get_status(const unsigned int led)
5065{
5066 int status;
5067 enum led_status_t led_s;
5068
5069 switch (led_supported) {
5070 case TPACPI_LED_570:
5071 if (!acpi_evalf(ec_handle,
5072 &status, "GLED", "dd", 1 << led))
5073 return -EIO;
5074 led_s = (status == 0)?
5075 TPACPI_LED_OFF :
5076 ((status == 1)?
5077 TPACPI_LED_ON :
5078 TPACPI_LED_BLINK);
5079 tpacpi_led_state_cache[led] = led_s;
5080 return led_s;
5081 default:
5082 return -ENXIO;
5083 }
5084
5085
5086}
5087
5088static int led_set_status(const unsigned int led,
5089 const enum led_status_t ledstatus)
5090{
5091
5092 static const unsigned int led_sled_arg1[] = { 0, 1, 3 };
5093 static const unsigned int led_led_arg1[] = { 0, 0x80, 0xc0 };
5094
5095 int rc = 0;
5096
5097 switch (led_supported) {
5098 case TPACPI_LED_570:
5099
5100 if (unlikely(led > 7))
5101 return -EINVAL;
5102 if (unlikely(tpacpi_is_led_restricted(led)))
5103 return -EPERM;
5104 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
5105 (1 << led), led_sled_arg1[ledstatus]))
5106 rc = -EIO;
5107 break;
5108 case TPACPI_LED_OLD:
5109
5110 if (unlikely(led > 7))
5111 return -EINVAL;
5112 if (unlikely(tpacpi_is_led_restricted(led)))
5113 return -EPERM;
5114 rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led));
5115 if (rc >= 0)
5116 rc = ec_write(TPACPI_LED_EC_HLBL,
5117 (ledstatus == TPACPI_LED_BLINK) << led);
5118 if (rc >= 0)
5119 rc = ec_write(TPACPI_LED_EC_HLCL,
5120 (ledstatus != TPACPI_LED_OFF) << led);
5121 break;
5122 case TPACPI_LED_NEW:
5123
5124 if (unlikely(led >= TPACPI_LED_NUMLEDS))
5125 return -EINVAL;
5126 if (unlikely(tpacpi_is_led_restricted(led)))
5127 return -EPERM;
5128 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
5129 led, led_led_arg1[ledstatus]))
5130 rc = -EIO;
5131 break;
5132 default:
5133 rc = -ENXIO;
5134 }
5135
5136 if (!rc)
5137 tpacpi_led_state_cache[led] = ledstatus;
5138
5139 return rc;
5140}
5141
5142static void led_set_status_worker(struct work_struct *work)
5143{
5144 struct tpacpi_led_classdev *data =
5145 container_of(work, struct tpacpi_led_classdev, work);
5146
5147 if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
5148 led_set_status(data->led, data->new_state);
5149}
5150
5151static void led_sysfs_set(struct led_classdev *led_cdev,
5152 enum led_brightness brightness)
5153{
5154 struct tpacpi_led_classdev *data = container_of(led_cdev,
5155 struct tpacpi_led_classdev, led_classdev);
5156
5157 if (brightness == LED_OFF)
5158 data->new_state = TPACPI_LED_OFF;
5159 else if (tpacpi_led_state_cache[data->led] != TPACPI_LED_BLINK)
5160 data->new_state = TPACPI_LED_ON;
5161 else
5162 data->new_state = TPACPI_LED_BLINK;
5163
5164 queue_work(tpacpi_wq, &data->work);
5165}
5166
5167static int led_sysfs_blink_set(struct led_classdev *led_cdev,
5168 unsigned long *delay_on, unsigned long *delay_off)
5169{
5170 struct tpacpi_led_classdev *data = container_of(led_cdev,
5171 struct tpacpi_led_classdev, led_classdev);
5172
5173
5174 if (*delay_on == 0 && *delay_off == 0) {
5175
5176 *delay_on = 500;
5177 *delay_off = 500;
5178 } else if ((*delay_on != 500) || (*delay_off != 500))
5179 return -EINVAL;
5180
5181 data->new_state = TPACPI_LED_BLINK;
5182 queue_work(tpacpi_wq, &data->work);
5183
5184 return 0;
5185}
5186
5187static enum led_brightness led_sysfs_get(struct led_classdev *led_cdev)
5188{
5189 int rc;
5190
5191 struct tpacpi_led_classdev *data = container_of(led_cdev,
5192 struct tpacpi_led_classdev, led_classdev);
5193
5194 rc = led_get_status(data->led);
5195
5196 if (rc == TPACPI_LED_OFF || rc < 0)
5197 rc = LED_OFF;
5198 else
5199 rc = LED_FULL;
5200
5201 return rc;
5202}
5203
5204static void led_exit(void)
5205{
5206 unsigned int i;
5207
5208 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
5209 if (tpacpi_leds[i].led_classdev.name)
5210 led_classdev_unregister(&tpacpi_leds[i].led_classdev);
5211 }
5212
5213 kfree(tpacpi_leds);
5214}
5215
5216static int __init tpacpi_init_led(unsigned int led)
5217{
5218 int rc;
5219
5220 tpacpi_leds[led].led = led;
5221
5222
5223 if (!tpacpi_led_names[led])
5224 return 0;
5225
5226 tpacpi_leds[led].led_classdev.brightness_set = &led_sysfs_set;
5227 tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set;
5228 if (led_supported == TPACPI_LED_570)
5229 tpacpi_leds[led].led_classdev.brightness_get =
5230 &led_sysfs_get;
5231
5232 tpacpi_leds[led].led_classdev.name = tpacpi_led_names[led];
5233
5234 INIT_WORK(&tpacpi_leds[led].work, led_set_status_worker);
5235
5236 rc = led_classdev_register(&tpacpi_pdev->dev,
5237 &tpacpi_leds[led].led_classdev);
5238 if (rc < 0)
5239 tpacpi_leds[led].led_classdev.name = NULL;
5240
5241 return rc;
5242}
5243
5244static const struct tpacpi_quirk led_useful_qtable[] __initconst = {
5245 TPACPI_Q_IBM('1', 'E', 0x009f),
5246 TPACPI_Q_IBM('1', 'N', 0x009f),
5247 TPACPI_Q_IBM('1', 'G', 0x009f),
5248
5249 TPACPI_Q_IBM('1', 'I', 0x0097),
5250 TPACPI_Q_IBM('1', 'R', 0x0097),
5251 TPACPI_Q_IBM('7', '0', 0x0097),
5252 TPACPI_Q_IBM('1', 'Y', 0x0097),
5253 TPACPI_Q_IBM('1', 'W', 0x0097),
5254 TPACPI_Q_IBM('1', 'V', 0x0097),
5255 TPACPI_Q_IBM('7', '8', 0x0097),
5256 TPACPI_Q_IBM('7', '6', 0x0097),
5257
5258 TPACPI_Q_IBM('1', 'K', 0x00bf),
5259 TPACPI_Q_IBM('1', 'Q', 0x00bf),
5260 TPACPI_Q_IBM('1', 'U', 0x00bf),
5261 TPACPI_Q_IBM('7', '4', 0x00bf),
5262 TPACPI_Q_IBM('7', '5', 0x00bf),
5263
5264 TPACPI_Q_IBM('7', '9', 0x1f97),
5265 TPACPI_Q_IBM('7', '7', 0x1f97),
5266 TPACPI_Q_IBM('7', 'F', 0x1f97),
5267 TPACPI_Q_IBM('7', 'B', 0x1fb7),
5268
5269
5270
5271
5272 {
5273 .vendor = PCI_VENDOR_ID_LENOVO,
5274 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
5275 .quirks = 0x1fffU,
5276 },
5277 {
5278 .vendor = PCI_VENDOR_ID_IBM,
5279 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_UNKNOWN,
5280 .quirks = 0x00ffU,
5281 },
5282 {
5283 .vendor = PCI_VENDOR_ID_IBM,
5284 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
5285 .quirks = 0x00bfU,
5286 },
5287};
5288
5289#undef TPACPI_LEDQ_IBM
5290#undef TPACPI_LEDQ_LNV
5291
5292static enum led_access_mode __init led_init_detect_mode(void)
5293{
5294 acpi_status status;
5295
5296 if (tpacpi_is_ibm()) {
5297
5298 status = acpi_get_handle(ec_handle, "SLED", &led_handle);
5299 if (ACPI_SUCCESS(status))
5300 return TPACPI_LED_570;
5301
5302
5303 status = acpi_get_handle(ec_handle, "SYSL", &led_handle);
5304 if (ACPI_SUCCESS(status))
5305 return TPACPI_LED_OLD;
5306 }
5307
5308
5309 status = acpi_get_handle(ec_handle, "LED", &led_handle);
5310 if (ACPI_SUCCESS(status))
5311 return TPACPI_LED_NEW;
5312
5313
5314 led_handle = NULL;
5315 return TPACPI_LED_NONE;
5316}
5317
5318static int __init led_init(struct ibm_init_struct *iibm)
5319{
5320 unsigned int i;
5321 int rc;
5322 unsigned long useful_leds;
5323
5324 vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
5325
5326 led_supported = led_init_detect_mode();
5327
5328 vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n",
5329 str_supported(led_supported), led_supported);
5330
5331 if (led_supported == TPACPI_LED_NONE)
5332 return 1;
5333
5334 tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS,
5335 GFP_KERNEL);
5336 if (!tpacpi_leds) {
5337 pr_err("Out of memory for LED data\n");
5338 return -ENOMEM;
5339 }
5340
5341 useful_leds = tpacpi_check_quirks(led_useful_qtable,
5342 ARRAY_SIZE(led_useful_qtable));
5343
5344 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
5345 if (!tpacpi_is_led_restricted(i) &&
5346 test_bit(i, &useful_leds)) {
5347 rc = tpacpi_init_led(i);
5348 if (rc < 0) {
5349 led_exit();
5350 return rc;
5351 }
5352 }
5353 }
5354
5355#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
5356 pr_notice("warning: userspace override of important "
5357 "firmware LEDs is enabled\n");
5358#endif
5359 return 0;
5360}
5361
5362#define str_led_status(s) \
5363 ((s) == TPACPI_LED_OFF ? "off" : \
5364 ((s) == TPACPI_LED_ON ? "on" : "blinking"))
5365
5366static int led_read(struct seq_file *m)
5367{
5368 if (!led_supported) {
5369 seq_printf(m, "status:\t\tnot supported\n");
5370 return 0;
5371 }
5372 seq_printf(m, "status:\t\tsupported\n");
5373
5374 if (led_supported == TPACPI_LED_570) {
5375
5376 int i, status;
5377 for (i = 0; i < 8; i++) {
5378 status = led_get_status(i);
5379 if (status < 0)
5380 return -EIO;
5381 seq_printf(m, "%d:\t\t%s\n",
5382 i, str_led_status(status));
5383 }
5384 }
5385
5386 seq_printf(m, "commands:\t"
5387 "<led> on, <led> off, <led> blink (<led> is 0-15)\n");
5388
5389 return 0;
5390}
5391
5392static int led_write(char *buf)
5393{
5394 char *cmd;
5395 int led, rc;
5396 enum led_status_t s;
5397
5398 if (!led_supported)
5399 return -ENODEV;
5400
5401 while ((cmd = next_cmd(&buf))) {
5402 if (sscanf(cmd, "%d", &led) != 1 || led < 0 || led > 15)
5403 return -EINVAL;
5404
5405 if (strstr(cmd, "off")) {
5406 s = TPACPI_LED_OFF;
5407 } else if (strstr(cmd, "on")) {
5408 s = TPACPI_LED_ON;
5409 } else if (strstr(cmd, "blink")) {
5410 s = TPACPI_LED_BLINK;
5411 } else {
5412 return -EINVAL;
5413 }
5414
5415 rc = led_set_status(led, s);
5416 if (rc < 0)
5417 return rc;
5418 }
5419
5420 return 0;
5421}
5422
5423static struct ibm_struct led_driver_data = {
5424 .name = "led",
5425 .read = led_read,
5426 .write = led_write,
5427 .exit = led_exit,
5428};
5429
5430
5431
5432
5433
5434TPACPI_HANDLE(beep, ec, "BEEP");
5435
5436#define TPACPI_BEEP_Q1 0x0001
5437
5438static const struct tpacpi_quirk beep_quirk_table[] __initconst = {
5439 TPACPI_Q_IBM('I', 'M', TPACPI_BEEP_Q1),
5440 TPACPI_Q_IBM('I', 'U', TPACPI_BEEP_Q1),
5441};
5442
5443static int __init beep_init(struct ibm_init_struct *iibm)
5444{
5445 unsigned long quirks;
5446
5447 vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n");
5448
5449 TPACPI_ACPIHANDLE_INIT(beep);
5450
5451 vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n",
5452 str_supported(beep_handle != NULL));
5453
5454 quirks = tpacpi_check_quirks(beep_quirk_table,
5455 ARRAY_SIZE(beep_quirk_table));
5456
5457 tp_features.beep_needs_two_args = !!(quirks & TPACPI_BEEP_Q1);
5458
5459 return (beep_handle)? 0 : 1;
5460}
5461
5462static int beep_read(struct seq_file *m)
5463{
5464 if (!beep_handle)
5465 seq_printf(m, "status:\t\tnot supported\n");
5466 else {
5467 seq_printf(m, "status:\t\tsupported\n");
5468 seq_printf(m, "commands:\t<cmd> (<cmd> is 0-17)\n");
5469 }
5470
5471 return 0;
5472}
5473
5474static int beep_write(char *buf)
5475{
5476 char *cmd;
5477 int beep_cmd;
5478
5479 if (!beep_handle)
5480 return -ENODEV;
5481
5482 while ((cmd = next_cmd(&buf))) {
5483 if (sscanf(cmd, "%u", &beep_cmd) == 1 &&
5484 beep_cmd >= 0 && beep_cmd <= 17) {
5485
5486 } else
5487 return -EINVAL;
5488 if (tp_features.beep_needs_two_args) {
5489 if (!acpi_evalf(beep_handle, NULL, NULL, "vdd",
5490 beep_cmd, 0))
5491 return -EIO;
5492 } else {
5493 if (!acpi_evalf(beep_handle, NULL, NULL, "vd",
5494 beep_cmd))
5495 return -EIO;
5496 }
5497 }
5498
5499 return 0;
5500}
5501
5502static struct ibm_struct beep_driver_data = {
5503 .name = "beep",
5504 .read = beep_read,
5505 .write = beep_write,
5506};
5507
5508
5509
5510
5511
5512enum thermal_access_mode {
5513 TPACPI_THERMAL_NONE = 0,
5514 TPACPI_THERMAL_ACPI_TMP07,
5515 TPACPI_THERMAL_ACPI_UPDT,
5516 TPACPI_THERMAL_TPEC_8,
5517 TPACPI_THERMAL_TPEC_16,
5518};
5519
5520enum {
5521 TP_EC_THERMAL_TMP0 = 0x78,
5522 TP_EC_THERMAL_TMP8 = 0xC0,
5523 TP_EC_THERMAL_TMP_NA = -128,
5524
5525 TPACPI_THERMAL_SENSOR_NA = -128000,
5526};
5527
5528
5529#define TPACPI_MAX_THERMAL_SENSORS 16
5530struct ibm_thermal_sensors_struct {
5531 s32 temp[TPACPI_MAX_THERMAL_SENSORS];
5532};
5533
5534static enum thermal_access_mode thermal_read_mode;
5535
5536
5537static int thermal_get_sensor(int idx, s32 *value)
5538{
5539 int t;
5540 s8 tmp;
5541 char tmpi[5];
5542
5543 t = TP_EC_THERMAL_TMP0;
5544
5545 switch (thermal_read_mode) {
5546#if TPACPI_MAX_THERMAL_SENSORS >= 16
5547 case TPACPI_THERMAL_TPEC_16:
5548 if (idx >= 8 && idx <= 15) {
5549 t = TP_EC_THERMAL_TMP8;
5550 idx -= 8;
5551 }
5552
5553#endif
5554 case TPACPI_THERMAL_TPEC_8:
5555 if (idx <= 7) {
5556 if (!acpi_ec_read(t + idx, &tmp))
5557 return -EIO;
5558 *value = tmp * 1000;
5559 return 0;
5560 }
5561 break;
5562
5563 case TPACPI_THERMAL_ACPI_UPDT:
5564 if (idx <= 7) {
5565 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
5566 if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
5567 return -EIO;
5568 if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
5569 return -EIO;
5570 *value = (t - 2732) * 100;
5571 return 0;
5572 }
5573 break;
5574
5575 case TPACPI_THERMAL_ACPI_TMP07:
5576 if (idx <= 7) {
5577 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
5578 if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
5579 return -EIO;
5580 if (t > 127 || t < -127)
5581 t = TP_EC_THERMAL_TMP_NA;
5582 *value = t * 1000;
5583 return 0;
5584 }
5585 break;
5586
5587 case TPACPI_THERMAL_NONE:
5588 default:
5589 return -ENOSYS;
5590 }
5591
5592 return -EINVAL;
5593}
5594
5595static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
5596{
5597 int res, i;
5598 int n;
5599
5600 n = 8;
5601 i = 0;
5602
5603 if (!s)
5604 return -EINVAL;
5605
5606 if (thermal_read_mode == TPACPI_THERMAL_TPEC_16)
5607 n = 16;
5608
5609 for (i = 0 ; i < n; i++) {
5610 res = thermal_get_sensor(i, &s->temp[i]);
5611 if (res)
5612 return res;
5613 }
5614
5615 return n;
5616}
5617
5618static void thermal_dump_all_sensors(void)
5619{
5620 int n, i;
5621 struct ibm_thermal_sensors_struct t;
5622
5623 n = thermal_get_sensors(&t);
5624 if (n <= 0)
5625 return;
5626
5627 pr_notice("temperatures (Celsius):");
5628
5629 for (i = 0; i < n; i++) {
5630 if (t.temp[i] != TPACPI_THERMAL_SENSOR_NA)
5631 pr_cont(" %d", (int)(t.temp[i] / 1000));
5632 else
5633 pr_cont(" N/A");
5634 }
5635
5636 pr_cont("\n");
5637}
5638
5639
5640
5641static ssize_t thermal_temp_input_show(struct device *dev,
5642 struct device_attribute *attr,
5643 char *buf)
5644{
5645 struct sensor_device_attribute *sensor_attr =
5646 to_sensor_dev_attr(attr);
5647 int idx = sensor_attr->index;
5648 s32 value;
5649 int res;
5650
5651 res = thermal_get_sensor(idx, &value);
5652 if (res)
5653 return res;
5654 if (value == TPACPI_THERMAL_SENSOR_NA)
5655 return -ENXIO;
5656
5657 return snprintf(buf, PAGE_SIZE, "%d\n", value);
5658}
5659
5660#define THERMAL_SENSOR_ATTR_TEMP(_idxA, _idxB) \
5661 SENSOR_ATTR(temp##_idxA##_input, S_IRUGO, \
5662 thermal_temp_input_show, NULL, _idxB)
5663
5664static struct sensor_device_attribute sensor_dev_attr_thermal_temp_input[] = {
5665 THERMAL_SENSOR_ATTR_TEMP(1, 0),
5666 THERMAL_SENSOR_ATTR_TEMP(2, 1),
5667 THERMAL_SENSOR_ATTR_TEMP(3, 2),
5668 THERMAL_SENSOR_ATTR_TEMP(4, 3),
5669 THERMAL_SENSOR_ATTR_TEMP(5, 4),
5670 THERMAL_SENSOR_ATTR_TEMP(6, 5),
5671 THERMAL_SENSOR_ATTR_TEMP(7, 6),
5672 THERMAL_SENSOR_ATTR_TEMP(8, 7),
5673 THERMAL_SENSOR_ATTR_TEMP(9, 8),
5674 THERMAL_SENSOR_ATTR_TEMP(10, 9),
5675 THERMAL_SENSOR_ATTR_TEMP(11, 10),
5676 THERMAL_SENSOR_ATTR_TEMP(12, 11),
5677 THERMAL_SENSOR_ATTR_TEMP(13, 12),
5678 THERMAL_SENSOR_ATTR_TEMP(14, 13),
5679 THERMAL_SENSOR_ATTR_TEMP(15, 14),
5680 THERMAL_SENSOR_ATTR_TEMP(16, 15),
5681};
5682
5683#define THERMAL_ATTRS(X) \
5684 &sensor_dev_attr_thermal_temp_input[X].dev_attr.attr
5685
5686static struct attribute *thermal_temp_input_attr[] = {
5687 THERMAL_ATTRS(8),
5688 THERMAL_ATTRS(9),
5689 THERMAL_ATTRS(10),
5690 THERMAL_ATTRS(11),
5691 THERMAL_ATTRS(12),
5692 THERMAL_ATTRS(13),
5693 THERMAL_ATTRS(14),
5694 THERMAL_ATTRS(15),
5695 THERMAL_ATTRS(0),
5696 THERMAL_ATTRS(1),
5697 THERMAL_ATTRS(2),
5698 THERMAL_ATTRS(3),
5699 THERMAL_ATTRS(4),
5700 THERMAL_ATTRS(5),
5701 THERMAL_ATTRS(6),
5702 THERMAL_ATTRS(7),
5703 NULL
5704};
5705
5706static const struct attribute_group thermal_temp_input16_group = {
5707 .attrs = thermal_temp_input_attr
5708};
5709
5710static const struct attribute_group thermal_temp_input8_group = {
5711 .attrs = &thermal_temp_input_attr[8]
5712};
5713
5714#undef THERMAL_SENSOR_ATTR_TEMP
5715#undef THERMAL_ATTRS
5716
5717
5718
5719static int __init thermal_init(struct ibm_init_struct *iibm)
5720{
5721 u8 t, ta1, ta2;
5722 int i;
5723 int acpi_tmp7;
5724 int res;
5725
5726 vdbg_printk(TPACPI_DBG_INIT, "initializing thermal subdriver\n");
5727
5728 acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
5729
5730 if (thinkpad_id.ec_model) {
5731
5732
5733
5734
5735
5736
5737
5738 ta1 = ta2 = 0;
5739 for (i = 0; i < 8; i++) {
5740 if (acpi_ec_read(TP_EC_THERMAL_TMP0 + i, &t)) {
5741 ta1 |= t;
5742 } else {
5743 ta1 = 0;
5744 break;
5745 }
5746 if (acpi_ec_read(TP_EC_THERMAL_TMP8 + i, &t)) {
5747 ta2 |= t;
5748 } else {
5749 ta1 = 0;
5750 break;
5751 }
5752 }
5753 if (ta1 == 0) {
5754
5755 if (acpi_tmp7) {
5756 pr_err("ThinkPad ACPI EC access misbehaving, "
5757 "falling back to ACPI TMPx access "
5758 "mode\n");
5759 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;
5760 } else {
5761 pr_err("ThinkPad ACPI EC access misbehaving, "
5762 "disabling thermal sensors access\n");
5763 thermal_read_mode = TPACPI_THERMAL_NONE;
5764 }
5765 } else {
5766 thermal_read_mode =
5767 (ta2 != 0) ?
5768 TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8;
5769 }
5770 } else if (acpi_tmp7) {
5771 if (tpacpi_is_ibm() &&
5772 acpi_evalf(ec_handle, NULL, "UPDT", "qv")) {
5773
5774 thermal_read_mode = TPACPI_THERMAL_ACPI_UPDT;
5775 } else {
5776
5777 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;
5778 }
5779 } else {
5780
5781 thermal_read_mode = TPACPI_THERMAL_NONE;
5782 }
5783
5784 vdbg_printk(TPACPI_DBG_INIT, "thermal is %s, mode %d\n",
5785 str_supported(thermal_read_mode != TPACPI_THERMAL_NONE),
5786 thermal_read_mode);
5787
5788 switch (thermal_read_mode) {
5789 case TPACPI_THERMAL_TPEC_16:
5790 res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
5791 &thermal_temp_input16_group);
5792 if (res)
5793 return res;
5794 break;
5795 case TPACPI_THERMAL_TPEC_8:
5796 case TPACPI_THERMAL_ACPI_TMP07:
5797 case TPACPI_THERMAL_ACPI_UPDT:
5798 res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
5799 &thermal_temp_input8_group);
5800 if (res)
5801 return res;
5802 break;
5803 case TPACPI_THERMAL_NONE:
5804 default:
5805 return 1;
5806 }
5807
5808 return 0;
5809}
5810
5811static void thermal_exit(void)
5812{
5813 switch (thermal_read_mode) {
5814 case TPACPI_THERMAL_TPEC_16:
5815 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
5816 &thermal_temp_input16_group);
5817 break;
5818 case TPACPI_THERMAL_TPEC_8:
5819 case TPACPI_THERMAL_ACPI_TMP07:
5820 case TPACPI_THERMAL_ACPI_UPDT:
5821 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
5822 &thermal_temp_input8_group);
5823 break;
5824 case TPACPI_THERMAL_NONE:
5825 default:
5826 break;
5827 }
5828}
5829
5830static int thermal_read(struct seq_file *m)
5831{
5832 int n, i;
5833 struct ibm_thermal_sensors_struct t;
5834
5835 n = thermal_get_sensors(&t);
5836 if (unlikely(n < 0))
5837 return n;
5838
5839 seq_printf(m, "temperatures:\t");
5840
5841 if (n > 0) {
5842 for (i = 0; i < (n - 1); i++)
5843 seq_printf(m, "%d ", t.temp[i] / 1000);
5844 seq_printf(m, "%d\n", t.temp[i] / 1000);
5845 } else
5846 seq_printf(m, "not supported\n");
5847
5848 return 0;
5849}
5850
5851static struct ibm_struct thermal_driver_data = {
5852 .name = "thermal",
5853 .read = thermal_read,
5854 .exit = thermal_exit,
5855};
5856
5857
5858
5859
5860
5861#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881enum {
5882 TP_EC_BACKLIGHT = 0x31,
5883
5884
5885 TP_EC_BACKLIGHT_LVLMSK = 0x1F,
5886 TP_EC_BACKLIGHT_CMDMSK = 0xE0,
5887 TP_EC_BACKLIGHT_MAPSW = 0x20,
5888};
5889
5890enum tpacpi_brightness_access_mode {
5891 TPACPI_BRGHT_MODE_AUTO = 0,
5892 TPACPI_BRGHT_MODE_EC,
5893 TPACPI_BRGHT_MODE_UCMS_STEP,
5894 TPACPI_BRGHT_MODE_ECNVRAM,
5895 TPACPI_BRGHT_MODE_MAX
5896};
5897
5898static struct backlight_device *ibm_backlight_device;
5899
5900static enum tpacpi_brightness_access_mode brightness_mode =
5901 TPACPI_BRGHT_MODE_MAX;
5902
5903static unsigned int brightness_enable = 2;
5904
5905static struct mutex brightness_mutex;
5906
5907
5908
5909static unsigned int tpacpi_brightness_nvram_get(void)
5910{
5911 u8 lnvram;
5912
5913 lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
5914 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
5915 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
5916 lnvram &= bright_maxlvl;
5917
5918 return lnvram;
5919}
5920
5921static void tpacpi_brightness_checkpoint_nvram(void)
5922{
5923 u8 lec = 0;
5924 u8 b_nvram;
5925
5926 if (brightness_mode != TPACPI_BRGHT_MODE_ECNVRAM)
5927 return;
5928
5929 vdbg_printk(TPACPI_DBG_BRGHT,
5930 "trying to checkpoint backlight level to NVRAM...\n");
5931
5932 if (mutex_lock_killable(&brightness_mutex) < 0)
5933 return;
5934
5935 if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
5936 goto unlock;
5937 lec &= TP_EC_BACKLIGHT_LVLMSK;
5938 b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
5939
5940 if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
5941 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {
5942
5943 b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<
5944 TP_NVRAM_POS_LEVEL_BRIGHTNESS);
5945 b_nvram |= lec;
5946 nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
5947 dbg_printk(TPACPI_DBG_BRGHT,
5948 "updated NVRAM backlight level to %u (0x%02x)\n",
5949 (unsigned int) lec, (unsigned int) b_nvram);
5950 } else
5951 vdbg_printk(TPACPI_DBG_BRGHT,
5952 "NVRAM backlight level already is %u (0x%02x)\n",
5953 (unsigned int) lec, (unsigned int) b_nvram);
5954
5955unlock:
5956 mutex_unlock(&brightness_mutex);
5957}
5958
5959
5960
5961static int tpacpi_brightness_get_raw(int *status)
5962{
5963 u8 lec = 0;
5964
5965 switch (brightness_mode) {
5966 case TPACPI_BRGHT_MODE_UCMS_STEP:
5967 *status = tpacpi_brightness_nvram_get();
5968 return 0;
5969 case TPACPI_BRGHT_MODE_EC:
5970 case TPACPI_BRGHT_MODE_ECNVRAM:
5971 if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
5972 return -EIO;
5973 *status = lec;
5974 return 0;
5975 default:
5976 return -ENXIO;
5977 }
5978}
5979
5980
5981
5982static int tpacpi_brightness_set_ec(unsigned int value)
5983{
5984 u8 lec = 0;
5985
5986 if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
5987 return -EIO;
5988
5989 if (unlikely(!acpi_ec_write(TP_EC_BACKLIGHT,
5990 (lec & TP_EC_BACKLIGHT_CMDMSK) |
5991 (value & TP_EC_BACKLIGHT_LVLMSK))))
5992 return -EIO;
5993
5994 return 0;
5995}
5996
5997
5998static int tpacpi_brightness_set_ucmsstep(unsigned int value)
5999{
6000 int cmos_cmd, inc;
6001 unsigned int current_value, i;
6002
6003 current_value = tpacpi_brightness_nvram_get();
6004
6005 if (value == current_value)
6006 return 0;
6007
6008 cmos_cmd = (value > current_value) ?
6009 TP_CMOS_BRIGHTNESS_UP :
6010 TP_CMOS_BRIGHTNESS_DOWN;
6011 inc = (value > current_value) ? 1 : -1;
6012
6013 for (i = current_value; i != value; i += inc)
6014 if (issue_thinkpad_cmos_command(cmos_cmd))
6015 return -EIO;
6016
6017 return 0;
6018}
6019
6020
6021static int brightness_set(unsigned int value)
6022{
6023 int res;
6024
6025 if (value > bright_maxlvl || value < 0)
6026 return -EINVAL;
6027
6028 vdbg_printk(TPACPI_DBG_BRGHT,
6029 "set backlight level to %d\n", value);
6030
6031 res = mutex_lock_killable(&brightness_mutex);
6032 if (res < 0)
6033 return res;
6034
6035 switch (brightness_mode) {
6036 case TPACPI_BRGHT_MODE_EC:
6037 case TPACPI_BRGHT_MODE_ECNVRAM:
6038 res = tpacpi_brightness_set_ec(value);
6039 break;
6040 case TPACPI_BRGHT_MODE_UCMS_STEP:
6041 res = tpacpi_brightness_set_ucmsstep(value);
6042 break;
6043 default:
6044 res = -ENXIO;
6045 }
6046
6047 mutex_unlock(&brightness_mutex);
6048 return res;
6049}
6050
6051
6052
6053static int brightness_update_status(struct backlight_device *bd)
6054{
6055 unsigned int level =
6056 (bd->props.fb_blank == FB_BLANK_UNBLANK &&
6057 bd->props.power == FB_BLANK_UNBLANK) ?
6058 bd->props.brightness : 0;
6059
6060 dbg_printk(TPACPI_DBG_BRGHT,
6061 "backlight: attempt to set level to %d\n",
6062 level);
6063
6064
6065
6066 return brightness_set(level);
6067}
6068
6069static int brightness_get(struct backlight_device *bd)
6070{
6071 int status, res;
6072
6073 res = mutex_lock_killable(&brightness_mutex);
6074 if (res < 0)
6075 return 0;
6076
6077 res = tpacpi_brightness_get_raw(&status);
6078
6079 mutex_unlock(&brightness_mutex);
6080
6081 if (res < 0)
6082 return 0;
6083
6084 return status & TP_EC_BACKLIGHT_LVLMSK;
6085}
6086
6087static void tpacpi_brightness_notify_change(void)
6088{
6089 backlight_force_update(ibm_backlight_device,
6090 BACKLIGHT_UPDATE_HOTKEY);
6091}
6092
6093static const struct backlight_ops ibm_backlight_data = {
6094 .get_brightness = brightness_get,
6095 .update_status = brightness_update_status,
6096};
6097
6098
6099
6100
6101
6102
6103
6104
6105static int __init tpacpi_query_bcl_levels(acpi_handle handle)
6106{
6107 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
6108 union acpi_object *obj;
6109 int rc;
6110
6111 if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) {
6112 obj = (union acpi_object *)buffer.pointer;
6113 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
6114 pr_err("Unknown _BCL data, please report this to %s\n",
6115 TPACPI_MAIL);
6116 rc = 0;
6117 } else {
6118 rc = obj->package.count;
6119 }
6120 } else {
6121 return 0;
6122 }
6123
6124 kfree(buffer.pointer);
6125 return rc;
6126}
6127
6128
6129
6130
6131
6132static unsigned int __init tpacpi_check_std_acpi_brightness_support(void)
6133{
6134 acpi_handle video_device;
6135 int bcl_levels = 0;
6136
6137 tpacpi_acpi_handle_locate("video", ACPI_VIDEO_HID, &video_device);
6138 if (video_device)
6139 bcl_levels = tpacpi_query_bcl_levels(video_device);
6140
6141 tp_features.bright_acpimode = (bcl_levels > 0);
6142
6143 return (bcl_levels > 2) ? (bcl_levels - 2) : 0;
6144}
6145
6146
6147
6148
6149
6150
6151#define TPACPI_BRGHT_Q_NOEC 0x0001
6152#define TPACPI_BRGHT_Q_EC 0x0002
6153#define TPACPI_BRGHT_Q_ASK 0x8000
6154
6155static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
6156
6157 TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC),
6158
6159
6160 TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC),
6161 TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
6162 TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_EC),
6163 TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
6164
6165
6166 TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC),
6167 TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
6168 TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
6169
6170
6171 TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC),
6172 TPACPI_Q_IBM('7', '4', TPACPI_BRGHT_Q_NOEC),
6173 TPACPI_Q_IBM('7', '5', TPACPI_BRGHT_Q_NOEC),
6174};
6175
6176
6177
6178
6179
6180static void __init tpacpi_detect_brightness_capabilities(void)
6181{
6182 unsigned int b;
6183
6184 vdbg_printk(TPACPI_DBG_INIT,
6185 "detecting firmware brightness interface capabilities\n");
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195 b = tpacpi_check_std_acpi_brightness_support();
6196 switch (b) {
6197 case 16:
6198 bright_maxlvl = 15;
6199 pr_info("detected a 16-level brightness capable ThinkPad\n");
6200 break;
6201 case 8:
6202 case 0:
6203 bright_maxlvl = 7;
6204 pr_info("detected a 8-level brightness capable ThinkPad\n");
6205 break;
6206 default:
6207 pr_err("Unsupported brightness interface, "
6208 "please contact %s\n", TPACPI_MAIL);
6209 tp_features.bright_unkfw = 1;
6210 bright_maxlvl = b - 1;
6211 }
6212}
6213
6214static int __init brightness_init(struct ibm_init_struct *iibm)
6215{
6216 struct backlight_properties props;
6217 int b;
6218 unsigned long quirks;
6219
6220 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
6221
6222 mutex_init(&brightness_mutex);
6223
6224 quirks = tpacpi_check_quirks(brightness_quirk_table,
6225 ARRAY_SIZE(brightness_quirk_table));
6226
6227
6228
6229
6230 if (tp_features.bright_unkfw)
6231 return 1;
6232
6233 if (!brightness_enable) {
6234 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
6235 "brightness support disabled by "
6236 "module parameter\n");
6237 return 1;
6238 }
6239
6240 if (acpi_video_backlight_support()) {
6241 if (brightness_enable > 1) {
6242 pr_info("Standard ACPI backlight interface "
6243 "available, not loading native one\n");
6244 return 1;
6245 } else if (brightness_enable == 1) {
6246 pr_warn("Cannot enable backlight brightness support, "
6247 "ACPI is already handling it. Refer to the "
6248 "acpi_backlight kernel parameter.\n");
6249 return 1;
6250 }
6251 } else if (tp_features.bright_acpimode && brightness_enable > 1) {
6252 pr_notice("Standard ACPI backlight interface not "
6253 "available, thinkpad_acpi native "
6254 "brightness control enabled\n");
6255 }
6256
6257
6258
6259
6260
6261
6262 if (brightness_mode > TPACPI_BRGHT_MODE_MAX)
6263 return -EINVAL;
6264
6265
6266 if (brightness_mode == TPACPI_BRGHT_MODE_AUTO ||
6267 brightness_mode == TPACPI_BRGHT_MODE_MAX) {
6268 if (quirks & TPACPI_BRGHT_Q_EC)
6269 brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
6270 else
6271 brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
6272
6273 dbg_printk(TPACPI_DBG_BRGHT,
6274 "driver auto-selected brightness_mode=%d\n",
6275 brightness_mode);
6276 }
6277
6278
6279 if (!tpacpi_is_ibm() &&
6280 (brightness_mode == TPACPI_BRGHT_MODE_ECNVRAM ||
6281 brightness_mode == TPACPI_BRGHT_MODE_EC))
6282 return -EINVAL;
6283
6284 if (tpacpi_brightness_get_raw(&b) < 0)
6285 return 1;
6286
6287 memset(&props, 0, sizeof(struct backlight_properties));
6288 props.type = BACKLIGHT_PLATFORM;
6289 props.max_brightness = bright_maxlvl;
6290 props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
6291 ibm_backlight_device = backlight_device_register(TPACPI_BACKLIGHT_DEV_NAME,
6292 NULL, NULL,
6293 &ibm_backlight_data,
6294 &props);
6295 if (IS_ERR(ibm_backlight_device)) {
6296 int rc = PTR_ERR(ibm_backlight_device);
6297 ibm_backlight_device = NULL;
6298 pr_err("Could not register backlight device\n");
6299 return rc;
6300 }
6301 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
6302 "brightness is supported\n");
6303
6304 if (quirks & TPACPI_BRGHT_Q_ASK) {
6305 pr_notice("brightness: will use unverified default: "
6306 "brightness_mode=%d\n", brightness_mode);
6307 pr_notice("brightness: please report to %s whether it works well "
6308 "or not on your ThinkPad\n", TPACPI_MAIL);
6309 }
6310
6311
6312
6313
6314
6315 backlight_update_status(ibm_backlight_device);
6316
6317 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
6318 "brightness: registering brightness hotkeys "
6319 "as change notification\n");
6320 tpacpi_hotkey_driver_mask_set(hotkey_driver_mask
6321 | TP_ACPI_HKEY_BRGHTUP_MASK
6322 | TP_ACPI_HKEY_BRGHTDWN_MASK);
6323 return 0;
6324}
6325
6326static void brightness_suspend(pm_message_t state)
6327{
6328 tpacpi_brightness_checkpoint_nvram();
6329}
6330
6331static void brightness_shutdown(void)
6332{
6333 tpacpi_brightness_checkpoint_nvram();
6334}
6335
6336static void brightness_exit(void)
6337{
6338 if (ibm_backlight_device) {
6339 vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_BRGHT,
6340 "calling backlight_device_unregister()\n");
6341 backlight_device_unregister(ibm_backlight_device);
6342 }
6343
6344 tpacpi_brightness_checkpoint_nvram();
6345}
6346
6347static int brightness_read(struct seq_file *m)
6348{
6349 int level;
6350
6351 level = brightness_get(NULL);
6352 if (level < 0) {
6353 seq_printf(m, "level:\t\tunreadable\n");
6354 } else {
6355 seq_printf(m, "level:\t\t%d\n", level);
6356 seq_printf(m, "commands:\tup, down\n");
6357 seq_printf(m, "commands:\tlevel <level> (<level> is 0-%d)\n",
6358 bright_maxlvl);
6359 }
6360
6361 return 0;
6362}
6363
6364static int brightness_write(char *buf)
6365{
6366 int level;
6367 int rc;
6368 char *cmd;
6369
6370 level = brightness_get(NULL);
6371 if (level < 0)
6372 return level;
6373
6374 while ((cmd = next_cmd(&buf))) {
6375 if (strlencmp(cmd, "up") == 0) {
6376 if (level < bright_maxlvl)
6377 level++;
6378 } else if (strlencmp(cmd, "down") == 0) {
6379 if (level > 0)
6380 level--;
6381 } else if (sscanf(cmd, "level %d", &level) == 1 &&
6382 level >= 0 && level <= bright_maxlvl) {
6383
6384 } else
6385 return -EINVAL;
6386 }
6387
6388 tpacpi_disclose_usertask("procfs brightness",
6389 "set level to %d\n", level);
6390
6391
6392
6393
6394
6395 rc = brightness_set(level);
6396 if (!rc && ibm_backlight_device)
6397 backlight_force_update(ibm_backlight_device,
6398 BACKLIGHT_UPDATE_SYSFS);
6399 return (rc == -EINTR)? -ERESTARTSYS : rc;
6400}
6401
6402static struct ibm_struct brightness_driver_data = {
6403 .name = "brightness",
6404 .read = brightness_read,
6405 .write = brightness_write,
6406 .exit = brightness_exit,
6407 .suspend = brightness_suspend,
6408 .shutdown = brightness_shutdown,
6409};
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT
6434
6435#define TPACPI_ALSA_DRVNAME "ThinkPad EC"
6436#define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control"
6437#define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME
6438
6439static int alsa_index = ~((1 << (SNDRV_CARDS - 3)) - 1);
6440static char *alsa_id = "ThinkPadEC";
6441static int alsa_enable = SNDRV_DEFAULT_ENABLE1;
6442
6443struct tpacpi_alsa_data {
6444 struct snd_card *card;
6445 struct snd_ctl_elem_id *ctl_mute_id;
6446 struct snd_ctl_elem_id *ctl_vol_id;
6447};
6448
6449static struct snd_card *alsa_card;
6450
6451enum {
6452 TP_EC_AUDIO = 0x30,
6453
6454
6455 TP_EC_AUDIO_MUTESW = 6,
6456
6457
6458 TP_EC_AUDIO_LVL_MSK = 0x0F,
6459 TP_EC_AUDIO_MUTESW_MSK = (1 << TP_EC_AUDIO_MUTESW),
6460
6461
6462 TP_EC_VOLUME_MAX = 14,
6463};
6464
6465enum tpacpi_volume_access_mode {
6466 TPACPI_VOL_MODE_AUTO = 0,
6467 TPACPI_VOL_MODE_EC,
6468 TPACPI_VOL_MODE_UCMS_STEP,
6469 TPACPI_VOL_MODE_ECNVRAM,
6470 TPACPI_VOL_MODE_MAX
6471};
6472
6473enum tpacpi_volume_capabilities {
6474 TPACPI_VOL_CAP_AUTO = 0,
6475 TPACPI_VOL_CAP_VOLMUTE,
6476 TPACPI_VOL_CAP_MUTEONLY,
6477 TPACPI_VOL_CAP_MAX
6478};
6479
6480static enum tpacpi_volume_access_mode volume_mode =
6481 TPACPI_VOL_MODE_MAX;
6482
6483static enum tpacpi_volume_capabilities volume_capabilities;
6484static int volume_control_allowed;
6485
6486
6487
6488
6489
6490static struct mutex volume_mutex;
6491
6492static void tpacpi_volume_checkpoint_nvram(void)
6493{
6494 u8 lec = 0;
6495 u8 b_nvram;
6496 u8 ec_mask;
6497
6498 if (volume_mode != TPACPI_VOL_MODE_ECNVRAM)
6499 return;
6500 if (!volume_control_allowed)
6501 return;
6502
6503 vdbg_printk(TPACPI_DBG_MIXER,
6504 "trying to checkpoint mixer state to NVRAM...\n");
6505
6506 if (tp_features.mixer_no_level_control)
6507 ec_mask = TP_EC_AUDIO_MUTESW_MSK;
6508 else
6509 ec_mask = TP_EC_AUDIO_MUTESW_MSK | TP_EC_AUDIO_LVL_MSK;
6510
6511 if (mutex_lock_killable(&volume_mutex) < 0)
6512 return;
6513
6514 if (unlikely(!acpi_ec_read(TP_EC_AUDIO, &lec)))
6515 goto unlock;
6516 lec &= ec_mask;
6517 b_nvram = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
6518
6519 if (lec != (b_nvram & ec_mask)) {
6520
6521 b_nvram &= ~ec_mask;
6522 b_nvram |= lec;
6523 nvram_write_byte(b_nvram, TP_NVRAM_ADDR_MIXER);
6524 dbg_printk(TPACPI_DBG_MIXER,
6525 "updated NVRAM mixer status to 0x%02x (0x%02x)\n",
6526 (unsigned int) lec, (unsigned int) b_nvram);
6527 } else {
6528 vdbg_printk(TPACPI_DBG_MIXER,
6529 "NVRAM mixer status already is 0x%02x (0x%02x)\n",
6530 (unsigned int) lec, (unsigned int) b_nvram);
6531 }
6532
6533unlock:
6534 mutex_unlock(&volume_mutex);
6535}
6536
6537static int volume_get_status_ec(u8 *status)
6538{
6539 u8 s;
6540
6541 if (!acpi_ec_read(TP_EC_AUDIO, &s))
6542 return -EIO;
6543
6544 *status = s;
6545
6546 dbg_printk(TPACPI_DBG_MIXER, "status 0x%02x\n", s);
6547
6548 return 0;
6549}
6550
6551static int volume_get_status(u8 *status)
6552{
6553 return volume_get_status_ec(status);
6554}
6555
6556static int volume_set_status_ec(const u8 status)
6557{
6558 if (!acpi_ec_write(TP_EC_AUDIO, status))
6559 return -EIO;
6560
6561 dbg_printk(TPACPI_DBG_MIXER, "set EC mixer to 0x%02x\n", status);
6562
6563 return 0;
6564}
6565
6566static int volume_set_status(const u8 status)
6567{
6568 return volume_set_status_ec(status);
6569}
6570
6571
6572static int __volume_set_mute_ec(const bool mute)
6573{
6574 int rc;
6575 u8 s, n;
6576
6577 if (mutex_lock_killable(&volume_mutex) < 0)
6578 return -EINTR;
6579
6580 rc = volume_get_status_ec(&s);
6581 if (rc)
6582 goto unlock;
6583
6584 n = (mute) ? s | TP_EC_AUDIO_MUTESW_MSK :
6585 s & ~TP_EC_AUDIO_MUTESW_MSK;
6586
6587 if (n != s) {
6588 rc = volume_set_status_ec(n);
6589 if (!rc)
6590 rc = 1;
6591 }
6592
6593unlock:
6594 mutex_unlock(&volume_mutex);
6595 return rc;
6596}
6597
6598static int volume_alsa_set_mute(const bool mute)
6599{
6600 dbg_printk(TPACPI_DBG_MIXER, "ALSA: trying to %smute\n",
6601 (mute) ? "" : "un");
6602 return __volume_set_mute_ec(mute);
6603}
6604
6605static int volume_set_mute(const bool mute)
6606{
6607 int rc;
6608
6609 dbg_printk(TPACPI_DBG_MIXER, "trying to %smute\n",
6610 (mute) ? "" : "un");
6611
6612 rc = __volume_set_mute_ec(mute);
6613 return (rc < 0) ? rc : 0;
6614}
6615
6616
6617static int __volume_set_volume_ec(const u8 vol)
6618{
6619 int rc;
6620 u8 s, n;
6621
6622 if (vol > TP_EC_VOLUME_MAX)
6623 return -EINVAL;
6624
6625 if (mutex_lock_killable(&volume_mutex) < 0)
6626 return -EINTR;
6627
6628 rc = volume_get_status_ec(&s);
6629 if (rc)
6630 goto unlock;
6631
6632 n = (s & ~TP_EC_AUDIO_LVL_MSK) | vol;
6633
6634 if (n != s) {
6635 rc = volume_set_status_ec(n);
6636 if (!rc)
6637 rc = 1;
6638 }
6639
6640unlock:
6641 mutex_unlock(&volume_mutex);
6642 return rc;
6643}
6644
6645static int volume_alsa_set_volume(const u8 vol)
6646{
6647 dbg_printk(TPACPI_DBG_MIXER,
6648 "ALSA: trying to set volume level to %hu\n", vol);
6649 return __volume_set_volume_ec(vol);
6650}
6651
6652static void volume_alsa_notify_change(void)
6653{
6654 struct tpacpi_alsa_data *d;
6655
6656 if (alsa_card && alsa_card->private_data) {
6657 d = alsa_card->private_data;
6658 if (d->ctl_mute_id)
6659 snd_ctl_notify(alsa_card,
6660 SNDRV_CTL_EVENT_MASK_VALUE,
6661 d->ctl_mute_id);
6662 if (d->ctl_vol_id)
6663 snd_ctl_notify(alsa_card,
6664 SNDRV_CTL_EVENT_MASK_VALUE,
6665 d->ctl_vol_id);
6666 }
6667}
6668
6669static int volume_alsa_vol_info(struct snd_kcontrol *kcontrol,
6670 struct snd_ctl_elem_info *uinfo)
6671{
6672 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
6673 uinfo->count = 1;
6674 uinfo->value.integer.min = 0;
6675 uinfo->value.integer.max = TP_EC_VOLUME_MAX;
6676 return 0;
6677}
6678
6679static int volume_alsa_vol_get(struct snd_kcontrol *kcontrol,
6680 struct snd_ctl_elem_value *ucontrol)
6681{
6682 u8 s;
6683 int rc;
6684
6685 rc = volume_get_status(&s);
6686 if (rc < 0)
6687 return rc;
6688
6689 ucontrol->value.integer.value[0] = s & TP_EC_AUDIO_LVL_MSK;
6690 return 0;
6691}
6692
6693static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol,
6694 struct snd_ctl_elem_value *ucontrol)
6695{
6696 tpacpi_disclose_usertask("ALSA", "set volume to %ld\n",
6697 ucontrol->value.integer.value[0]);
6698 return volume_alsa_set_volume(ucontrol->value.integer.value[0]);
6699}
6700
6701#define volume_alsa_mute_info snd_ctl_boolean_mono_info
6702
6703static int volume_alsa_mute_get(struct snd_kcontrol *kcontrol,
6704 struct snd_ctl_elem_value *ucontrol)
6705{
6706 u8 s;
6707 int rc;
6708
6709 rc = volume_get_status(&s);
6710 if (rc < 0)
6711 return rc;
6712
6713 ucontrol->value.integer.value[0] =
6714 (s & TP_EC_AUDIO_MUTESW_MSK) ? 0 : 1;
6715 return 0;
6716}
6717
6718static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol,
6719 struct snd_ctl_elem_value *ucontrol)
6720{
6721 tpacpi_disclose_usertask("ALSA", "%smute\n",
6722 ucontrol->value.integer.value[0] ?
6723 "un" : "");
6724 return volume_alsa_set_mute(!ucontrol->value.integer.value[0]);
6725}
6726
6727static struct snd_kcontrol_new volume_alsa_control_vol __devinitdata = {
6728 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6729 .name = "Console Playback Volume",
6730 .index = 0,
6731 .access = SNDRV_CTL_ELEM_ACCESS_READ,
6732 .info = volume_alsa_vol_info,
6733 .get = volume_alsa_vol_get,
6734};
6735
6736static struct snd_kcontrol_new volume_alsa_control_mute __devinitdata = {
6737 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6738 .name = "Console Playback Switch",
6739 .index = 0,
6740 .access = SNDRV_CTL_ELEM_ACCESS_READ,
6741 .info = volume_alsa_mute_info,
6742 .get = volume_alsa_mute_get,
6743};
6744
6745static void volume_suspend(pm_message_t state)
6746{
6747 tpacpi_volume_checkpoint_nvram();
6748}
6749
6750static void volume_resume(void)
6751{
6752 volume_alsa_notify_change();
6753}
6754
6755static void volume_shutdown(void)
6756{
6757 tpacpi_volume_checkpoint_nvram();
6758}
6759
6760static void volume_exit(void)
6761{
6762 if (alsa_card) {
6763 snd_card_free(alsa_card);
6764 alsa_card = NULL;
6765 }
6766
6767 tpacpi_volume_checkpoint_nvram();
6768}
6769
6770static int __init volume_create_alsa_mixer(void)
6771{
6772 struct snd_card *card;
6773 struct tpacpi_alsa_data *data;
6774 struct snd_kcontrol *ctl_vol;
6775 struct snd_kcontrol *ctl_mute;
6776 int rc;
6777
6778 rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE,
6779 sizeof(struct tpacpi_alsa_data), &card);
6780 if (rc < 0 || !card) {
6781 pr_err("Failed to create ALSA card structures: %d\n", rc);
6782 return 1;
6783 }
6784
6785 BUG_ON(!card->private_data);
6786 data = card->private_data;
6787 data->card = card;
6788
6789 strlcpy(card->driver, TPACPI_ALSA_DRVNAME,
6790 sizeof(card->driver));
6791 strlcpy(card->shortname, TPACPI_ALSA_SHRTNAME,
6792 sizeof(card->shortname));
6793 snprintf(card->mixername, sizeof(card->mixername), "ThinkPad EC %s",
6794 (thinkpad_id.ec_version_str) ?
6795 thinkpad_id.ec_version_str : "(unknown)");
6796 snprintf(card->longname, sizeof(card->longname),
6797 "%s at EC reg 0x%02x, fw %s", card->shortname, TP_EC_AUDIO,
6798 (thinkpad_id.ec_version_str) ?
6799 thinkpad_id.ec_version_str : "unknown");
6800
6801 if (volume_control_allowed) {
6802 volume_alsa_control_vol.put = volume_alsa_vol_put;
6803 volume_alsa_control_vol.access =
6804 SNDRV_CTL_ELEM_ACCESS_READWRITE;
6805
6806 volume_alsa_control_mute.put = volume_alsa_mute_put;
6807 volume_alsa_control_mute.access =
6808 SNDRV_CTL_ELEM_ACCESS_READWRITE;
6809 }
6810
6811 if (!tp_features.mixer_no_level_control) {
6812 ctl_vol = snd_ctl_new1(&volume_alsa_control_vol, NULL);
6813 rc = snd_ctl_add(card, ctl_vol);
6814 if (rc < 0) {
6815 pr_err("Failed to create ALSA volume control: %d\n",
6816 rc);
6817 goto err_exit;
6818 }
6819 data->ctl_vol_id = &ctl_vol->id;
6820 }
6821
6822 ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL);
6823 rc = snd_ctl_add(card, ctl_mute);
6824 if (rc < 0) {
6825 pr_err("Failed to create ALSA mute control: %d\n", rc);
6826 goto err_exit;
6827 }
6828 data->ctl_mute_id = &ctl_mute->id;
6829
6830 snd_card_set_dev(card, &tpacpi_pdev->dev);
6831 rc = snd_card_register(card);
6832 if (rc < 0) {
6833 pr_err("Failed to register ALSA card: %d\n", rc);
6834 goto err_exit;
6835 }
6836
6837 alsa_card = card;
6838 return 0;
6839
6840err_exit:
6841 snd_card_free(card);
6842 return 1;
6843}
6844
6845#define TPACPI_VOL_Q_MUTEONLY 0x0001
6846#define TPACPI_VOL_Q_LEVEL 0x0002
6847
6848static const struct tpacpi_quirk volume_quirk_table[] __initconst = {
6849
6850 { .vendor = PCI_VENDOR_ID_IBM,
6851 .bios = TPACPI_MATCH_ANY,
6852 .ec = TPACPI_MATCH_ANY,
6853 .quirks = TPACPI_VOL_Q_LEVEL },
6854
6855
6856 TPACPI_QEC_LNV('7', 'C', TPACPI_VOL_Q_LEVEL),
6857 TPACPI_QEC_LNV('7', 'E', TPACPI_VOL_Q_LEVEL),
6858 TPACPI_QEC_LNV('7', '9', TPACPI_VOL_Q_LEVEL),
6859 TPACPI_QEC_LNV('7', 'B', TPACPI_VOL_Q_LEVEL),
6860 TPACPI_QEC_LNV('7', 'J', TPACPI_VOL_Q_LEVEL),
6861 TPACPI_QEC_LNV('7', '7', TPACPI_VOL_Q_LEVEL),
6862 TPACPI_QEC_LNV('7', 'F', TPACPI_VOL_Q_LEVEL),
6863
6864
6865 { .vendor = PCI_VENDOR_ID_LENOVO,
6866 .bios = TPACPI_MATCH_ANY,
6867 .ec = TPACPI_MATCH_ANY,
6868 .quirks = TPACPI_VOL_Q_MUTEONLY }
6869};
6870
6871static int __init volume_init(struct ibm_init_struct *iibm)
6872{
6873 unsigned long quirks;
6874 int rc;
6875
6876 vdbg_printk(TPACPI_DBG_INIT, "initializing volume subdriver\n");
6877
6878 mutex_init(&volume_mutex);
6879
6880
6881
6882
6883
6884
6885 if (volume_mode > TPACPI_VOL_MODE_MAX)
6886 return -EINVAL;
6887
6888 if (volume_mode == TPACPI_VOL_MODE_UCMS_STEP) {
6889 pr_err("UCMS step volume mode not implemented, "
6890 "please contact %s\n", TPACPI_MAIL);
6891 return 1;
6892 }
6893
6894 if (volume_capabilities >= TPACPI_VOL_CAP_MAX)
6895 return -EINVAL;
6896
6897
6898
6899
6900
6901 if (!alsa_enable) {
6902 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6903 "ALSA mixer disabled by parameter, "
6904 "not loading volume subdriver...\n");
6905 return 1;
6906 }
6907
6908 quirks = tpacpi_check_quirks(volume_quirk_table,
6909 ARRAY_SIZE(volume_quirk_table));
6910
6911 switch (volume_capabilities) {
6912 case TPACPI_VOL_CAP_AUTO:
6913 if (quirks & TPACPI_VOL_Q_MUTEONLY)
6914 tp_features.mixer_no_level_control = 1;
6915 else if (quirks & TPACPI_VOL_Q_LEVEL)
6916 tp_features.mixer_no_level_control = 0;
6917 else
6918 return 1;
6919 break;
6920 case TPACPI_VOL_CAP_VOLMUTE:
6921 tp_features.mixer_no_level_control = 0;
6922 break;
6923 case TPACPI_VOL_CAP_MUTEONLY:
6924 tp_features.mixer_no_level_control = 1;
6925 break;
6926 default:
6927 return 1;
6928 }
6929
6930 if (volume_capabilities != TPACPI_VOL_CAP_AUTO)
6931 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6932 "using user-supplied volume_capabilities=%d\n",
6933 volume_capabilities);
6934
6935 if (volume_mode == TPACPI_VOL_MODE_AUTO ||
6936 volume_mode == TPACPI_VOL_MODE_MAX) {
6937 volume_mode = TPACPI_VOL_MODE_ECNVRAM;
6938
6939 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6940 "driver auto-selected volume_mode=%d\n",
6941 volume_mode);
6942 } else {
6943 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6944 "using user-supplied volume_mode=%d\n",
6945 volume_mode);
6946 }
6947
6948 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6949 "mute is supported, volume control is %s\n",
6950 str_supported(!tp_features.mixer_no_level_control));
6951
6952 rc = volume_create_alsa_mixer();
6953 if (rc) {
6954 pr_err("Could not create the ALSA mixer interface\n");
6955 return rc;
6956 }
6957
6958 pr_info("Console audio control enabled, mode: %s\n",
6959 (volume_control_allowed) ?
6960 "override (read/write)" :
6961 "monitor (read only)");
6962
6963 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_MIXER,
6964 "registering volume hotkeys as change notification\n");
6965 tpacpi_hotkey_driver_mask_set(hotkey_driver_mask
6966 | TP_ACPI_HKEY_VOLUP_MASK
6967 | TP_ACPI_HKEY_VOLDWN_MASK
6968 | TP_ACPI_HKEY_MUTE_MASK);
6969
6970 return 0;
6971}
6972
6973static int volume_read(struct seq_file *m)
6974{
6975 u8 status;
6976
6977 if (volume_get_status(&status) < 0) {
6978 seq_printf(m, "level:\t\tunreadable\n");
6979 } else {
6980 if (tp_features.mixer_no_level_control)
6981 seq_printf(m, "level:\t\tunsupported\n");
6982 else
6983 seq_printf(m, "level:\t\t%d\n",
6984 status & TP_EC_AUDIO_LVL_MSK);
6985
6986 seq_printf(m, "mute:\t\t%s\n",
6987 onoff(status, TP_EC_AUDIO_MUTESW));
6988
6989 if (volume_control_allowed) {
6990 seq_printf(m, "commands:\tunmute, mute\n");
6991 if (!tp_features.mixer_no_level_control) {
6992 seq_printf(m,
6993 "commands:\tup, down\n");
6994 seq_printf(m,
6995 "commands:\tlevel <level>"
6996 " (<level> is 0-%d)\n",
6997 TP_EC_VOLUME_MAX);
6998 }
6999 }
7000 }
7001
7002 return 0;
7003}
7004
7005static int volume_write(char *buf)
7006{
7007 u8 s;
7008 u8 new_level, new_mute;
7009 int l;
7010 char *cmd;
7011 int rc;
7012
7013
7014
7015
7016
7017 if (!volume_control_allowed && tpacpi_lifecycle != TPACPI_LIFE_INIT) {
7018 if (unlikely(!tp_warned.volume_ctrl_forbidden)) {
7019 tp_warned.volume_ctrl_forbidden = 1;
7020 pr_notice("Console audio control in monitor mode, "
7021 "changes are not allowed\n");
7022 pr_notice("Use the volume_control=1 module parameter "
7023 "to enable volume control\n");
7024 }
7025 return -EPERM;
7026 }
7027
7028 rc = volume_get_status(&s);
7029 if (rc < 0)
7030 return rc;
7031
7032 new_level = s & TP_EC_AUDIO_LVL_MSK;
7033 new_mute = s & TP_EC_AUDIO_MUTESW_MSK;
7034
7035 while ((cmd = next_cmd(&buf))) {
7036 if (!tp_features.mixer_no_level_control) {
7037 if (strlencmp(cmd, "up") == 0) {
7038 if (new_mute)
7039 new_mute = 0;
7040 else if (new_level < TP_EC_VOLUME_MAX)
7041 new_level++;
7042 continue;
7043 } else if (strlencmp(cmd, "down") == 0) {
7044 if (new_mute)
7045 new_mute = 0;
7046 else if (new_level > 0)
7047 new_level--;
7048 continue;
7049 } else if (sscanf(cmd, "level %u", &l) == 1 &&
7050 l >= 0 && l <= TP_EC_VOLUME_MAX) {
7051 new_level = l;
7052 continue;
7053 }
7054 }
7055 if (strlencmp(cmd, "mute") == 0)
7056 new_mute = TP_EC_AUDIO_MUTESW_MSK;
7057 else if (strlencmp(cmd, "unmute") == 0)
7058 new_mute = 0;
7059 else
7060 return -EINVAL;
7061 }
7062
7063 if (tp_features.mixer_no_level_control) {
7064 tpacpi_disclose_usertask("procfs volume", "%smute\n",
7065 new_mute ? "" : "un");
7066 rc = volume_set_mute(!!new_mute);
7067 } else {
7068 tpacpi_disclose_usertask("procfs volume",
7069 "%smute and set level to %d\n",
7070 new_mute ? "" : "un", new_level);
7071 rc = volume_set_status(new_mute | new_level);
7072 }
7073 volume_alsa_notify_change();
7074
7075 return (rc == -EINTR) ? -ERESTARTSYS : rc;
7076}
7077
7078static struct ibm_struct volume_driver_data = {
7079 .name = "volume",
7080 .read = volume_read,
7081 .write = volume_write,
7082 .exit = volume_exit,
7083 .suspend = volume_suspend,
7084 .resume = volume_resume,
7085 .shutdown = volume_shutdown,
7086};
7087
7088#else
7089
7090#define alsa_card NULL
7091
7092static void inline volume_alsa_notify_change(void)
7093{
7094}
7095
7096static int __init volume_init(struct ibm_init_struct *iibm)
7097{
7098 pr_info("volume: disabled as there is no ALSA support in this kernel\n");
7099
7100 return 1;
7101}
7102
7103static struct ibm_struct volume_driver_data = {
7104 .name = "volume",
7105};
7106
7107#endif
7108
7109
7110
7111
7112
7113
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
7229enum {
7230 fan_status_offset = 0x2f,
7231 fan_rpm_offset = 0x84,
7232
7233 fan_select_offset = 0x31,
7234
7235
7236 TP_EC_FAN_FULLSPEED = 0x40,
7237 TP_EC_FAN_AUTO = 0x80,
7238
7239 TPACPI_FAN_LAST_LEVEL = 0x100,
7240};
7241
7242enum fan_status_access_mode {
7243 TPACPI_FAN_NONE = 0,
7244 TPACPI_FAN_RD_ACPI_GFAN,
7245 TPACPI_FAN_RD_TPEC,
7246};
7247
7248enum fan_control_access_mode {
7249 TPACPI_FAN_WR_NONE = 0,
7250 TPACPI_FAN_WR_ACPI_SFAN,
7251 TPACPI_FAN_WR_TPEC,
7252 TPACPI_FAN_WR_ACPI_FANS,
7253};
7254
7255enum fan_control_commands {
7256 TPACPI_FAN_CMD_SPEED = 0x0001,
7257 TPACPI_FAN_CMD_LEVEL = 0x0002,
7258 TPACPI_FAN_CMD_ENABLE = 0x0004,
7259
7260};
7261
7262static int fan_control_allowed;
7263
7264static enum fan_status_access_mode fan_status_access_mode;
7265static enum fan_control_access_mode fan_control_access_mode;
7266static enum fan_control_commands fan_control_commands;
7267
7268static u8 fan_control_initial_status;
7269static u8 fan_control_desired_level;
7270static u8 fan_control_resume_level;
7271static int fan_watchdog_maxinterval;
7272
7273static struct mutex fan_mutex;
7274
7275static void fan_watchdog_fire(struct work_struct *ignored);
7276static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire);
7277
7278TPACPI_HANDLE(fans, ec, "FANS");
7279TPACPI_HANDLE(gfan, ec, "GFAN",
7280 "\\FSPD",
7281 );
7282TPACPI_HANDLE(sfan, ec, "SFAN",
7283 "JFNS",
7284 );
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302static void fan_quirk1_setup(void)
7303{
7304 if (fan_control_initial_status == 0x07) {
7305 pr_notice("fan_init: initial fan status is unknown, "
7306 "assuming it is in auto mode\n");
7307 tp_features.fan_ctrl_status_undef = 1;
7308 }
7309}
7310
7311static void fan_quirk1_handle(u8 *fan_status)
7312{
7313 if (unlikely(tp_features.fan_ctrl_status_undef)) {
7314 if (*fan_status != fan_control_initial_status) {
7315
7316
7317
7318 tp_features.fan_ctrl_status_undef = 0;
7319 } else {
7320
7321
7322 *fan_status = TP_EC_FAN_AUTO;
7323 }
7324 }
7325}
7326
7327
7328static bool fan_select_fan1(void)
7329{
7330 if (tp_features.second_fan) {
7331 u8 val;
7332
7333 if (ec_read(fan_select_offset, &val) < 0)
7334 return false;
7335 val &= 0xFEU;
7336 if (ec_write(fan_select_offset, val) < 0)
7337 return false;
7338 }
7339 return true;
7340}
7341
7342
7343static bool fan_select_fan2(void)
7344{
7345 u8 val;
7346
7347 if (!tp_features.second_fan)
7348 return false;
7349
7350 if (ec_read(fan_select_offset, &val) < 0)
7351 return false;
7352 val |= 0x01U;
7353 if (ec_write(fan_select_offset, val) < 0)
7354 return false;
7355
7356 return true;
7357}
7358
7359
7360
7361
7362static void fan_update_desired_level(u8 status)
7363{
7364 if ((status &
7365 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
7366 if (status > 7)
7367 fan_control_desired_level = 7;
7368 else
7369 fan_control_desired_level = status;
7370 }
7371}
7372
7373static int fan_get_status(u8 *status)
7374{
7375 u8 s;
7376
7377
7378
7379
7380 switch (fan_status_access_mode) {
7381 case TPACPI_FAN_RD_ACPI_GFAN:
7382
7383
7384 if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d")))
7385 return -EIO;
7386
7387 if (likely(status))
7388 *status = s & 0x07;
7389
7390 break;
7391
7392 case TPACPI_FAN_RD_TPEC:
7393
7394 if (unlikely(!acpi_ec_read(fan_status_offset, &s)))
7395 return -EIO;
7396
7397 if (likely(status)) {
7398 *status = s;
7399 fan_quirk1_handle(status);
7400 }
7401
7402 break;
7403
7404 default:
7405 return -ENXIO;
7406 }
7407
7408 return 0;
7409}
7410
7411static int fan_get_status_safe(u8 *status)
7412{
7413 int rc;
7414 u8 s;
7415
7416 if (mutex_lock_killable(&fan_mutex))
7417 return -ERESTARTSYS;
7418 rc = fan_get_status(&s);
7419 if (!rc)
7420 fan_update_desired_level(s);
7421 mutex_unlock(&fan_mutex);
7422
7423 if (status)
7424 *status = s;
7425
7426 return rc;
7427}
7428
7429static int fan_get_speed(unsigned int *speed)
7430{
7431 u8 hi, lo;
7432
7433 switch (fan_status_access_mode) {
7434 case TPACPI_FAN_RD_TPEC:
7435
7436 if (unlikely(!fan_select_fan1()))
7437 return -EIO;
7438 if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) ||
7439 !acpi_ec_read(fan_rpm_offset + 1, &hi)))
7440 return -EIO;
7441
7442 if (likely(speed))
7443 *speed = (hi << 8) | lo;
7444
7445 break;
7446
7447 default:
7448 return -ENXIO;
7449 }
7450
7451 return 0;
7452}
7453
7454static int fan2_get_speed(unsigned int *speed)
7455{
7456 u8 hi, lo;
7457 bool rc;
7458
7459 switch (fan_status_access_mode) {
7460 case TPACPI_FAN_RD_TPEC:
7461
7462 if (unlikely(!fan_select_fan2()))
7463 return -EIO;
7464 rc = !acpi_ec_read(fan_rpm_offset, &lo) ||
7465 !acpi_ec_read(fan_rpm_offset + 1, &hi);
7466 fan_select_fan1();
7467 if (rc)
7468 return -EIO;
7469
7470 if (likely(speed))
7471 *speed = (hi << 8) | lo;
7472
7473 break;
7474
7475 default:
7476 return -ENXIO;
7477 }
7478
7479 return 0;
7480}
7481
7482static int fan_set_level(int level)
7483{
7484 if (!fan_control_allowed)
7485 return -EPERM;
7486
7487 switch (fan_control_access_mode) {
7488 case TPACPI_FAN_WR_ACPI_SFAN:
7489 if (level >= 0 && level <= 7) {
7490 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
7491 return -EIO;
7492 } else
7493 return -EINVAL;
7494 break;
7495
7496 case TPACPI_FAN_WR_ACPI_FANS:
7497 case TPACPI_FAN_WR_TPEC:
7498 if (!(level & TP_EC_FAN_AUTO) &&
7499 !(level & TP_EC_FAN_FULLSPEED) &&
7500 ((level < 0) || (level > 7)))
7501 return -EINVAL;
7502
7503
7504
7505 if (level & TP_EC_FAN_FULLSPEED)
7506 level |= 7;
7507 else if (level & TP_EC_FAN_AUTO)
7508 level |= 4;
7509
7510 if (!acpi_ec_write(fan_status_offset, level))
7511 return -EIO;
7512 else
7513 tp_features.fan_ctrl_status_undef = 0;
7514 break;
7515
7516 default:
7517 return -ENXIO;
7518 }
7519
7520 vdbg_printk(TPACPI_DBG_FAN,
7521 "fan control: set fan control register to 0x%02x\n", level);
7522 return 0;
7523}
7524
7525static int fan_set_level_safe(int level)
7526{
7527 int rc;
7528
7529 if (!fan_control_allowed)
7530 return -EPERM;
7531
7532 if (mutex_lock_killable(&fan_mutex))
7533 return -ERESTARTSYS;
7534
7535 if (level == TPACPI_FAN_LAST_LEVEL)
7536 level = fan_control_desired_level;
7537
7538 rc = fan_set_level(level);
7539 if (!rc)
7540 fan_update_desired_level(level);
7541
7542 mutex_unlock(&fan_mutex);
7543 return rc;
7544}
7545
7546static int fan_set_enable(void)
7547{
7548 u8 s;
7549 int rc;
7550
7551 if (!fan_control_allowed)
7552 return -EPERM;
7553
7554 if (mutex_lock_killable(&fan_mutex))
7555 return -ERESTARTSYS;
7556
7557 switch (fan_control_access_mode) {
7558 case TPACPI_FAN_WR_ACPI_FANS:
7559 case TPACPI_FAN_WR_TPEC:
7560 rc = fan_get_status(&s);
7561 if (rc < 0)
7562 break;
7563
7564
7565 if (s != 7) {
7566 s &= 0x07;
7567 s |= TP_EC_FAN_AUTO | 4;
7568 }
7569
7570 if (!acpi_ec_write(fan_status_offset, s))
7571 rc = -EIO;
7572 else {
7573 tp_features.fan_ctrl_status_undef = 0;
7574 rc = 0;
7575 }
7576 break;
7577
7578 case TPACPI_FAN_WR_ACPI_SFAN:
7579 rc = fan_get_status(&s);
7580 if (rc < 0)
7581 break;
7582
7583 s &= 0x07;
7584
7585
7586 s |= 4;
7587
7588 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s))
7589 rc = -EIO;
7590 else
7591 rc = 0;
7592 break;
7593
7594 default:
7595 rc = -ENXIO;
7596 }
7597
7598 mutex_unlock(&fan_mutex);
7599
7600 if (!rc)
7601 vdbg_printk(TPACPI_DBG_FAN,
7602 "fan control: set fan control register to 0x%02x\n",
7603 s);
7604 return rc;
7605}
7606
7607static int fan_set_disable(void)
7608{
7609 int rc;
7610
7611 if (!fan_control_allowed)
7612 return -EPERM;
7613
7614 if (mutex_lock_killable(&fan_mutex))
7615 return -ERESTARTSYS;
7616
7617 rc = 0;
7618 switch (fan_control_access_mode) {
7619 case TPACPI_FAN_WR_ACPI_FANS:
7620 case TPACPI_FAN_WR_TPEC:
7621 if (!acpi_ec_write(fan_status_offset, 0x00))
7622 rc = -EIO;
7623 else {
7624 fan_control_desired_level = 0;
7625 tp_features.fan_ctrl_status_undef = 0;
7626 }
7627 break;
7628
7629 case TPACPI_FAN_WR_ACPI_SFAN:
7630 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))
7631 rc = -EIO;
7632 else
7633 fan_control_desired_level = 0;
7634 break;
7635
7636 default:
7637 rc = -ENXIO;
7638 }
7639
7640 if (!rc)
7641 vdbg_printk(TPACPI_DBG_FAN,
7642 "fan control: set fan control register to 0\n");
7643
7644 mutex_unlock(&fan_mutex);
7645 return rc;
7646}
7647
7648static int fan_set_speed(int speed)
7649{
7650 int rc;
7651
7652 if (!fan_control_allowed)
7653 return -EPERM;
7654
7655 if (mutex_lock_killable(&fan_mutex))
7656 return -ERESTARTSYS;
7657
7658 rc = 0;
7659 switch (fan_control_access_mode) {
7660 case TPACPI_FAN_WR_ACPI_FANS:
7661 if (speed >= 0 && speed <= 65535) {
7662 if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
7663 speed, speed, speed))
7664 rc = -EIO;
7665 } else
7666 rc = -EINVAL;
7667 break;
7668
7669 default:
7670 rc = -ENXIO;
7671 }
7672
7673 mutex_unlock(&fan_mutex);
7674 return rc;
7675}
7676
7677static void fan_watchdog_reset(void)
7678{
7679 static int fan_watchdog_active;
7680
7681 if (fan_control_access_mode == TPACPI_FAN_WR_NONE)
7682 return;
7683
7684 if (fan_watchdog_active)
7685 cancel_delayed_work(&fan_watchdog_task);
7686
7687 if (fan_watchdog_maxinterval > 0 &&
7688 tpacpi_lifecycle != TPACPI_LIFE_EXITING) {
7689 fan_watchdog_active = 1;
7690 if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task,
7691 msecs_to_jiffies(fan_watchdog_maxinterval
7692 * 1000))) {
7693 pr_err("failed to queue the fan watchdog, "
7694 "watchdog will not trigger\n");
7695 }
7696 } else
7697 fan_watchdog_active = 0;
7698}
7699
7700static void fan_watchdog_fire(struct work_struct *ignored)
7701{
7702 int rc;
7703
7704 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
7705 return;
7706
7707 pr_notice("fan watchdog: enabling fan\n");
7708 rc = fan_set_enable();
7709 if (rc < 0) {
7710 pr_err("fan watchdog: error %d while enabling fan, "
7711 "will try again later...\n", -rc);
7712
7713 fan_watchdog_reset();
7714 }
7715}
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739static ssize_t fan_pwm1_enable_show(struct device *dev,
7740 struct device_attribute *attr,
7741 char *buf)
7742{
7743 int res, mode;
7744 u8 status;
7745
7746 res = fan_get_status_safe(&status);
7747 if (res)
7748 return res;
7749
7750 if (status & TP_EC_FAN_FULLSPEED) {
7751 mode = 0;
7752 } else if (status & TP_EC_FAN_AUTO) {
7753 mode = 2;
7754 } else
7755 mode = 1;
7756
7757 return snprintf(buf, PAGE_SIZE, "%d\n", mode);
7758}
7759
7760static ssize_t fan_pwm1_enable_store(struct device *dev,
7761 struct device_attribute *attr,
7762 const char *buf, size_t count)
7763{
7764 unsigned long t;
7765 int res, level;
7766
7767 if (parse_strtoul(buf, 2, &t))
7768 return -EINVAL;
7769
7770 tpacpi_disclose_usertask("hwmon pwm1_enable",
7771 "set fan mode to %lu\n", t);
7772
7773 switch (t) {
7774 case 0:
7775 level = TP_EC_FAN_FULLSPEED;
7776 break;
7777 case 1:
7778 level = TPACPI_FAN_LAST_LEVEL;
7779 break;
7780 case 2:
7781 level = TP_EC_FAN_AUTO;
7782 break;
7783 case 3:
7784
7785 return -ENOSYS;
7786 default:
7787 return -EINVAL;
7788 }
7789
7790 res = fan_set_level_safe(level);
7791 if (res == -ENXIO)
7792 return -EINVAL;
7793 else if (res < 0)
7794 return res;
7795
7796 fan_watchdog_reset();
7797
7798 return count;
7799}
7800
7801static struct device_attribute dev_attr_fan_pwm1_enable =
7802 __ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
7803 fan_pwm1_enable_show, fan_pwm1_enable_store);
7804
7805
7806static ssize_t fan_pwm1_show(struct device *dev,
7807 struct device_attribute *attr,
7808 char *buf)
7809{
7810 int res;
7811 u8 status;
7812
7813 res = fan_get_status_safe(&status);
7814 if (res)
7815 return res;
7816
7817 if ((status &
7818 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0)
7819 status = fan_control_desired_level;
7820
7821 if (status > 7)
7822 status = 7;
7823
7824 return snprintf(buf, PAGE_SIZE, "%u\n", (status * 255) / 7);
7825}
7826
7827static ssize_t fan_pwm1_store(struct device *dev,
7828 struct device_attribute *attr,
7829 const char *buf, size_t count)
7830{
7831 unsigned long s;
7832 int rc;
7833 u8 status, newlevel;
7834
7835 if (parse_strtoul(buf, 255, &s))
7836 return -EINVAL;
7837
7838 tpacpi_disclose_usertask("hwmon pwm1",
7839 "set fan speed to %lu\n", s);
7840
7841
7842 newlevel = (s >> 5) & 0x07;
7843
7844 if (mutex_lock_killable(&fan_mutex))
7845 return -ERESTARTSYS;
7846
7847 rc = fan_get_status(&status);
7848 if (!rc && (status &
7849 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
7850 rc = fan_set_level(newlevel);
7851 if (rc == -ENXIO)
7852 rc = -EINVAL;
7853 else if (!rc) {
7854 fan_update_desired_level(newlevel);
7855 fan_watchdog_reset();
7856 }
7857 }
7858
7859 mutex_unlock(&fan_mutex);
7860 return (rc)? rc : count;
7861}
7862
7863static struct device_attribute dev_attr_fan_pwm1 =
7864 __ATTR(pwm1, S_IWUSR | S_IRUGO,
7865 fan_pwm1_show, fan_pwm1_store);
7866
7867
7868static ssize_t fan_fan1_input_show(struct device *dev,
7869 struct device_attribute *attr,
7870 char *buf)
7871{
7872 int res;
7873 unsigned int speed;
7874
7875 res = fan_get_speed(&speed);
7876 if (res < 0)
7877 return res;
7878
7879 return snprintf(buf, PAGE_SIZE, "%u\n", speed);
7880}
7881
7882static struct device_attribute dev_attr_fan_fan1_input =
7883 __ATTR(fan1_input, S_IRUGO,
7884 fan_fan1_input_show, NULL);
7885
7886
7887static ssize_t fan_fan2_input_show(struct device *dev,
7888 struct device_attribute *attr,
7889 char *buf)
7890{
7891 int res;
7892 unsigned int speed;
7893
7894 res = fan2_get_speed(&speed);
7895 if (res < 0)
7896 return res;
7897
7898 return snprintf(buf, PAGE_SIZE, "%u\n", speed);
7899}
7900
7901static struct device_attribute dev_attr_fan_fan2_input =
7902 __ATTR(fan2_input, S_IRUGO,
7903 fan_fan2_input_show, NULL);
7904
7905
7906static ssize_t fan_fan_watchdog_show(struct device_driver *drv,
7907 char *buf)
7908{
7909 return snprintf(buf, PAGE_SIZE, "%u\n", fan_watchdog_maxinterval);
7910}
7911
7912static ssize_t fan_fan_watchdog_store(struct device_driver *drv,
7913 const char *buf, size_t count)
7914{
7915 unsigned long t;
7916
7917 if (parse_strtoul(buf, 120, &t))
7918 return -EINVAL;
7919
7920 if (!fan_control_allowed)
7921 return -EPERM;
7922
7923 fan_watchdog_maxinterval = t;
7924 fan_watchdog_reset();
7925
7926 tpacpi_disclose_usertask("fan_watchdog", "set to %lu\n", t);
7927
7928 return count;
7929}
7930
7931static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO,
7932 fan_fan_watchdog_show, fan_fan_watchdog_store);
7933
7934
7935static struct attribute *fan_attributes[] = {
7936 &dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr,
7937 &dev_attr_fan_fan1_input.attr,
7938 NULL,
7939 NULL
7940};
7941
7942static const struct attribute_group fan_attr_group = {
7943 .attrs = fan_attributes,
7944};
7945
7946#define TPACPI_FAN_Q1 0x0001
7947#define TPACPI_FAN_2FAN 0x0002
7948
7949#define TPACPI_FAN_QI(__id1, __id2, __quirks) \
7950 { .vendor = PCI_VENDOR_ID_IBM, \
7951 .bios = TPACPI_MATCH_ANY, \
7952 .ec = TPID(__id1, __id2), \
7953 .quirks = __quirks }
7954
7955#define TPACPI_FAN_QL(__id1, __id2, __quirks) \
7956 { .vendor = PCI_VENDOR_ID_LENOVO, \
7957 .bios = TPACPI_MATCH_ANY, \
7958 .ec = TPID(__id1, __id2), \
7959 .quirks = __quirks }
7960
7961static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
7962 TPACPI_FAN_QI('1', 'Y', TPACPI_FAN_Q1),
7963 TPACPI_FAN_QI('7', '8', TPACPI_FAN_Q1),
7964 TPACPI_FAN_QI('7', '6', TPACPI_FAN_Q1),
7965 TPACPI_FAN_QI('7', '0', TPACPI_FAN_Q1),
7966 TPACPI_FAN_QL('7', 'M', TPACPI_FAN_2FAN),
7967};
7968
7969#undef TPACPI_FAN_QL
7970#undef TPACPI_FAN_QI
7971
7972static int __init fan_init(struct ibm_init_struct *iibm)
7973{
7974 int rc;
7975 unsigned long quirks;
7976
7977 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
7978 "initializing fan subdriver\n");
7979
7980 mutex_init(&fan_mutex);
7981 fan_status_access_mode = TPACPI_FAN_NONE;
7982 fan_control_access_mode = TPACPI_FAN_WR_NONE;
7983 fan_control_commands = 0;
7984 fan_watchdog_maxinterval = 0;
7985 tp_features.fan_ctrl_status_undef = 0;
7986 tp_features.second_fan = 0;
7987 fan_control_desired_level = 7;
7988
7989 if (tpacpi_is_ibm()) {
7990 TPACPI_ACPIHANDLE_INIT(fans);
7991 TPACPI_ACPIHANDLE_INIT(gfan);
7992 TPACPI_ACPIHANDLE_INIT(sfan);
7993 }
7994
7995 quirks = tpacpi_check_quirks(fan_quirk_table,
7996 ARRAY_SIZE(fan_quirk_table));
7997
7998 if (gfan_handle) {
7999
8000 fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN;
8001 } else {
8002
8003
8004 if (likely(acpi_ec_read(fan_status_offset,
8005 &fan_control_initial_status))) {
8006 fan_status_access_mode = TPACPI_FAN_RD_TPEC;
8007 if (quirks & TPACPI_FAN_Q1)
8008 fan_quirk1_setup();
8009 if (quirks & TPACPI_FAN_2FAN) {
8010 tp_features.second_fan = 1;
8011 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
8012 "secondary fan support enabled\n");
8013 }
8014 } else {
8015 pr_err("ThinkPad ACPI EC access misbehaving, "
8016 "fan status and control unavailable\n");
8017 return 1;
8018 }
8019 }
8020
8021 if (sfan_handle) {
8022
8023 fan_control_access_mode = TPACPI_FAN_WR_ACPI_SFAN;
8024 fan_control_commands |=
8025 TPACPI_FAN_CMD_LEVEL | TPACPI_FAN_CMD_ENABLE;
8026 } else {
8027 if (!gfan_handle) {
8028
8029
8030
8031 if (fans_handle) {
8032
8033 fan_control_access_mode =
8034 TPACPI_FAN_WR_ACPI_FANS;
8035 fan_control_commands |=
8036 TPACPI_FAN_CMD_SPEED |
8037 TPACPI_FAN_CMD_LEVEL |
8038 TPACPI_FAN_CMD_ENABLE;
8039 } else {
8040 fan_control_access_mode = TPACPI_FAN_WR_TPEC;
8041 fan_control_commands |=
8042 TPACPI_FAN_CMD_LEVEL |
8043 TPACPI_FAN_CMD_ENABLE;
8044 }
8045 }
8046 }
8047
8048 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
8049 "fan is %s, modes %d, %d\n",
8050 str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||
8051 fan_control_access_mode != TPACPI_FAN_WR_NONE),
8052 fan_status_access_mode, fan_control_access_mode);
8053
8054
8055 if (!fan_control_allowed) {
8056 fan_control_access_mode = TPACPI_FAN_WR_NONE;
8057 fan_control_commands = 0;
8058 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
8059 "fan control features disabled by parameter\n");
8060 }
8061
8062
8063 if (fan_status_access_mode != TPACPI_FAN_NONE)
8064 fan_get_status_safe(NULL);
8065
8066 if (fan_status_access_mode != TPACPI_FAN_NONE ||
8067 fan_control_access_mode != TPACPI_FAN_WR_NONE) {
8068 if (tp_features.second_fan) {
8069
8070 fan_attributes[ARRAY_SIZE(fan_attributes)-2] =
8071 &dev_attr_fan_fan2_input.attr;
8072 }
8073 rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
8074 &fan_attr_group);
8075 if (rc < 0)
8076 return rc;
8077
8078 rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
8079 &driver_attr_fan_watchdog);
8080 if (rc < 0) {
8081 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
8082 &fan_attr_group);
8083 return rc;
8084 }
8085 return 0;
8086 } else
8087 return 1;
8088}
8089
8090static void fan_exit(void)
8091{
8092 vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_FAN,
8093 "cancelling any pending fan watchdog tasks\n");
8094
8095
8096 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group);
8097 driver_remove_file(&tpacpi_hwmon_pdriver.driver,
8098 &driver_attr_fan_watchdog);
8099
8100 cancel_delayed_work(&fan_watchdog_task);
8101 flush_workqueue(tpacpi_wq);
8102}
8103
8104static void fan_suspend(pm_message_t state)
8105{
8106 int rc;
8107
8108 if (!fan_control_allowed)
8109 return;
8110
8111
8112 fan_control_resume_level = 0;
8113 rc = fan_get_status_safe(&fan_control_resume_level);
8114 if (rc < 0)
8115 pr_notice("failed to read fan level for later "
8116 "restore during resume: %d\n", rc);
8117
8118
8119
8120 if (tp_features.fan_ctrl_status_undef)
8121 fan_control_resume_level = 0;
8122}
8123
8124static void fan_resume(void)
8125{
8126 u8 current_level = 7;
8127 bool do_set = false;
8128 int rc;
8129
8130
8131 tp_features.fan_ctrl_status_undef = 0;
8132
8133 if (!fan_control_allowed ||
8134 !fan_control_resume_level ||
8135 (fan_get_status_safe(¤t_level) < 0))
8136 return;
8137
8138 switch (fan_control_access_mode) {
8139 case TPACPI_FAN_WR_ACPI_SFAN:
8140
8141 do_set = (fan_control_resume_level > current_level);
8142 break;
8143 case TPACPI_FAN_WR_ACPI_FANS:
8144 case TPACPI_FAN_WR_TPEC:
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160 if (fan_control_resume_level != 7 &&
8161 !(fan_control_resume_level & TP_EC_FAN_FULLSPEED))
8162 return;
8163 else
8164 do_set = !(current_level & TP_EC_FAN_FULLSPEED) &&
8165 (current_level != fan_control_resume_level);
8166 break;
8167 default:
8168 return;
8169 }
8170 if (do_set) {
8171 pr_notice("restoring fan level to 0x%02x\n",
8172 fan_control_resume_level);
8173 rc = fan_set_level_safe(fan_control_resume_level);
8174 if (rc < 0)
8175 pr_notice("failed to restore fan level: %d\n", rc);
8176 }
8177}
8178
8179static int fan_read(struct seq_file *m)
8180{
8181 int rc;
8182 u8 status;
8183 unsigned int speed = 0;
8184
8185 switch (fan_status_access_mode) {
8186 case TPACPI_FAN_RD_ACPI_GFAN:
8187
8188 rc = fan_get_status_safe(&status);
8189 if (rc < 0)
8190 return rc;
8191
8192 seq_printf(m, "status:\t\t%s\n"
8193 "level:\t\t%d\n",
8194 (status != 0) ? "enabled" : "disabled", status);
8195 break;
8196
8197 case TPACPI_FAN_RD_TPEC:
8198
8199 rc = fan_get_status_safe(&status);
8200 if (rc < 0)
8201 return rc;
8202
8203 seq_printf(m, "status:\t\t%s\n",
8204 (status != 0) ? "enabled" : "disabled");
8205
8206 rc = fan_get_speed(&speed);
8207 if (rc < 0)
8208 return rc;
8209
8210 seq_printf(m, "speed:\t\t%d\n", speed);
8211
8212 if (status & TP_EC_FAN_FULLSPEED)
8213
8214 seq_printf(m, "level:\t\tdisengaged\n");
8215 else if (status & TP_EC_FAN_AUTO)
8216 seq_printf(m, "level:\t\tauto\n");
8217 else
8218 seq_printf(m, "level:\t\t%d\n", status);
8219 break;
8220
8221 case TPACPI_FAN_NONE:
8222 default:
8223 seq_printf(m, "status:\t\tnot supported\n");
8224 }
8225
8226 if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) {
8227 seq_printf(m, "commands:\tlevel <level>");
8228
8229 switch (fan_control_access_mode) {
8230 case TPACPI_FAN_WR_ACPI_SFAN:
8231 seq_printf(m, " (<level> is 0-7)\n");
8232 break;
8233
8234 default:
8235 seq_printf(m, " (<level> is 0-7, "
8236 "auto, disengaged, full-speed)\n");
8237 break;
8238 }
8239 }
8240
8241 if (fan_control_commands & TPACPI_FAN_CMD_ENABLE)
8242 seq_printf(m, "commands:\tenable, disable\n"
8243 "commands:\twatchdog <timeout> (<timeout> "
8244 "is 0 (off), 1-120 (seconds))\n");
8245
8246 if (fan_control_commands & TPACPI_FAN_CMD_SPEED)
8247 seq_printf(m, "commands:\tspeed <speed>"
8248 " (<speed> is 0-65535)\n");
8249
8250 return 0;
8251}
8252
8253static int fan_write_cmd_level(const char *cmd, int *rc)
8254{
8255 int level;
8256
8257 if (strlencmp(cmd, "level auto") == 0)
8258 level = TP_EC_FAN_AUTO;
8259 else if ((strlencmp(cmd, "level disengaged") == 0) |
8260 (strlencmp(cmd, "level full-speed") == 0))
8261 level = TP_EC_FAN_FULLSPEED;
8262 else if (sscanf(cmd, "level %d", &level) != 1)
8263 return 0;
8264
8265 *rc = fan_set_level_safe(level);
8266 if (*rc == -ENXIO)
8267 pr_err("level command accepted for unsupported access mode %d\n",
8268 fan_control_access_mode);
8269 else if (!*rc)
8270 tpacpi_disclose_usertask("procfs fan",
8271 "set level to %d\n", level);
8272
8273 return 1;
8274}
8275
8276static int fan_write_cmd_enable(const char *cmd, int *rc)
8277{
8278 if (strlencmp(cmd, "enable") != 0)
8279 return 0;
8280
8281 *rc = fan_set_enable();
8282 if (*rc == -ENXIO)
8283 pr_err("enable command accepted for unsupported access mode %d\n",
8284 fan_control_access_mode);
8285 else if (!*rc)
8286 tpacpi_disclose_usertask("procfs fan", "enable\n");
8287
8288 return 1;
8289}
8290
8291static int fan_write_cmd_disable(const char *cmd, int *rc)
8292{
8293 if (strlencmp(cmd, "disable") != 0)
8294 return 0;
8295
8296 *rc = fan_set_disable();
8297 if (*rc == -ENXIO)
8298 pr_err("disable command accepted for unsupported access mode %d\n",
8299 fan_control_access_mode);
8300 else if (!*rc)
8301 tpacpi_disclose_usertask("procfs fan", "disable\n");
8302
8303 return 1;
8304}
8305
8306static int fan_write_cmd_speed(const char *cmd, int *rc)
8307{
8308 int speed;
8309
8310
8311
8312
8313 if (sscanf(cmd, "speed %d", &speed) != 1)
8314 return 0;
8315
8316 *rc = fan_set_speed(speed);
8317 if (*rc == -ENXIO)
8318 pr_err("speed command accepted for unsupported access mode %d\n",
8319 fan_control_access_mode);
8320 else if (!*rc)
8321 tpacpi_disclose_usertask("procfs fan",
8322 "set speed to %d\n", speed);
8323
8324 return 1;
8325}
8326
8327static int fan_write_cmd_watchdog(const char *cmd, int *rc)
8328{
8329 int interval;
8330
8331 if (sscanf(cmd, "watchdog %d", &interval) != 1)
8332 return 0;
8333
8334 if (interval < 0 || interval > 120)
8335 *rc = -EINVAL;
8336 else {
8337 fan_watchdog_maxinterval = interval;
8338 tpacpi_disclose_usertask("procfs fan",
8339 "set watchdog timer to %d\n",
8340 interval);
8341 }
8342
8343 return 1;
8344}
8345
8346static int fan_write(char *buf)
8347{
8348 char *cmd;
8349 int rc = 0;
8350
8351 while (!rc && (cmd = next_cmd(&buf))) {
8352 if (!((fan_control_commands & TPACPI_FAN_CMD_LEVEL) &&
8353 fan_write_cmd_level(cmd, &rc)) &&
8354 !((fan_control_commands & TPACPI_FAN_CMD_ENABLE) &&
8355 (fan_write_cmd_enable(cmd, &rc) ||
8356 fan_write_cmd_disable(cmd, &rc) ||
8357 fan_write_cmd_watchdog(cmd, &rc))) &&
8358 !((fan_control_commands & TPACPI_FAN_CMD_SPEED) &&
8359 fan_write_cmd_speed(cmd, &rc))
8360 )
8361 rc = -EINVAL;
8362 else if (!rc)
8363 fan_watchdog_reset();
8364 }
8365
8366 return rc;
8367}
8368
8369static struct ibm_struct fan_driver_data = {
8370 .name = "fan",
8371 .read = fan_read,
8372 .write = fan_write,
8373 .exit = fan_exit,
8374 .suspend = fan_suspend,
8375 .resume = fan_resume,
8376};
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390static void tpacpi_driver_event(const unsigned int hkey_event)
8391{
8392 if (ibm_backlight_device) {
8393 switch (hkey_event) {
8394 case TP_HKEY_EV_BRGHT_UP:
8395 case TP_HKEY_EV_BRGHT_DOWN:
8396 tpacpi_brightness_notify_change();
8397 }
8398 }
8399 if (alsa_card) {
8400 switch (hkey_event) {
8401 case TP_HKEY_EV_VOL_UP:
8402 case TP_HKEY_EV_VOL_DOWN:
8403 case TP_HKEY_EV_VOL_MUTE:
8404 volume_alsa_notify_change();
8405 }
8406 }
8407}
8408
8409static void hotkey_driver_event(const unsigned int scancode)
8410{
8411 tpacpi_driver_event(TP_HKEY_EV_HOTKEY_BASE + scancode);
8412}
8413
8414
8415static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev,
8416 struct device_attribute *attr,
8417 char *buf)
8418{
8419 return snprintf(buf, PAGE_SIZE, "%s\n", TPACPI_NAME);
8420}
8421
8422static struct device_attribute dev_attr_thinkpad_acpi_pdev_name =
8423 __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL);
8424
8425
8426
8427
8428static struct proc_dir_entry *proc_dir;
8429
8430
8431
8432
8433
8434static int force_load;
8435
8436#ifdef CONFIG_THINKPAD_ACPI_DEBUG
8437static const char * __init str_supported(int is_supported)
8438{
8439 static char text_unsupported[] __initdata = "not supported";
8440
8441 return (is_supported)? &text_unsupported[4] : &text_unsupported[0];
8442}
8443#endif
8444
8445static void ibm_exit(struct ibm_struct *ibm)
8446{
8447 dbg_printk(TPACPI_DBG_EXIT, "removing %s\n", ibm->name);
8448
8449 list_del_init(&ibm->all_drivers);
8450
8451 if (ibm->flags.acpi_notify_installed) {
8452 dbg_printk(TPACPI_DBG_EXIT,
8453 "%s: acpi_remove_notify_handler\n", ibm->name);
8454 BUG_ON(!ibm->acpi);
8455 acpi_remove_notify_handler(*ibm->acpi->handle,
8456 ibm->acpi->type,
8457 dispatch_acpi_notify);
8458 ibm->flags.acpi_notify_installed = 0;
8459 }
8460
8461 if (ibm->flags.proc_created) {
8462 dbg_printk(TPACPI_DBG_EXIT,
8463 "%s: remove_proc_entry\n", ibm->name);
8464 remove_proc_entry(ibm->name, proc_dir);
8465 ibm->flags.proc_created = 0;
8466 }
8467
8468 if (ibm->flags.acpi_driver_registered) {
8469 dbg_printk(TPACPI_DBG_EXIT,
8470 "%s: acpi_bus_unregister_driver\n", ibm->name);
8471 BUG_ON(!ibm->acpi);
8472 acpi_bus_unregister_driver(ibm->acpi->driver);
8473 kfree(ibm->acpi->driver);
8474 ibm->acpi->driver = NULL;
8475 ibm->flags.acpi_driver_registered = 0;
8476 }
8477
8478 if (ibm->flags.init_called && ibm->exit) {
8479 ibm->exit();
8480 ibm->flags.init_called = 0;
8481 }
8482
8483 dbg_printk(TPACPI_DBG_INIT, "finished removing %s\n", ibm->name);
8484}
8485
8486static int __init ibm_init(struct ibm_init_struct *iibm)
8487{
8488 int ret;
8489 struct ibm_struct *ibm = iibm->data;
8490 struct proc_dir_entry *entry;
8491
8492 BUG_ON(ibm == NULL);
8493
8494 INIT_LIST_HEAD(&ibm->all_drivers);
8495
8496 if (ibm->flags.experimental && !experimental)
8497 return 0;
8498
8499 dbg_printk(TPACPI_DBG_INIT,
8500 "probing for %s\n", ibm->name);
8501
8502 if (iibm->init) {
8503 ret = iibm->init(iibm);
8504 if (ret > 0)
8505 return 0;
8506 if (ret)
8507 return ret;
8508
8509 ibm->flags.init_called = 1;
8510 }
8511
8512 if (ibm->acpi) {
8513 if (ibm->acpi->hid) {
8514 ret = register_tpacpi_subdriver(ibm);
8515 if (ret)
8516 goto err_out;
8517 }
8518
8519 if (ibm->acpi->notify) {
8520 ret = setup_acpi_notify(ibm);
8521 if (ret == -ENODEV) {
8522 pr_notice("disabling subdriver %s\n",
8523 ibm->name);
8524 ret = 0;
8525 goto err_out;
8526 }
8527 if (ret < 0)
8528 goto err_out;
8529 }
8530 }
8531
8532 dbg_printk(TPACPI_DBG_INIT,
8533 "%s installed\n", ibm->name);
8534
8535 if (ibm->read) {
8536 mode_t mode = iibm->base_procfs_mode;
8537
8538 if (!mode)
8539 mode = S_IRUGO;
8540 if (ibm->write)
8541 mode |= S_IWUSR;
8542 entry = proc_create_data(ibm->name, mode, proc_dir,
8543 &dispatch_proc_fops, ibm);
8544 if (!entry) {
8545 pr_err("unable to create proc entry %s\n", ibm->name);
8546 ret = -ENODEV;
8547 goto err_out;
8548 }
8549 ibm->flags.proc_created = 1;
8550 }
8551
8552 list_add_tail(&ibm->all_drivers, &tpacpi_all_drivers);
8553
8554 return 0;
8555
8556err_out:
8557 dbg_printk(TPACPI_DBG_INIT,
8558 "%s: at error exit path with result %d\n",
8559 ibm->name, ret);
8560
8561 ibm_exit(ibm);
8562 return (ret < 0)? ret : 0;
8563}
8564
8565
8566
8567static bool __pure __init tpacpi_is_fw_digit(const char c)
8568{
8569 return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z');
8570}
8571
8572
8573static bool __pure __init tpacpi_is_valid_fw_id(const char* const s,
8574 const char t)
8575{
8576 return s && strlen(s) >= 8 &&
8577 tpacpi_is_fw_digit(s[0]) &&
8578 tpacpi_is_fw_digit(s[1]) &&
8579 s[2] == t && s[3] == 'T' &&
8580 tpacpi_is_fw_digit(s[4]) &&
8581 tpacpi_is_fw_digit(s[5]);
8582}
8583
8584
8585
8586
8587static int __must_check __init get_thinkpad_model_data(
8588 struct thinkpad_id_data *tp)
8589{
8590 const struct dmi_device *dev = NULL;
8591 char ec_fw_string[18];
8592 char const *s;
8593
8594 if (!tp)
8595 return -EINVAL;
8596
8597 memset(tp, 0, sizeof(*tp));
8598
8599 if (dmi_name_in_vendors("IBM"))
8600 tp->vendor = PCI_VENDOR_ID_IBM;
8601 else if (dmi_name_in_vendors("LENOVO"))
8602 tp->vendor = PCI_VENDOR_ID_LENOVO;
8603 else
8604 return 0;
8605
8606 s = dmi_get_system_info(DMI_BIOS_VERSION);
8607 tp->bios_version_str = kstrdup(s, GFP_KERNEL);
8608 if (s && !tp->bios_version_str)
8609 return -ENOMEM;
8610
8611
8612 if (!tpacpi_is_valid_fw_id(tp->bios_version_str, 'E'))
8613 return 0;
8614
8615 tp->bios_model = tp->bios_version_str[0]
8616 | (tp->bios_version_str[1] << 8);
8617 tp->bios_release = (tp->bios_version_str[4] << 8)
8618 | tp->bios_version_str[5];
8619
8620
8621
8622
8623
8624
8625
8626
8627 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
8628 if (sscanf(dev->name,
8629 "IBM ThinkPad Embedded Controller -[%17c",
8630 ec_fw_string) == 1) {
8631 ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
8632 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
8633
8634 tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL);
8635 if (!tp->ec_version_str)
8636 return -ENOMEM;
8637
8638 if (tpacpi_is_valid_fw_id(ec_fw_string, 'H')) {
8639 tp->ec_model = ec_fw_string[0]
8640 | (ec_fw_string[1] << 8);
8641 tp->ec_release = (ec_fw_string[4] << 8)
8642 | ec_fw_string[5];
8643 } else {
8644 pr_notice("ThinkPad firmware release %s "
8645 "doesn't match the known patterns\n",
8646 ec_fw_string);
8647 pr_notice("please report this to %s\n",
8648 TPACPI_MAIL);
8649 }
8650 break;
8651 }
8652 }
8653
8654 s = dmi_get_system_info(DMI_PRODUCT_VERSION);
8655 if (s && !strnicmp(s, "ThinkPad", 8)) {
8656 tp->model_str = kstrdup(s, GFP_KERNEL);
8657 if (!tp->model_str)
8658 return -ENOMEM;
8659 }
8660
8661 s = dmi_get_system_info(DMI_PRODUCT_NAME);
8662 tp->nummodel_str = kstrdup(s, GFP_KERNEL);
8663 if (s && !tp->nummodel_str)
8664 return -ENOMEM;
8665
8666 return 0;
8667}
8668
8669static int __init probe_for_thinkpad(void)
8670{
8671 int is_thinkpad;
8672
8673 if (acpi_disabled)
8674 return -ENODEV;
8675
8676
8677 if (!tpacpi_is_ibm() && !tpacpi_is_lenovo())
8678 return -ENODEV;
8679
8680
8681
8682
8683
8684 is_thinkpad = (thinkpad_id.model_str != NULL) ||
8685 (thinkpad_id.ec_model != 0) ||
8686 tpacpi_is_fw_known();
8687
8688
8689 tpacpi_acpi_handle_locate("ec", TPACPI_ACPI_EC_HID, &ec_handle);
8690 if (!ec_handle) {
8691 if (is_thinkpad)
8692 pr_err("Not yet supported ThinkPad detected!\n");
8693 return -ENODEV;
8694 }
8695
8696 if (!is_thinkpad && !force_load)
8697 return -ENODEV;
8698
8699 return 0;
8700}
8701
8702static void __init thinkpad_acpi_init_banner(void)
8703{
8704 pr_info("%s v%s\n", TPACPI_DESC, TPACPI_VERSION);
8705 pr_info("%s\n", TPACPI_URL);
8706
8707 pr_info("ThinkPad BIOS %s, EC %s\n",
8708 (thinkpad_id.bios_version_str) ?
8709 thinkpad_id.bios_version_str : "unknown",
8710 (thinkpad_id.ec_version_str) ?
8711 thinkpad_id.ec_version_str : "unknown");
8712
8713 BUG_ON(!thinkpad_id.vendor);
8714
8715 if (thinkpad_id.model_str)
8716 pr_info("%s %s, model %s\n",
8717 (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
8718 "IBM" : ((thinkpad_id.vendor ==
8719 PCI_VENDOR_ID_LENOVO) ?
8720 "Lenovo" : "Unknown vendor"),
8721 thinkpad_id.model_str,
8722 (thinkpad_id.nummodel_str) ?
8723 thinkpad_id.nummodel_str : "unknown");
8724}
8725
8726
8727
8728static struct ibm_init_struct ibms_init[] __initdata = {
8729 {
8730 .data = &thinkpad_acpi_driver_data,
8731 },
8732 {
8733 .init = hotkey_init,
8734 .data = &hotkey_driver_data,
8735 },
8736 {
8737 .init = bluetooth_init,
8738 .data = &bluetooth_driver_data,
8739 },
8740 {
8741 .init = wan_init,
8742 .data = &wan_driver_data,
8743 },
8744 {
8745 .init = uwb_init,
8746 .data = &uwb_driver_data,
8747 },
8748#ifdef CONFIG_THINKPAD_ACPI_VIDEO
8749 {
8750 .init = video_init,
8751 .base_procfs_mode = S_IRUSR,
8752 .data = &video_driver_data,
8753 },
8754#endif
8755 {
8756 .init = light_init,
8757 .data = &light_driver_data,
8758 },
8759 {
8760 .init = cmos_init,
8761 .data = &cmos_driver_data,
8762 },
8763 {
8764 .init = led_init,
8765 .data = &led_driver_data,
8766 },
8767 {
8768 .init = beep_init,
8769 .data = &beep_driver_data,
8770 },
8771 {
8772 .init = thermal_init,
8773 .data = &thermal_driver_data,
8774 },
8775 {
8776 .init = brightness_init,
8777 .data = &brightness_driver_data,
8778 },
8779 {
8780 .init = volume_init,
8781 .data = &volume_driver_data,
8782 },
8783 {
8784 .init = fan_init,
8785 .data = &fan_driver_data,
8786 },
8787};
8788
8789static int __init set_ibm_param(const char *val, struct kernel_param *kp)
8790{
8791 unsigned int i;
8792 struct ibm_struct *ibm;
8793
8794 if (!kp || !kp->name || !val)
8795 return -EINVAL;
8796
8797 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
8798 ibm = ibms_init[i].data;
8799 WARN_ON(ibm == NULL);
8800
8801 if (!ibm || !ibm->name)
8802 continue;
8803
8804 if (strcmp(ibm->name, kp->name) == 0 && ibm->write) {
8805 if (strlen(val) > sizeof(ibms_init[i].param) - 2)
8806 return -ENOSPC;
8807 strcpy(ibms_init[i].param, val);
8808 strcat(ibms_init[i].param, ",");
8809 return 0;
8810 }
8811 }
8812
8813 return -EINVAL;
8814}
8815
8816module_param(experimental, int, 0444);
8817MODULE_PARM_DESC(experimental,
8818 "Enables experimental features when non-zero");
8819
8820module_param_named(debug, dbg_level, uint, 0);
8821MODULE_PARM_DESC(debug, "Sets debug level bit-mask");
8822
8823module_param(force_load, bool, 0444);
8824MODULE_PARM_DESC(force_load,
8825 "Attempts to load the driver even on a "
8826 "mis-identified ThinkPad when true");
8827
8828module_param_named(fan_control, fan_control_allowed, bool, 0444);
8829MODULE_PARM_DESC(fan_control,
8830 "Enables setting fan parameters features when true");
8831
8832module_param_named(brightness_mode, brightness_mode, uint, 0444);
8833MODULE_PARM_DESC(brightness_mode,
8834 "Selects brightness control strategy: "
8835 "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM");
8836
8837module_param(brightness_enable, uint, 0444);
8838MODULE_PARM_DESC(brightness_enable,
8839 "Enables backlight control when 1, disables when 0");
8840
8841module_param(hotkey_report_mode, uint, 0444);
8842MODULE_PARM_DESC(hotkey_report_mode,
8843 "used for backwards compatibility with userspace, "
8844 "see documentation");
8845
8846#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT
8847module_param_named(volume_mode, volume_mode, uint, 0444);
8848MODULE_PARM_DESC(volume_mode,
8849 "Selects volume control strategy: "
8850 "0=auto, 1=EC, 2=N/A, 3=EC+NVRAM");
8851
8852module_param_named(volume_capabilities, volume_capabilities, uint, 0444);
8853MODULE_PARM_DESC(volume_capabilities,
8854 "Selects the mixer capabilites: "
8855 "0=auto, 1=volume and mute, 2=mute only");
8856
8857module_param_named(volume_control, volume_control_allowed, bool, 0444);
8858MODULE_PARM_DESC(volume_control,
8859 "Enables software override for the console audio "
8860 "control when true");
8861
8862
8863module_param_named(index, alsa_index, int, 0444);
8864MODULE_PARM_DESC(index, "ALSA index for the ACPI EC Mixer");
8865module_param_named(id, alsa_id, charp, 0444);
8866MODULE_PARM_DESC(id, "ALSA id for the ACPI EC Mixer");
8867module_param_named(enable, alsa_enable, bool, 0444);
8868MODULE_PARM_DESC(enable, "Enable the ALSA interface for the ACPI EC Mixer");
8869#endif
8870
8871#define TPACPI_PARAM(feature) \
8872 module_param_call(feature, set_ibm_param, NULL, NULL, 0); \
8873 MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command " \
8874 "at module load, see documentation")
8875
8876TPACPI_PARAM(hotkey);
8877TPACPI_PARAM(bluetooth);
8878TPACPI_PARAM(video);
8879TPACPI_PARAM(light);
8880TPACPI_PARAM(cmos);
8881TPACPI_PARAM(led);
8882TPACPI_PARAM(beep);
8883TPACPI_PARAM(brightness);
8884TPACPI_PARAM(volume);
8885TPACPI_PARAM(fan);
8886
8887#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
8888module_param(dbg_wlswemul, uint, 0444);
8889MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation");
8890module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0);
8891MODULE_PARM_DESC(wlsw_state,
8892 "Initial state of the emulated WLSW switch");
8893
8894module_param(dbg_bluetoothemul, uint, 0444);
8895MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation");
8896module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0);
8897MODULE_PARM_DESC(bluetooth_state,
8898 "Initial state of the emulated bluetooth switch");
8899
8900module_param(dbg_wwanemul, uint, 0444);
8901MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation");
8902module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0);
8903MODULE_PARM_DESC(wwan_state,
8904 "Initial state of the emulated WWAN switch");
8905
8906module_param(dbg_uwbemul, uint, 0444);
8907MODULE_PARM_DESC(dbg_uwbemul, "Enables UWB switch emulation");
8908module_param_named(uwb_state, tpacpi_uwb_emulstate, bool, 0);
8909MODULE_PARM_DESC(uwb_state,
8910 "Initial state of the emulated UWB switch");
8911#endif
8912
8913static void thinkpad_acpi_module_exit(void)
8914{
8915 struct ibm_struct *ibm, *itmp;
8916
8917 tpacpi_lifecycle = TPACPI_LIFE_EXITING;
8918
8919 list_for_each_entry_safe_reverse(ibm, itmp,
8920 &tpacpi_all_drivers,
8921 all_drivers) {
8922 ibm_exit(ibm);
8923 }
8924
8925 dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
8926
8927 if (tpacpi_inputdev) {
8928 if (tp_features.input_device_registered)
8929 input_unregister_device(tpacpi_inputdev);
8930 else
8931 input_free_device(tpacpi_inputdev);
8932 }
8933
8934 if (tpacpi_hwmon)
8935 hwmon_device_unregister(tpacpi_hwmon);
8936
8937 if (tp_features.sensors_pdev_attrs_registered)
8938 device_remove_file(&tpacpi_sensors_pdev->dev,
8939 &dev_attr_thinkpad_acpi_pdev_name);
8940 if (tpacpi_sensors_pdev)
8941 platform_device_unregister(tpacpi_sensors_pdev);
8942 if (tpacpi_pdev)
8943 platform_device_unregister(tpacpi_pdev);
8944
8945 if (tp_features.sensors_pdrv_attrs_registered)
8946 tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver);
8947 if (tp_features.platform_drv_attrs_registered)
8948 tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
8949
8950 if (tp_features.sensors_pdrv_registered)
8951 platform_driver_unregister(&tpacpi_hwmon_pdriver);
8952
8953 if (tp_features.platform_drv_registered)
8954 platform_driver_unregister(&tpacpi_pdriver);
8955
8956 if (proc_dir)
8957 remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir);
8958
8959 if (tpacpi_wq)
8960 destroy_workqueue(tpacpi_wq);
8961
8962 kfree(thinkpad_id.bios_version_str);
8963 kfree(thinkpad_id.ec_version_str);
8964 kfree(thinkpad_id.model_str);
8965}
8966
8967
8968static int __init thinkpad_acpi_module_init(void)
8969{
8970 int ret, i;
8971
8972 tpacpi_lifecycle = TPACPI_LIFE_INIT;
8973
8974
8975 if (hotkey_report_mode > 2)
8976 return -EINVAL;
8977
8978
8979
8980 ret = get_thinkpad_model_data(&thinkpad_id);
8981 if (ret) {
8982 pr_err("unable to get DMI data: %d\n", ret);
8983 thinkpad_acpi_module_exit();
8984 return ret;
8985 }
8986 ret = probe_for_thinkpad();
8987 if (ret) {
8988 thinkpad_acpi_module_exit();
8989 return ret;
8990 }
8991
8992
8993
8994 thinkpad_acpi_init_banner();
8995 tpacpi_check_outdated_fw();
8996
8997 TPACPI_ACPIHANDLE_INIT(ecrd);
8998 TPACPI_ACPIHANDLE_INIT(ecwr);
8999
9000 tpacpi_wq = create_singlethread_workqueue(TPACPI_WORKQUEUE_NAME);
9001 if (!tpacpi_wq) {
9002 thinkpad_acpi_module_exit();
9003 return -ENOMEM;
9004 }
9005
9006 proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir);
9007 if (!proc_dir) {
9008 pr_err("unable to create proc dir " TPACPI_PROC_DIR "\n");
9009 thinkpad_acpi_module_exit();
9010 return -ENODEV;
9011 }
9012
9013 ret = platform_driver_register(&tpacpi_pdriver);
9014 if (ret) {
9015 pr_err("unable to register main platform driver\n");
9016 thinkpad_acpi_module_exit();
9017 return ret;
9018 }
9019 tp_features.platform_drv_registered = 1;
9020
9021 ret = platform_driver_register(&tpacpi_hwmon_pdriver);
9022 if (ret) {
9023 pr_err("unable to register hwmon platform driver\n");
9024 thinkpad_acpi_module_exit();
9025 return ret;
9026 }
9027 tp_features.sensors_pdrv_registered = 1;
9028
9029 ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
9030 if (!ret) {
9031 tp_features.platform_drv_attrs_registered = 1;
9032 ret = tpacpi_create_driver_attributes(
9033 &tpacpi_hwmon_pdriver.driver);
9034 }
9035 if (ret) {
9036 pr_err("unable to create sysfs driver attributes\n");
9037 thinkpad_acpi_module_exit();
9038 return ret;
9039 }
9040 tp_features.sensors_pdrv_attrs_registered = 1;
9041
9042
9043
9044 tpacpi_pdev = platform_device_register_simple(TPACPI_DRVR_NAME, -1,
9045 NULL, 0);
9046 if (IS_ERR(tpacpi_pdev)) {
9047 ret = PTR_ERR(tpacpi_pdev);
9048 tpacpi_pdev = NULL;
9049 pr_err("unable to register platform device\n");
9050 thinkpad_acpi_module_exit();
9051 return ret;
9052 }
9053 tpacpi_sensors_pdev = platform_device_register_simple(
9054 TPACPI_HWMON_DRVR_NAME,
9055 -1, NULL, 0);
9056 if (IS_ERR(tpacpi_sensors_pdev)) {
9057 ret = PTR_ERR(tpacpi_sensors_pdev);
9058 tpacpi_sensors_pdev = NULL;
9059 pr_err("unable to register hwmon platform device\n");
9060 thinkpad_acpi_module_exit();
9061 return ret;
9062 }
9063 ret = device_create_file(&tpacpi_sensors_pdev->dev,
9064 &dev_attr_thinkpad_acpi_pdev_name);
9065 if (ret) {
9066 pr_err("unable to create sysfs hwmon device attributes\n");
9067 thinkpad_acpi_module_exit();
9068 return ret;
9069 }
9070 tp_features.sensors_pdev_attrs_registered = 1;
9071 tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev);
9072 if (IS_ERR(tpacpi_hwmon)) {
9073 ret = PTR_ERR(tpacpi_hwmon);
9074 tpacpi_hwmon = NULL;
9075 pr_err("unable to register hwmon device\n");
9076 thinkpad_acpi_module_exit();
9077 return ret;
9078 }
9079 mutex_init(&tpacpi_inputdev_send_mutex);
9080 tpacpi_inputdev = input_allocate_device();
9081 if (!tpacpi_inputdev) {
9082 pr_err("unable to allocate input device\n");
9083 thinkpad_acpi_module_exit();
9084 return -ENOMEM;
9085 } else {
9086
9087 tpacpi_inputdev->name = "ThinkPad Extra Buttons";
9088 tpacpi_inputdev->phys = TPACPI_DRVR_NAME "/input0";
9089 tpacpi_inputdev->id.bustype = BUS_HOST;
9090 tpacpi_inputdev->id.vendor = thinkpad_id.vendor;
9091 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
9092 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
9093 tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev;
9094 }
9095
9096
9097 tpacpi_detect_brightness_capabilities();
9098
9099
9100 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
9101 ret = ibm_init(&ibms_init[i]);
9102 if (ret >= 0 && *ibms_init[i].param)
9103 ret = ibms_init[i].data->write(ibms_init[i].param);
9104 if (ret < 0) {
9105 thinkpad_acpi_module_exit();
9106 return ret;
9107 }
9108 }
9109
9110 tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
9111
9112 ret = input_register_device(tpacpi_inputdev);
9113 if (ret < 0) {
9114 pr_err("unable to register input device\n");
9115 thinkpad_acpi_module_exit();
9116 return ret;
9117 } else {
9118 tp_features.input_device_registered = 1;
9119 }
9120
9121 return 0;
9122}
9123
9124MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
9125
9126
9127
9128
9129
9130
9131
9132
9133MODULE_DEVICE_TABLE(acpi, ibm_htk_device_ids);
9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144#define IBM_BIOS_MODULE_ALIAS(__type) \
9145 MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW*")
9146
9147
9148
9149
9150IBM_BIOS_MODULE_ALIAS("I[MU]");
9151
9152MODULE_AUTHOR("Borislav Deianov <borislav@users.sf.net>");
9153MODULE_AUTHOR("Henrique de Moraes Holschuh <hmh@hmh.eng.br>");
9154MODULE_DESCRIPTION(TPACPI_DESC);
9155MODULE_VERSION(TPACPI_VERSION);
9156MODULE_LICENSE("GPL");
9157
9158module_init(thinkpad_acpi_module_init);
9159module_exit(thinkpad_acpi_module_exit);
9160