also generate such events.
The bit mask allows some control over which hot keys generate ACPI
-events. Not all bits in the mask can be modified. Not all bits that
-can be modified do anything. Not all hot keys can be individually
-controlled by the mask. Most recent ThinkPad models honor the
-following bits (assuming the hot keys feature has been enabled):
-
- key bit behavior when set behavior when unset
-
- Fn-F3 always generates ACPI event
- Fn-F4 always generates ACPI event
- Fn-F5 0010 generate ACPI event enable/disable Bluetooth
- Fn-F7 0040 generate ACPI event switch LCD and external display
- Fn-F8 0080 generate ACPI event expand screen or none
- Fn-F9 0100 generate ACPI event none
- Fn-F12 always generates ACPI event
-
-Some models do not support all of the above. For example, the T30 does
-not support Fn-F5 and Fn-F9. Other models do not support the mask at
-all. On those models, hot keys cannot be controlled individually.
+events. Not all bits in the mask can be modified. Not all bits that can
+be modified do anything. Not all hot keys can be individually controlled
+by the mask. Some models do not support the mask at all. On those
+models, hot keys cannot be controlled individually.
Note that enabling ACPI events for some keys prevents their default
-behavior. For example, if events for Fn-F5 are enabled, that key will
-no longer enable/disable Bluetooth by itself. This can still be done
-from an acpid handler for the ibm/hotkey event.
+behavior. For example, if events for Fn-F5 are enabled, that key will no
+longer enable/disable Bluetooth by itself. This can still be done from
+an acpid handler for the ibm/hotkey event.
+
+On some models, even enabling/disabling the entire hot key feature may
+change the way some keys behave (e.g. in a T43, Fn+F4 will generate an
+button/sleep ACPI event if hot keys are disabled, and it will ignore its
+mask when hot keys are enabled, so the key always does something. On a
+X40, Fn+F4 respects its mask status, but generates the button/sleep ACPI
+event if masked off).
Note also that not all Fn key combinations are supported through
ACPI. For example, on the X40, the brightness, volume and "Access IBM"
echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
- echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys
- echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
- ... any other 4-hex-digit mask ...
+ echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys
+ echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
+ ... any other 8-hex-digit mask ...
echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
sysfs notes:
*/
static int hotkey_orig_status;
-static int hotkey_orig_mask;
+static u32 hotkey_orig_mask;
static struct attribute_set *hotkey_dev_attributes;
struct device_attribute *attr,
char *buf)
{
- int res, status, mask;
+ int res, status;
+ u32 mask;
res = hotkey_get(&status, &mask);
if (res)
const char *buf, size_t count)
{
unsigned long t;
- int res, status, mask;
+ int res, status;
+ u32 mask;
if (parse_strtoul(buf, 1, &t))
return -EINVAL;
struct device_attribute *attr,
char *buf)
{
- int res, status, mask;
+ int res, status;
+ u32 mask;
res = hotkey_get(&status, &mask);
if (res)
return res;
- return snprintf(buf, PAGE_SIZE, "0x%04x\n", mask);
+ return snprintf(buf, PAGE_SIZE, "0x%08x\n", mask);
}
static ssize_t hotkey_mask_store(struct device *dev,
const char *buf, size_t count)
{
unsigned long t;
- int res, status, mask;
+ int res, status;
+ u32 mask;
- if (parse_strtoul(buf, 0xffff, &t))
+ if (parse_strtoul(buf, 0xffffffffUL, &t))
return -EINVAL;
res = hotkey_get(&status, &mask);
struct device_attribute *attr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "0x%04x\n", hotkey_orig_mask);
+ return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask);
}
static struct device_attribute dev_attr_hotkey_bios_mask =
{
int hkey;
- if (acpi_evalf(hkey_handle, &hkey, "MHKP", "d"))
+ if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
acpi_bus_generate_event(ibm->acpi->device, event, hkey);
- else {
- printk(IBM_ERR "unknown hotkey event %d\n", event);
+ } else {
+ printk(IBM_ERR "unknown hotkey notification event %d\n", event);
acpi_bus_generate_event(ibm->acpi->device, event, 0);
}
}
/*
* Call with hotkey_mutex held
*/
-static int hotkey_get(int *status, int *mask)
+static int hotkey_get(int *status, u32 *mask)
{
if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
return -EIO;
/*
* Call with hotkey_mutex held
*/
-static int hotkey_set(int status, int mask)
+static int hotkey_set(int status, u32 mask)
{
int i;
/* procfs -------------------------------------------------------------- */
static int hotkey_read(char *p)
{
- int res, status, mask;
+ int res, status;
+ u32 mask;
int len = 0;
if (!tp_features.hotkey) {
len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
if (tp_features.hotkey_mask) {
- len += sprintf(p + len, "mask:\t\t0x%04x\n", mask);
+ len += sprintf(p + len, "mask:\t\t0x%08x\n", mask);
len += sprintf(p + len,
"commands:\tenable, disable, reset, <mask>\n");
} else {
static int hotkey_write(char *buf)
{
- int res, status, mask;
+ int res, status;
+ u32 mask;
char *cmd;
int do_cmd = 0;
*/
static int hotkey_orig_status;
-static int hotkey_orig_mask;
+static u32 hotkey_orig_mask;
static struct mutex hotkey_mutex;
static int hotkey_init(struct ibm_init_struct *iibm);
static void hotkey_exit(void);
-static int hotkey_get(int *status, int *mask);
-static int hotkey_set(int status, int mask);
+static int hotkey_get(int *status, u32 *mask);
+static int hotkey_set(int status, u32 mask);
static void hotkey_notify(struct ibm_struct *ibm, u32 event);
static int hotkey_read(char *p);
static int hotkey_write(char *buf);