diff options
-rw-r--r-- | Documentation/ABI/testing/sysfs-platform-eeepc-wmi | 14 | ||||
-rw-r--r-- | drivers/platform/x86/eeepc-wmi.c | 89 |
2 files changed, 102 insertions, 1 deletions
diff --git a/Documentation/ABI/testing/sysfs-platform-eeepc-wmi b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi index e4b5fef5fad..9fc8d33e280 100644 --- a/Documentation/ABI/testing/sysfs-platform-eeepc-wmi +++ b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi | |||
@@ -8,3 +8,17 @@ Description: | |||
8 | * 0 -> Super Performance Mode | 8 | * 0 -> Super Performance Mode |
9 | * 1 -> High Performance Mode | 9 | * 1 -> High Performance Mode |
10 | * 2 -> Power Saving Mode | 10 | * 2 -> Power Saving Mode |
11 | |||
12 | What: /sys/devices/platform/eeepc-wmi/camera | ||
13 | Date: Jan 2010 | ||
14 | KernelVersion: 2.6.39 | ||
15 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
16 | Description: | ||
17 | Control the camera. 1 means on, 0 means off. | ||
18 | |||
19 | What: /sys/devices/platform/eeepc-wmi/cardr | ||
20 | Date: Jan 2010 | ||
21 | KernelVersion: 2.6.39 | ||
22 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
23 | Description: | ||
24 | Control the card reader. 1 means on, 0 means off. | ||
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index 391c32bd703..83415dd42d0 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c | |||
@@ -73,6 +73,8 @@ MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID); | |||
73 | #define EEEPC_WMI_DEVID_BLUETOOTH 0x00010013 | 73 | #define EEEPC_WMI_DEVID_BLUETOOTH 0x00010013 |
74 | #define EEEPC_WMI_DEVID_WWAN3G 0x00010019 | 74 | #define EEEPC_WMI_DEVID_WWAN3G 0x00010019 |
75 | #define EEEPC_WMI_DEVID_BACKLIGHT 0x00050012 | 75 | #define EEEPC_WMI_DEVID_BACKLIGHT 0x00050012 |
76 | #define EEEPC_WMI_DEVID_CAMERA 0x00060013 | ||
77 | #define EEEPC_WMI_DEVID_CARDREADER 0x00080013 | ||
76 | #define EEEPC_WMI_DEVID_TPDLED 0x00100011 | 78 | #define EEEPC_WMI_DEVID_TPDLED 0x00100011 |
77 | 79 | ||
78 | #define EEEPC_WMI_DSTS_STATUS_BIT 0x00000001 | 80 | #define EEEPC_WMI_DSTS_STATUS_BIT 0x00000001 |
@@ -879,6 +881,70 @@ static void eeepc_wmi_notify(u32 value, void *context) | |||
879 | kfree(obj); | 881 | kfree(obj); |
880 | } | 882 | } |
881 | 883 | ||
884 | /* | ||
885 | * Sys helpers | ||
886 | */ | ||
887 | static int parse_arg(const char *buf, unsigned long count, int *val) | ||
888 | { | ||
889 | if (!count) | ||
890 | return 0; | ||
891 | if (sscanf(buf, "%i", val) != 1) | ||
892 | return -EINVAL; | ||
893 | return count; | ||
894 | } | ||
895 | |||
896 | static ssize_t store_sys_wmi(int devid, const char *buf, size_t count) | ||
897 | { | ||
898 | acpi_status status; | ||
899 | u32 retval; | ||
900 | int rv, value; | ||
901 | |||
902 | value = eeepc_wmi_get_devstate_simple(devid); | ||
903 | if (value == -ENODEV) /* Check device presence */ | ||
904 | return value; | ||
905 | |||
906 | rv = parse_arg(buf, count, &value); | ||
907 | status = eeepc_wmi_set_devstate(devid, value, &retval); | ||
908 | |||
909 | if (ACPI_FAILURE(status)) | ||
910 | return -EIO; | ||
911 | return rv; | ||
912 | } | ||
913 | |||
914 | static ssize_t show_sys_wmi(int devid, char *buf) | ||
915 | { | ||
916 | int value = eeepc_wmi_get_devstate_simple(devid); | ||
917 | |||
918 | if (value < 0) | ||
919 | return value; | ||
920 | |||
921 | return sprintf(buf, "%d\n", value); | ||
922 | } | ||
923 | |||
924 | #define EEEPC_WMI_CREATE_DEVICE_ATTR(_name, _mode, _cm) \ | ||
925 | static ssize_t show_##_name(struct device *dev, \ | ||
926 | struct device_attribute *attr, \ | ||
927 | char *buf) \ | ||
928 | { \ | ||
929 | return show_sys_wmi(_cm, buf); \ | ||
930 | } \ | ||
931 | static ssize_t store_##_name(struct device *dev, \ | ||
932 | struct device_attribute *attr, \ | ||
933 | const char *buf, size_t count) \ | ||
934 | { \ | ||
935 | return store_sys_wmi(_cm, buf, count); \ | ||
936 | } \ | ||
937 | static struct device_attribute dev_attr_##_name = { \ | ||
938 | .attr = { \ | ||
939 | .name = __stringify(_name), \ | ||
940 | .mode = _mode }, \ | ||
941 | .show = show_##_name, \ | ||
942 | .store = store_##_name, \ | ||
943 | } | ||
944 | |||
945 | EEEPC_WMI_CREATE_DEVICE_ATTR(camera, 0644, EEEPC_WMI_DEVID_CAMERA); | ||
946 | EEEPC_WMI_CREATE_DEVICE_ATTR(cardr, 0644, EEEPC_WMI_DEVID_CARDREADER); | ||
947 | |||
882 | static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, | 948 | static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, |
883 | const char *buf, size_t count) | 949 | const char *buf, size_t count) |
884 | { | 950 | { |
@@ -904,11 +970,32 @@ static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv); | |||
904 | 970 | ||
905 | static struct attribute *platform_attributes[] = { | 971 | static struct attribute *platform_attributes[] = { |
906 | &dev_attr_cpufv.attr, | 972 | &dev_attr_cpufv.attr, |
973 | &dev_attr_camera.attr, | ||
974 | &dev_attr_cardr.attr, | ||
907 | NULL | 975 | NULL |
908 | }; | 976 | }; |
909 | 977 | ||
978 | static mode_t eeepc_sysfs_is_visible(struct kobject *kobj, | ||
979 | struct attribute *attr, | ||
980 | int idx) | ||
981 | { | ||
982 | bool supported = true; | ||
983 | int devid = -1; | ||
984 | |||
985 | if (attr == &dev_attr_camera.attr) | ||
986 | devid = EEEPC_WMI_DEVID_CAMERA; | ||
987 | else if (attr == &dev_attr_cardr.attr) | ||
988 | devid = EEEPC_WMI_DEVID_CARDREADER; | ||
989 | |||
990 | if (devid != -1) | ||
991 | supported = eeepc_wmi_get_devstate_simple(devid) != -ENODEV; | ||
992 | |||
993 | return supported ? attr->mode : 0; | ||
994 | } | ||
995 | |||
910 | static struct attribute_group platform_attribute_group = { | 996 | static struct attribute_group platform_attribute_group = { |
911 | .attrs = platform_attributes | 997 | .is_visible = eeepc_sysfs_is_visible, |
998 | .attrs = platform_attributes | ||
912 | }; | 999 | }; |
913 | 1000 | ||
914 | static void eeepc_wmi_sysfs_exit(struct platform_device *device) | 1001 | static void eeepc_wmi_sysfs_exit(struct platform_device *device) |