diff options
-rw-r--r-- | drivers/platform/x86/toshiba_acpi.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 4f722aa0c7b3..3884bdd1e9fe 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -114,6 +114,7 @@ MODULE_LICENSE("GPL"); | |||
114 | #define HCI_VIDEO_OUT 0x001c | 114 | #define HCI_VIDEO_OUT 0x001c |
115 | #define HCI_HOTKEY_EVENT 0x001e | 115 | #define HCI_HOTKEY_EVENT 0x001e |
116 | #define HCI_LCD_BRIGHTNESS 0x002a | 116 | #define HCI_LCD_BRIGHTNESS 0x002a |
117 | #define HCI_WIRELESS 0x0056 | ||
117 | #define HCI_ACCELEROMETER 0x006d | 118 | #define HCI_ACCELEROMETER 0x006d |
118 | #define HCI_KBD_ILLUMINATION 0x0095 | 119 | #define HCI_KBD_ILLUMINATION 0x0095 |
119 | #define HCI_ECO_MODE 0x0097 | 120 | #define HCI_ECO_MODE 0x0097 |
@@ -148,6 +149,10 @@ MODULE_LICENSE("GPL"); | |||
148 | #define SCI_KBD_MODE_ON 0x8 | 149 | #define SCI_KBD_MODE_ON 0x8 |
149 | #define SCI_KBD_MODE_OFF 0x10 | 150 | #define SCI_KBD_MODE_OFF 0x10 |
150 | #define SCI_KBD_TIME_MAX 0x3c001a | 151 | #define SCI_KBD_TIME_MAX 0x3c001a |
152 | #define HCI_WIRELESS_STATUS 0x1 | ||
153 | #define HCI_WIRELESS_WWAN 0x3 | ||
154 | #define HCI_WIRELESS_WWAN_STATUS 0x2000 | ||
155 | #define HCI_WIRELESS_WWAN_POWER 0x4000 | ||
151 | #define SCI_USB_CHARGE_MODE_MASK 0xff | 156 | #define SCI_USB_CHARGE_MODE_MASK 0xff |
152 | #define SCI_USB_CHARGE_DISABLED 0x00 | 157 | #define SCI_USB_CHARGE_DISABLED 0x00 |
153 | #define SCI_USB_CHARGE_ALTERNATE 0x09 | 158 | #define SCI_USB_CHARGE_ALTERNATE 0x09 |
@@ -197,12 +202,14 @@ struct toshiba_acpi_dev { | |||
197 | unsigned int kbd_function_keys_supported:1; | 202 | unsigned int kbd_function_keys_supported:1; |
198 | unsigned int panel_power_on_supported:1; | 203 | unsigned int panel_power_on_supported:1; |
199 | unsigned int usb_three_supported:1; | 204 | unsigned int usb_three_supported:1; |
205 | unsigned int wwan_supported:1; | ||
200 | unsigned int sysfs_created:1; | 206 | unsigned int sysfs_created:1; |
201 | unsigned int special_functions; | 207 | unsigned int special_functions; |
202 | 208 | ||
203 | bool kbd_led_registered; | 209 | bool kbd_led_registered; |
204 | bool illumination_led_registered; | 210 | bool illumination_led_registered; |
205 | bool eco_led_registered; | 211 | bool eco_led_registered; |
212 | bool killswitch; | ||
206 | }; | 213 | }; |
207 | 214 | ||
208 | static struct toshiba_acpi_dev *toshiba_acpi; | 215 | static struct toshiba_acpi_dev *toshiba_acpi; |
@@ -1085,6 +1092,104 @@ static int toshiba_hotkey_event_type_get(struct toshiba_acpi_dev *dev, | |||
1085 | return -EIO; | 1092 | return -EIO; |
1086 | } | 1093 | } |
1087 | 1094 | ||
1095 | /* Wireless status (RFKill, WLAN, BT, WWAN) */ | ||
1096 | static int toshiba_wireless_status(struct toshiba_acpi_dev *dev) | ||
1097 | { | ||
1098 | u32 in[TCI_WORDS] = { HCI_GET, HCI_WIRELESS, 0, 0, 0, 0 }; | ||
1099 | u32 out[TCI_WORDS]; | ||
1100 | acpi_status status; | ||
1101 | |||
1102 | in[3] = HCI_WIRELESS_STATUS; | ||
1103 | status = tci_raw(dev, in, out); | ||
1104 | |||
1105 | if (ACPI_FAILURE(status)) { | ||
1106 | pr_err("ACPI call to get Wireless status failed\n"); | ||
1107 | return -EIO; | ||
1108 | } | ||
1109 | |||
1110 | if (out[0] == TOS_NOT_SUPPORTED) | ||
1111 | return -ENODEV; | ||
1112 | |||
1113 | if (out[0] != TOS_SUCCESS) | ||
1114 | return -EIO; | ||
1115 | |||
1116 | dev->killswitch = !!(out[2] & HCI_WIRELESS_STATUS); | ||
1117 | |||
1118 | return 0; | ||
1119 | } | ||
1120 | |||
1121 | /* WWAN */ | ||
1122 | static void toshiba_wwan_available(struct toshiba_acpi_dev *dev) | ||
1123 | { | ||
1124 | u32 in[TCI_WORDS] = { HCI_GET, HCI_WIRELESS, 0, 0, 0, 0 }; | ||
1125 | u32 out[TCI_WORDS]; | ||
1126 | acpi_status status; | ||
1127 | |||
1128 | dev->wwan_supported = 0; | ||
1129 | |||
1130 | /* | ||
1131 | * WWAN support can be queried by setting the in[3] value to | ||
1132 | * HCI_WIRELESS_WWAN (0x03). | ||
1133 | * | ||
1134 | * If supported, out[0] contains TOS_SUCCESS and out[2] contains | ||
1135 | * HCI_WIRELESS_WWAN_STATUS (0x2000). | ||
1136 | * | ||
1137 | * If not supported, out[0] contains TOS_INPUT_DATA_ERROR (0x8300) | ||
1138 | * or TOS_NOT_SUPPORTED (0x8000). | ||
1139 | */ | ||
1140 | in[3] = HCI_WIRELESS_WWAN; | ||
1141 | status = tci_raw(dev, in, out); | ||
1142 | |||
1143 | if (ACPI_FAILURE(status)) { | ||
1144 | pr_err("ACPI call to get WWAN status failed\n"); | ||
1145 | return; | ||
1146 | } | ||
1147 | |||
1148 | if (out[0] != TOS_SUCCESS) | ||
1149 | return; | ||
1150 | |||
1151 | dev->wwan_supported = (out[2] == HCI_WIRELESS_WWAN_STATUS); | ||
1152 | } | ||
1153 | |||
1154 | static int toshiba_wwan_set(struct toshiba_acpi_dev *dev, u32 state) | ||
1155 | { | ||
1156 | u32 in[TCI_WORDS] = { HCI_SET, HCI_WIRELESS, state, 0, 0, 0 }; | ||
1157 | u32 out[TCI_WORDS]; | ||
1158 | acpi_status status; | ||
1159 | |||
1160 | in[3] = HCI_WIRELESS_WWAN_STATUS; | ||
1161 | status = tci_raw(dev, in, out); | ||
1162 | |||
1163 | if (ACPI_FAILURE(status)) { | ||
1164 | pr_err("ACPI call to set WWAN status failed\n"); | ||
1165 | return -EIO; | ||
1166 | } | ||
1167 | |||
1168 | if (out[0] == TOS_NOT_SUPPORTED) | ||
1169 | return -ENODEV; | ||
1170 | |||
1171 | if (out[0] != TOS_SUCCESS) | ||
1172 | return -EIO; | ||
1173 | |||
1174 | /* | ||
1175 | * Some devices only need to call HCI_WIRELESS_WWAN_STATUS to | ||
1176 | * (de)activate the device, but some others need the | ||
1177 | * HCI_WIRELESS_WWAN_POWER call as well. | ||
1178 | */ | ||
1179 | in[3] = HCI_WIRELESS_WWAN_POWER; | ||
1180 | status = tci_raw(dev, in, out); | ||
1181 | |||
1182 | if (ACPI_FAILURE(status)) { | ||
1183 | pr_err("ACPI call to set WWAN power failed\n"); | ||
1184 | return -EIO; | ||
1185 | } | ||
1186 | |||
1187 | if (out[0] == TOS_NOT_SUPPORTED) | ||
1188 | return -ENODEV; | ||
1189 | |||
1190 | return out[0] == TOS_SUCCESS ? 0 : -EIO; | ||
1191 | } | ||
1192 | |||
1088 | /* Transflective Backlight */ | 1193 | /* Transflective Backlight */ |
1089 | static int get_tr_backlight_status(struct toshiba_acpi_dev *dev, u32 *status) | 1194 | static int get_tr_backlight_status(struct toshiba_acpi_dev *dev, u32 *status) |
1090 | { | 1195 | { |
@@ -2569,6 +2674,8 @@ static void print_supported_features(struct toshiba_acpi_dev *dev) | |||
2569 | pr_cont(" panel-power-on"); | 2674 | pr_cont(" panel-power-on"); |
2570 | if (dev->usb_three_supported) | 2675 | if (dev->usb_three_supported) |
2571 | pr_cont(" usb3"); | 2676 | pr_cont(" usb3"); |
2677 | if (dev->wwan_supported) | ||
2678 | pr_cont(" wwan"); | ||
2572 | 2679 | ||
2573 | pr_cont("\n"); | 2680 | pr_cont("\n"); |
2574 | } | 2681 | } |
@@ -2744,6 +2851,8 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
2744 | ret = get_fan_status(dev, &dummy); | 2851 | ret = get_fan_status(dev, &dummy); |
2745 | dev->fan_supported = !ret; | 2852 | dev->fan_supported = !ret; |
2746 | 2853 | ||
2854 | toshiba_wwan_available(dev); | ||
2855 | |||
2747 | print_supported_features(dev); | 2856 | print_supported_features(dev); |
2748 | 2857 | ||
2749 | ret = sysfs_create_group(&dev->acpi_dev->dev.kobj, | 2858 | ret = sysfs_create_group(&dev->acpi_dev->dev.kobj, |