Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPI: thinkpad-acpi: add sysfs support to hotkey subdriver

Add the hotkey sysfs support.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>

authored by

Henrique de Moraes Holschuh and committed by
Len Brown
a0416420 d94a7f16

+176 -11
+47 -11
Documentation/thinkpad-acpi.txt
··· 134 134 subsystems are not documented here, nor are they tracked by this 135 135 attribute. 136 136 137 - Hot keys -- /proc/acpi/ibm/hotkey 138 - --------------------------------- 137 + Hot keys 138 + -------- 139 + 140 + procfs: /proc/acpi/ibm/hotkey 141 + sysfs device attribute: hotkey/* 139 142 140 143 Without this driver, only the Fn-F4 key (sleep button) generates an 141 144 ACPI event. With the driver loaded, the hotkey feature enabled and the ··· 151 148 All labeled Fn-Fx key combinations generate distinct events. In 152 149 addition, the lid microswitch and some docking station buttons may 153 150 also generate such events. 154 - 155 - The following commands can be written to this file: 156 - 157 - echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature 158 - echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature 159 - echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys 160 - echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys 161 - ... any other 4-hex-digit mask ... 162 - echo reset > /proc/acpi/ibm/hotkey -- restore the original mask 163 151 164 152 The bit mask allows some control over which hot keys generate ACPI 165 153 events. Not all bits in the mask can be modified. Not all bits that ··· 182 188 buttons do not generate ACPI events even with this driver. They *can* 183 189 be used through the "ThinkPad Buttons" utility, see 184 190 http://www.nongnu.org/tpb/ 191 + 192 + procfs notes: 193 + 194 + The following commands can be written to the /proc/acpi/ibm/hotkey file: 195 + 196 + echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature 197 + echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature 198 + echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys 199 + echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys 200 + ... any other 4-hex-digit mask ... 201 + echo reset > /proc/acpi/ibm/hotkey -- restore the original mask 202 + 203 + sysfs notes: 204 + 205 + The hot keys attributes are in a hotkey/ subdirectory off the 206 + thinkpad device. 207 + 208 + bios_enabled: 209 + Returns the status of the hot keys feature when 210 + thinkpad-acpi was loaded. Upon module unload, the hot 211 + key feature status will be restored to this value. 212 + 213 + 0: hot keys were disabled 214 + 1: hot keys were enabled 215 + 216 + bios_mask: 217 + Returns the hot keys mask when thinkpad-acpi was loaded. 218 + Upon module unload, the hot keys mask will be restored 219 + to this value. 220 + 221 + enable: 222 + Enables/disables the hot keys feature, and reports 223 + current status of the hot keys feature. 224 + 225 + 0: disables the hot keys feature / feature disabled 226 + 1: enables the hot keys feature / feature enabled 227 + 228 + mask: 229 + bit mask to enable ACPI event generation for each hot 230 + key (see above). Returns the current status of the hot 231 + keys mask, and allows one to modify it. 232 + 185 233 186 234 Bluetooth -- /proc/acpi/ibm/bluetooth 187 235 -------------------------------------
+127
drivers/misc/thinkpad_acpi.c
··· 706 706 static int hotkey_orig_status; 707 707 static int hotkey_orig_mask; 708 708 709 + static struct attribute_set *hotkey_dev_attributes = NULL; 710 + 711 + /* sysfs hotkey enable ------------------------------------------------- */ 712 + static ssize_t hotkey_enable_show(struct device *dev, 713 + struct device_attribute *attr, 714 + char *buf) 715 + { 716 + int res, status, mask; 717 + 718 + res = hotkey_get(&status, &mask); 719 + if (res) 720 + return res; 721 + 722 + return snprintf(buf, PAGE_SIZE, "%d\n", status); 723 + } 724 + 725 + static ssize_t hotkey_enable_store(struct device *dev, 726 + struct device_attribute *attr, 727 + const char *buf, size_t count) 728 + { 729 + unsigned long t; 730 + int res, status, mask; 731 + 732 + if (parse_strtoul(buf, 1, &t)) 733 + return -EINVAL; 734 + 735 + res = hotkey_get(&status, &mask); 736 + if (!res) 737 + res = hotkey_set(t, mask); 738 + 739 + return (res) ? res : count; 740 + } 741 + 742 + static struct device_attribute dev_attr_hotkey_enable = 743 + __ATTR(enable, S_IWUSR | S_IRUGO, 744 + hotkey_enable_show, hotkey_enable_store); 745 + 746 + /* sysfs hotkey mask --------------------------------------------------- */ 747 + static ssize_t hotkey_mask_show(struct device *dev, 748 + struct device_attribute *attr, 749 + char *buf) 750 + { 751 + int res, status, mask; 752 + 753 + res = hotkey_get(&status, &mask); 754 + if (res) 755 + return res; 756 + 757 + return snprintf(buf, PAGE_SIZE, "0x%04x\n", mask); 758 + } 759 + 760 + static ssize_t hotkey_mask_store(struct device *dev, 761 + struct device_attribute *attr, 762 + const char *buf, size_t count) 763 + { 764 + unsigned long t; 765 + int res, status, mask; 766 + 767 + if (parse_strtoul(buf, 0xffff, &t)) 768 + return -EINVAL; 769 + 770 + res = hotkey_get(&status, &mask); 771 + if (!res) 772 + hotkey_set(status, t); 773 + 774 + return (res) ? res : count; 775 + } 776 + 777 + static struct device_attribute dev_attr_hotkey_mask = 778 + __ATTR(mask, S_IWUSR | S_IRUGO, 779 + hotkey_mask_show, hotkey_mask_store); 780 + 781 + /* sysfs hotkey bios_enabled ------------------------------------------- */ 782 + static ssize_t hotkey_bios_enabled_show(struct device *dev, 783 + struct device_attribute *attr, 784 + char *buf) 785 + { 786 + return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status); 787 + } 788 + 789 + static struct device_attribute dev_attr_hotkey_bios_enabled = 790 + __ATTR(bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL); 791 + 792 + /* sysfs hotkey bios_mask ---------------------------------------------- */ 793 + static ssize_t hotkey_bios_mask_show(struct device *dev, 794 + struct device_attribute *attr, 795 + char *buf) 796 + { 797 + return snprintf(buf, PAGE_SIZE, "0x%04x\n", hotkey_orig_mask); 798 + } 799 + 800 + static struct device_attribute dev_attr_hotkey_bios_mask = 801 + __ATTR(bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL); 802 + 803 + /* --------------------------------------------------------------------- */ 804 + 805 + static struct attribute *hotkey_mask_attributes[] = { 806 + &dev_attr_hotkey_mask.attr, 807 + &dev_attr_hotkey_bios_enabled.attr, 808 + &dev_attr_hotkey_bios_mask.attr, 809 + }; 810 + 709 811 static int __init hotkey_init(struct ibm_init_struct *iibm) 710 812 { 711 813 int res; ··· 824 722 str_supported(tp_features.hotkey)); 825 723 826 724 if (tp_features.hotkey) { 725 + hotkey_dev_attributes = create_attr_set(4, 726 + TPACPI_HOTKEY_SYSFS_GROUP); 727 + if (!hotkey_dev_attributes) 728 + return -ENOMEM; 729 + res = add_to_attr_set(hotkey_dev_attributes, 730 + &dev_attr_hotkey_enable.attr); 731 + if (res) 732 + return res; 733 + 827 734 /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 828 735 A30, R30, R31, T20-22, X20-21, X22-24 */ 829 736 tp_features.hotkey_mask = ··· 842 731 str_supported(tp_features.hotkey_mask)); 843 732 844 733 res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask); 734 + if (!res && tp_features.hotkey_mask) { 735 + res = add_many_to_attr_set(hotkey_dev_attributes, 736 + hotkey_mask_attributes, 737 + ARRAY_SIZE(hotkey_mask_attributes)); 738 + } 739 + if (!res) 740 + res = register_attr_set_with_sysfs( 741 + hotkey_dev_attributes, 742 + &tpacpi_pdev->dev.kobj); 743 + 845 744 if (res) 846 745 return res; 847 746 } ··· 868 747 res = hotkey_set(hotkey_orig_status, hotkey_orig_mask); 869 748 if (res) 870 749 printk(IBM_ERR "failed to restore hotkey to BIOS defaults\n"); 750 + } 751 + 752 + if (hotkey_dev_attributes) { 753 + delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); 754 + hotkey_dev_attributes = NULL; 871 755 } 872 756 } 873 757 ··· 924 798 return 0; 925 799 } 926 800 801 + /* procfs -------------------------------------------------------------- */ 927 802 static int hotkey_read(char *p) 928 803 { 929 804 int res, status, mask;
+2
drivers/misc/thinkpad_acpi.h
··· 414 414 * Hotkey subdriver 415 415 */ 416 416 417 + #define TPACPI_HOTKEY_SYSFS_GROUP "hotkey" 418 + 417 419 static int hotkey_orig_status; 418 420 static int hotkey_orig_mask; 419 421