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