1 From a0416420e2c6244792d6f308183ad57c40532078 Mon Sep 17 00:00:00 2001
2 From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
3 Date: Fri, 27 Apr 2007 22:00:16 -0300
4 Subject: ACPI: thinkpad-acpi: add sysfs support to hotkey subdriver
6 Add the hotkey sysfs support.
8 Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
9 Signed-off-by: Len Brown <len.brown@intel.com>
11 Documentation/thinkpad-acpi.txt | 58 ++++++++++++++----
12 drivers/misc/thinkpad_acpi.c | 127 +++++++++++++++++++++++++++++++++++++++
13 drivers/misc/thinkpad_acpi.h | 2 +
14 3 files changed, 176 insertions(+), 11 deletions(-)
16 diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
17 index e3ad7a4..ebeed58 100644
18 --- a/Documentation/thinkpad-acpi.txt
19 +++ b/Documentation/thinkpad-acpi.txt
20 @@ -134,8 +134,11 @@ end of this document. Changes to the sysfs interface done by the kernel
21 subsystems are not documented here, nor are they tracked by this
24 -Hot keys -- /proc/acpi/ibm/hotkey
25 ----------------------------------
29 +procfs: /proc/acpi/ibm/hotkey
30 +sysfs device attribute: hotkey/*
32 Without this driver, only the Fn-F4 key (sleep button) generates an
33 ACPI event. With the driver loaded, the hotkey feature enabled and the
34 @@ -149,15 +152,6 @@ All labeled Fn-Fx key combinations generate distinct events. In
35 addition, the lid microswitch and some docking station buttons may
36 also generate such events.
38 -The following commands can be written to this file:
40 - echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
41 - echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
42 - echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys
43 - echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
44 - ... any other 4-hex-digit mask ...
45 - echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
47 The bit mask allows some control over which hot keys generate ACPI
48 events. Not all bits in the mask can be modified. Not all bits that
49 can be modified do anything. Not all hot keys can be individually
50 @@ -189,6 +183,48 @@ buttons do not generate ACPI events even with this driver. They *can*
51 be used through the "ThinkPad Buttons" utility, see
52 http://www.nongnu.org/tpb/
56 +The following commands can be written to the /proc/acpi/ibm/hotkey file:
58 + echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
59 + echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
60 + echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys
61 + echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
62 + ... any other 4-hex-digit mask ...
63 + echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
67 + The hot keys attributes are in a hotkey/ subdirectory off the
71 + Returns the status of the hot keys feature when
72 + thinkpad-acpi was loaded. Upon module unload, the hot
73 + key feature status will be restored to this value.
75 + 0: hot keys were disabled
76 + 1: hot keys were enabled
79 + Returns the hot keys mask when thinkpad-acpi was loaded.
80 + Upon module unload, the hot keys mask will be restored
84 + Enables/disables the hot keys feature, and reports
85 + current status of the hot keys feature.
87 + 0: disables the hot keys feature / feature disabled
88 + 1: enables the hot keys feature / feature enabled
91 + bit mask to enable ACPI event generation for each hot
92 + key (see above). Returns the current status of the hot
93 + keys mask, and allows one to modify it.
96 Bluetooth -- /proc/acpi/ibm/bluetooth
97 -------------------------------------
99 diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
100 index a565265..83a8d98 100644
101 --- a/drivers/misc/thinkpad_acpi.c
102 +++ b/drivers/misc/thinkpad_acpi.c
103 @@ -706,6 +706,108 @@ static struct ibm_struct thinkpad_acpi_driver_data = {
104 static int hotkey_orig_status;
105 static int hotkey_orig_mask;
107 +static struct attribute_set *hotkey_dev_attributes = NULL;
109 +/* sysfs hotkey enable ------------------------------------------------- */
110 +static ssize_t hotkey_enable_show(struct device *dev,
111 + struct device_attribute *attr,
114 + int res, status, mask;
116 + res = hotkey_get(&status, &mask);
120 + return snprintf(buf, PAGE_SIZE, "%d\n", status);
123 +static ssize_t hotkey_enable_store(struct device *dev,
124 + struct device_attribute *attr,
125 + const char *buf, size_t count)
128 + int res, status, mask;
130 + if (parse_strtoul(buf, 1, &t))
133 + res = hotkey_get(&status, &mask);
135 + res = hotkey_set(t, mask);
137 + return (res) ? res : count;
140 +static struct device_attribute dev_attr_hotkey_enable =
141 + __ATTR(enable, S_IWUSR | S_IRUGO,
142 + hotkey_enable_show, hotkey_enable_store);
144 +/* sysfs hotkey mask --------------------------------------------------- */
145 +static ssize_t hotkey_mask_show(struct device *dev,
146 + struct device_attribute *attr,
149 + int res, status, mask;
151 + res = hotkey_get(&status, &mask);
155 + return snprintf(buf, PAGE_SIZE, "0x%04x\n", mask);
158 +static ssize_t hotkey_mask_store(struct device *dev,
159 + struct device_attribute *attr,
160 + const char *buf, size_t count)
163 + int res, status, mask;
165 + if (parse_strtoul(buf, 0xffff, &t))
168 + res = hotkey_get(&status, &mask);
170 + hotkey_set(status, t);
172 + return (res) ? res : count;
175 +static struct device_attribute dev_attr_hotkey_mask =
176 + __ATTR(mask, S_IWUSR | S_IRUGO,
177 + hotkey_mask_show, hotkey_mask_store);
179 +/* sysfs hotkey bios_enabled ------------------------------------------- */
180 +static ssize_t hotkey_bios_enabled_show(struct device *dev,
181 + struct device_attribute *attr,
184 + return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status);
187 +static struct device_attribute dev_attr_hotkey_bios_enabled =
188 + __ATTR(bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL);
190 +/* sysfs hotkey bios_mask ---------------------------------------------- */
191 +static ssize_t hotkey_bios_mask_show(struct device *dev,
192 + struct device_attribute *attr,
195 + return snprintf(buf, PAGE_SIZE, "0x%04x\n", hotkey_orig_mask);
198 +static struct device_attribute dev_attr_hotkey_bios_mask =
199 + __ATTR(bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL);
201 +/* --------------------------------------------------------------------- */
203 +static struct attribute *hotkey_mask_attributes[] = {
204 + &dev_attr_hotkey_mask.attr,
205 + &dev_attr_hotkey_bios_enabled.attr,
206 + &dev_attr_hotkey_bios_mask.attr,
209 static int __init hotkey_init(struct ibm_init_struct *iibm)
212 @@ -722,6 +824,15 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
213 str_supported(tp_features.hotkey));
215 if (tp_features.hotkey) {
216 + hotkey_dev_attributes = create_attr_set(4,
217 + TPACPI_HOTKEY_SYSFS_GROUP);
218 + if (!hotkey_dev_attributes)
220 + res = add_to_attr_set(hotkey_dev_attributes,
221 + &dev_attr_hotkey_enable.attr);
225 /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
226 A30, R30, R31, T20-22, X20-21, X22-24 */
227 tp_features.hotkey_mask =
228 @@ -731,6 +842,16 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
229 str_supported(tp_features.hotkey_mask));
231 res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask);
232 + if (!res && tp_features.hotkey_mask) {
233 + res = add_many_to_attr_set(hotkey_dev_attributes,
234 + hotkey_mask_attributes,
235 + ARRAY_SIZE(hotkey_mask_attributes));
238 + res = register_attr_set_with_sysfs(
239 + hotkey_dev_attributes,
240 + &tpacpi_pdev->dev.kobj);
245 @@ -748,6 +869,11 @@ static void hotkey_exit(void)
247 printk(IBM_ERR "failed to restore hotkey to BIOS defaults\n");
250 + if (hotkey_dev_attributes) {
251 + delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
252 + hotkey_dev_attributes = NULL;
256 static void hotkey_notify(struct ibm_struct *ibm, u32 event)
257 @@ -798,6 +924,7 @@ static int hotkey_set(int status, int mask)
261 +/* procfs -------------------------------------------------------------- */
262 static int hotkey_read(char *p)
264 int res, status, mask;
265 diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
266 index a9e7093..7615adb 100644
267 --- a/drivers/misc/thinkpad_acpi.h
268 +++ b/drivers/misc/thinkpad_acpi.h
269 @@ -414,6 +414,8 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc);
273 +#define TPACPI_HOTKEY_SYSFS_GROUP "hotkey"
275 static int hotkey_orig_status;
276 static int hotkey_orig_mask;