diff options
author | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 2007-04-27 21:00:17 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-04-28 21:41:20 -0400 |
commit | d3a6ade4f84416d774c3e5db5faae1840d55bd97 (patch) | |
tree | 7d9568a5531b9ad4a48308e4e63ca7976f7de558 | |
parent | a0416420e2c6244792d6f308183ad57c40532078 (diff) |
ACPI: thinkpad-acpi: add sysfs support to wan and bluetooth subdrivers
Add support to sysfs to the wan and bluetooth subdrivers.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | Documentation/thinkpad-acpi.txt | 61 | ||||
-rw-r--r-- | drivers/misc/thinkpad_acpi.c | 144 | ||||
-rw-r--r-- | drivers/misc/thinkpad_acpi.h | 4 |
3 files changed, 186 insertions, 23 deletions
diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt index ebeed589f6d7..2d4803359a04 100644 --- a/Documentation/thinkpad-acpi.txt +++ b/Documentation/thinkpad-acpi.txt | |||
@@ -225,15 +225,35 @@ sysfs notes: | |||
225 | keys mask, and allows one to modify it. | 225 | keys mask, and allows one to modify it. |
226 | 226 | ||
227 | 227 | ||
228 | Bluetooth -- /proc/acpi/ibm/bluetooth | 228 | Bluetooth |
229 | ------------------------------------- | 229 | --------- |
230 | 230 | ||
231 | This feature shows the presence and current state of a Bluetooth | 231 | procfs: /proc/acpi/ibm/bluetooth |
232 | device. If Bluetooth is installed, the following commands can be used: | 232 | sysfs device attribute: bluetooth/enable |
233 | |||
234 | This feature shows the presence and current state of a ThinkPad | ||
235 | Bluetooth device in the internal ThinkPad CDC slot. | ||
236 | |||
237 | Procfs notes: | ||
238 | |||
239 | If Bluetooth is installed, the following commands can be used: | ||
233 | 240 | ||
234 | echo enable > /proc/acpi/ibm/bluetooth | 241 | echo enable > /proc/acpi/ibm/bluetooth |
235 | echo disable > /proc/acpi/ibm/bluetooth | 242 | echo disable > /proc/acpi/ibm/bluetooth |
236 | 243 | ||
244 | Sysfs notes: | ||
245 | |||
246 | If the Bluetooth CDC card is installed, it can be enabled / | ||
247 | disabled through the "bluetooth/enable" thinkpad-acpi device | ||
248 | attribute, and its current status can also be queried. | ||
249 | |||
250 | enable: | ||
251 | 0: disables Bluetooth / Bluetooth is disabled | ||
252 | 1: enables Bluetooth / Bluetooth is enabled. | ||
253 | |||
254 | Note: this interface will be probably be superseeded by the | ||
255 | generic rfkill class. | ||
256 | |||
237 | Video output control -- /proc/acpi/ibm/video | 257 | Video output control -- /proc/acpi/ibm/video |
238 | -------------------------------------------- | 258 | -------------------------------------------- |
239 | 259 | ||
@@ -874,23 +894,42 @@ with EINVAL, try to set pwm1_enable to 1 and pwm1 to at least 128 (255 | |||
874 | would be the safest choice, though). | 894 | would be the safest choice, though). |
875 | 895 | ||
876 | 896 | ||
877 | EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan | 897 | EXPERIMENTAL: WAN |
878 | --------------------------------------- | 898 | ----------------- |
899 | |||
900 | procfs: /proc/acpi/ibm/wan | ||
901 | sysfs device attribute: wwan/enable | ||
879 | 902 | ||
880 | This feature is marked EXPERIMENTAL because the implementation | 903 | This feature is marked EXPERIMENTAL because the implementation |
881 | directly accesses hardware registers and may not work as expected. USE | 904 | directly accesses hardware registers and may not work as expected. USE |
882 | WITH CAUTION! To use this feature, you need to supply the | 905 | WITH CAUTION! To use this feature, you need to supply the |
883 | experimental=1 parameter when loading the module. | 906 | experimental=1 parameter when loading the module. |
884 | 907 | ||
885 | This feature shows the presence and current state of a WAN (Sierra | 908 | This feature shows the presence and current state of a W-WAN (Sierra |
886 | Wireless EV-DO) device. If WAN is installed, the following commands can | 909 | Wireless EV-DO) device. |
887 | be used: | 910 | |
911 | It was tested on a Lenovo Thinkpad X60. It should probably work on other | ||
912 | Thinkpad models which come with this module installed. | ||
913 | |||
914 | Procfs notes: | ||
915 | |||
916 | If the W-WAN card is installed, the following commands can be used: | ||
888 | 917 | ||
889 | echo enable > /proc/acpi/ibm/wan | 918 | echo enable > /proc/acpi/ibm/wan |
890 | echo disable > /proc/acpi/ibm/wan | 919 | echo disable > /proc/acpi/ibm/wan |
891 | 920 | ||
892 | It was tested on a Lenovo Thinkpad X60. It should probably work on other | 921 | Sysfs notes: |
893 | Thinkpad models which come with this module installed. | 922 | |
923 | If the W-WAN card is installed, it can be enabled / | ||
924 | disabled through the "wwan/enable" thinkpad-acpi device | ||
925 | attribute, and its current status can also be queried. | ||
926 | |||
927 | enable: | ||
928 | 0: disables WWAN card / WWAN card is disabled | ||
929 | 1: enables WWAN card / WWAN card is enabled. | ||
930 | |||
931 | Note: this interface will be probably be superseeded by the | ||
932 | generic rfkill class. | ||
894 | 933 | ||
895 | Multiple Commands, Module Parameters | 934 | Multiple Commands, Module Parameters |
896 | ------------------------------------ | 935 | ------------------------------------ |
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 83a8d984e709..6c36a55cb3d1 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
@@ -1020,8 +1020,54 @@ static struct ibm_struct hotkey_driver_data = { | |||
1020 | * Bluetooth subdriver | 1020 | * Bluetooth subdriver |
1021 | */ | 1021 | */ |
1022 | 1022 | ||
1023 | /* sysfs bluetooth enable ---------------------------------------------- */ | ||
1024 | static ssize_t bluetooth_enable_show(struct device *dev, | ||
1025 | struct device_attribute *attr, | ||
1026 | char *buf) | ||
1027 | { | ||
1028 | int status; | ||
1029 | |||
1030 | status = bluetooth_get_radiosw(); | ||
1031 | if (status < 0) | ||
1032 | return status; | ||
1033 | |||
1034 | return snprintf(buf, PAGE_SIZE, "%d\n", status ? 1 : 0); | ||
1035 | } | ||
1036 | |||
1037 | static ssize_t bluetooth_enable_store(struct device *dev, | ||
1038 | struct device_attribute *attr, | ||
1039 | const char *buf, size_t count) | ||
1040 | { | ||
1041 | unsigned long t; | ||
1042 | int res; | ||
1043 | |||
1044 | if (parse_strtoul(buf, 1, &t)) | ||
1045 | return -EINVAL; | ||
1046 | |||
1047 | res = bluetooth_set_radiosw(t); | ||
1048 | |||
1049 | return (res) ? res : count; | ||
1050 | } | ||
1051 | |||
1052 | static struct device_attribute dev_attr_bluetooth_enable = | ||
1053 | __ATTR(enable, S_IWUSR | S_IRUGO, | ||
1054 | bluetooth_enable_show, bluetooth_enable_store); | ||
1055 | |||
1056 | /* --------------------------------------------------------------------- */ | ||
1057 | |||
1058 | static struct attribute *bluetooth_attributes[] = { | ||
1059 | &dev_attr_bluetooth_enable.attr, | ||
1060 | NULL | ||
1061 | }; | ||
1062 | |||
1063 | static const struct attribute_group bluetooth_attr_group = { | ||
1064 | .name = TPACPI_BLUETH_SYSFS_GROUP, | ||
1065 | .attrs = bluetooth_attributes, | ||
1066 | }; | ||
1067 | |||
1023 | static int __init bluetooth_init(struct ibm_init_struct *iibm) | 1068 | static int __init bluetooth_init(struct ibm_init_struct *iibm) |
1024 | { | 1069 | { |
1070 | int res; | ||
1025 | int status = 0; | 1071 | int status = 0; |
1026 | 1072 | ||
1027 | vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n"); | 1073 | vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n"); |
@@ -1037,17 +1083,29 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) | |||
1037 | str_supported(tp_features.bluetooth), | 1083 | str_supported(tp_features.bluetooth), |
1038 | status); | 1084 | status); |
1039 | 1085 | ||
1040 | if (tp_features.bluetooth && | 1086 | if (tp_features.bluetooth) { |
1041 | !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) { | 1087 | if (!(status & TP_ACPI_BLUETOOTH_HWPRESENT)) { |
1042 | /* no bluetooth hardware present in system */ | 1088 | /* no bluetooth hardware present in system */ |
1043 | tp_features.bluetooth = 0; | 1089 | tp_features.bluetooth = 0; |
1044 | dbg_printk(TPACPI_DBG_INIT, | 1090 | dbg_printk(TPACPI_DBG_INIT, |
1045 | "bluetooth hardware not installed\n"); | 1091 | "bluetooth hardware not installed\n"); |
1092 | } else { | ||
1093 | res = sysfs_create_group(&tpacpi_pdev->dev.kobj, | ||
1094 | &bluetooth_attr_group); | ||
1095 | if (res) | ||
1096 | return res; | ||
1097 | } | ||
1046 | } | 1098 | } |
1047 | 1099 | ||
1048 | return (tp_features.bluetooth)? 0 : 1; | 1100 | return (tp_features.bluetooth)? 0 : 1; |
1049 | } | 1101 | } |
1050 | 1102 | ||
1103 | static void bluetooth_exit(void) | ||
1104 | { | ||
1105 | sysfs_remove_group(&tpacpi_pdev->dev.kobj, | ||
1106 | &bluetooth_attr_group); | ||
1107 | } | ||
1108 | |||
1051 | static int bluetooth_get_radiosw(void) | 1109 | static int bluetooth_get_radiosw(void) |
1052 | { | 1110 | { |
1053 | int status; | 1111 | int status; |
@@ -1080,6 +1138,7 @@ static int bluetooth_set_radiosw(int radio_on) | |||
1080 | return 0; | 1138 | return 0; |
1081 | } | 1139 | } |
1082 | 1140 | ||
1141 | /* procfs -------------------------------------------------------------- */ | ||
1083 | static int bluetooth_read(char *p) | 1142 | static int bluetooth_read(char *p) |
1084 | { | 1143 | { |
1085 | int len = 0; | 1144 | int len = 0; |
@@ -1119,14 +1178,61 @@ static struct ibm_struct bluetooth_driver_data = { | |||
1119 | .name = "bluetooth", | 1178 | .name = "bluetooth", |
1120 | .read = bluetooth_read, | 1179 | .read = bluetooth_read, |
1121 | .write = bluetooth_write, | 1180 | .write = bluetooth_write, |
1181 | .exit = bluetooth_exit, | ||
1122 | }; | 1182 | }; |
1123 | 1183 | ||
1124 | /************************************************************************* | 1184 | /************************************************************************* |
1125 | * Wan subdriver | 1185 | * Wan subdriver |
1126 | */ | 1186 | */ |
1127 | 1187 | ||
1188 | /* sysfs wan enable ---------------------------------------------------- */ | ||
1189 | static ssize_t wan_enable_show(struct device *dev, | ||
1190 | struct device_attribute *attr, | ||
1191 | char *buf) | ||
1192 | { | ||
1193 | int status; | ||
1194 | |||
1195 | status = wan_get_radiosw(); | ||
1196 | if (status < 0) | ||
1197 | return status; | ||
1198 | |||
1199 | return snprintf(buf, PAGE_SIZE, "%d\n", status ? 1 : 0); | ||
1200 | } | ||
1201 | |||
1202 | static ssize_t wan_enable_store(struct device *dev, | ||
1203 | struct device_attribute *attr, | ||
1204 | const char *buf, size_t count) | ||
1205 | { | ||
1206 | unsigned long t; | ||
1207 | int res; | ||
1208 | |||
1209 | if (parse_strtoul(buf, 1, &t)) | ||
1210 | return -EINVAL; | ||
1211 | |||
1212 | res = wan_set_radiosw(t); | ||
1213 | |||
1214 | return (res) ? res : count; | ||
1215 | } | ||
1216 | |||
1217 | static struct device_attribute dev_attr_wan_enable = | ||
1218 | __ATTR(enable, S_IWUSR | S_IRUGO, | ||
1219 | wan_enable_show, wan_enable_store); | ||
1220 | |||
1221 | /* --------------------------------------------------------------------- */ | ||
1222 | |||
1223 | static struct attribute *wan_attributes[] = { | ||
1224 | &dev_attr_wan_enable.attr, | ||
1225 | NULL | ||
1226 | }; | ||
1227 | |||
1228 | static const struct attribute_group wan_attr_group = { | ||
1229 | .name = TPACPI_WAN_SYSFS_GROUP, | ||
1230 | .attrs = wan_attributes, | ||
1231 | }; | ||
1232 | |||
1128 | static int __init wan_init(struct ibm_init_struct *iibm) | 1233 | static int __init wan_init(struct ibm_init_struct *iibm) |
1129 | { | 1234 | { |
1235 | int res; | ||
1130 | int status = 0; | 1236 | int status = 0; |
1131 | 1237 | ||
1132 | vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n"); | 1238 | vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n"); |
@@ -1140,17 +1246,29 @@ static int __init wan_init(struct ibm_init_struct *iibm) | |||
1140 | str_supported(tp_features.wan), | 1246 | str_supported(tp_features.wan), |
1141 | status); | 1247 | status); |
1142 | 1248 | ||
1143 | if (tp_features.wan && | 1249 | if (tp_features.wan) { |
1144 | !(status & TP_ACPI_WANCARD_HWPRESENT)) { | 1250 | if (!(status & TP_ACPI_WANCARD_HWPRESENT)) { |
1145 | /* no wan hardware present in system */ | 1251 | /* no wan hardware present in system */ |
1146 | tp_features.wan = 0; | 1252 | tp_features.wan = 0; |
1147 | dbg_printk(TPACPI_DBG_INIT, | 1253 | dbg_printk(TPACPI_DBG_INIT, |
1148 | "wan hardware not installed\n"); | 1254 | "wan hardware not installed\n"); |
1255 | } else { | ||
1256 | res = sysfs_create_group(&tpacpi_pdev->dev.kobj, | ||
1257 | &wan_attr_group); | ||
1258 | if (res) | ||
1259 | return res; | ||
1260 | } | ||
1149 | } | 1261 | } |
1150 | 1262 | ||
1151 | return (tp_features.wan)? 0 : 1; | 1263 | return (tp_features.wan)? 0 : 1; |
1152 | } | 1264 | } |
1153 | 1265 | ||
1266 | static void wan_exit(void) | ||
1267 | { | ||
1268 | sysfs_remove_group(&tpacpi_pdev->dev.kobj, | ||
1269 | &wan_attr_group); | ||
1270 | } | ||
1271 | |||
1154 | static int wan_get_radiosw(void) | 1272 | static int wan_get_radiosw(void) |
1155 | { | 1273 | { |
1156 | int status; | 1274 | int status; |
@@ -1183,6 +1301,7 @@ static int wan_set_radiosw(int radio_on) | |||
1183 | return 0; | 1301 | return 0; |
1184 | } | 1302 | } |
1185 | 1303 | ||
1304 | /* procfs -------------------------------------------------------------- */ | ||
1186 | static int wan_read(char *p) | 1305 | static int wan_read(char *p) |
1187 | { | 1306 | { |
1188 | int len = 0; | 1307 | int len = 0; |
@@ -1222,6 +1341,7 @@ static struct ibm_struct wan_driver_data = { | |||
1222 | .name = "wan", | 1341 | .name = "wan", |
1223 | .read = wan_read, | 1342 | .read = wan_read, |
1224 | .write = wan_write, | 1343 | .write = wan_write, |
1344 | .exit = wan_exit, | ||
1225 | .flags.experimental = 1, | 1345 | .flags.experimental = 1, |
1226 | }; | 1346 | }; |
1227 | 1347 | ||
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h index 7615adb381c8..a6c285585863 100644 --- a/drivers/misc/thinkpad_acpi.h +++ b/drivers/misc/thinkpad_acpi.h | |||
@@ -278,6 +278,8 @@ static int beep_write(char *buf); | |||
278 | * Bluetooth subdriver | 278 | * Bluetooth subdriver |
279 | */ | 279 | */ |
280 | 280 | ||
281 | #define TPACPI_BLUETH_SYSFS_GROUP "bluetooth" | ||
282 | |||
281 | enum { | 283 | enum { |
282 | /* ACPI GBDC/SBDC bits */ | 284 | /* ACPI GBDC/SBDC bits */ |
283 | TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */ | 285 | TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */ |
@@ -551,6 +553,8 @@ static int volume_write(char *buf); | |||
551 | * Wan subdriver | 553 | * Wan subdriver |
552 | */ | 554 | */ |
553 | 555 | ||
556 | #define TPACPI_WAN_SYSFS_GROUP "wwan" | ||
557 | |||
554 | enum { | 558 | enum { |
555 | /* ACPI GWAN/SWAN bits */ | 559 | /* ACPI GWAN/SWAN bits */ |
556 | TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */ | 560 | TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */ |