|
@@ -51,6 +51,7 @@
|
|
|
#include <linux/dmi.h>
|
|
|
#include <linux/uaccess.h>
|
|
|
#include <linux/miscdevice.h>
|
|
|
+#include <linux/rfkill.h>
|
|
|
#include <linux/toshiba.h>
|
|
|
#include <acpi/video.h>
|
|
|
|
|
@@ -174,6 +175,7 @@ struct toshiba_acpi_dev {
|
|
|
struct led_classdev kbd_led;
|
|
|
struct led_classdev eco_led;
|
|
|
struct miscdevice miscdev;
|
|
|
+ struct rfkill *wwan_rfk;
|
|
|
|
|
|
int force_fan;
|
|
|
int last_key_event;
|
|
@@ -2346,6 +2348,67 @@ static const struct file_operations toshiba_acpi_fops = {
|
|
|
.llseek = noop_llseek,
|
|
|
};
|
|
|
|
|
|
+/*
|
|
|
+ * WWAN RFKill handlers
|
|
|
+ */
|
|
|
+static int toshiba_acpi_wwan_set_block(void *data, bool blocked)
|
|
|
+{
|
|
|
+ struct toshiba_acpi_dev *dev = data;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ ret = toshiba_wireless_status(dev);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ if (!dev->killswitch)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ return toshiba_wwan_set(dev, !blocked);
|
|
|
+}
|
|
|
+
|
|
|
+static void toshiba_acpi_wwan_poll(struct rfkill *rfkill, void *data)
|
|
|
+{
|
|
|
+ struct toshiba_acpi_dev *dev = data;
|
|
|
+
|
|
|
+ if (toshiba_wireless_status(dev))
|
|
|
+ return;
|
|
|
+
|
|
|
+ rfkill_set_hw_state(dev->wwan_rfk, !dev->killswitch);
|
|
|
+}
|
|
|
+
|
|
|
+static const struct rfkill_ops wwan_rfk_ops = {
|
|
|
+ .set_block = toshiba_acpi_wwan_set_block,
|
|
|
+ .poll = toshiba_acpi_wwan_poll,
|
|
|
+};
|
|
|
+
|
|
|
+static int toshiba_acpi_setup_wwan_rfkill(struct toshiba_acpi_dev *dev)
|
|
|
+{
|
|
|
+ int ret = toshiba_wireless_status(dev);
|
|
|
+
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ dev->wwan_rfk = rfkill_alloc("Toshiba WWAN",
|
|
|
+ &dev->acpi_dev->dev,
|
|
|
+ RFKILL_TYPE_WWAN,
|
|
|
+ &wwan_rfk_ops,
|
|
|
+ dev);
|
|
|
+ if (!dev->wwan_rfk) {
|
|
|
+ pr_err("Unable to allocate WWAN rfkill device\n");
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ rfkill_set_hw_state(dev->wwan_rfk, !dev->killswitch);
|
|
|
+
|
|
|
+ ret = rfkill_register(dev->wwan_rfk);
|
|
|
+ if (ret) {
|
|
|
+ pr_err("Unable to register WWAN rfkill device\n");
|
|
|
+ rfkill_destroy(dev->wwan_rfk);
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Hotkeys
|
|
|
*/
|
|
@@ -2713,6 +2776,11 @@ static int toshiba_acpi_remove(struct acpi_device *acpi_dev)
|
|
|
if (dev->eco_led_registered)
|
|
|
led_classdev_unregister(&dev->eco_led);
|
|
|
|
|
|
+ if (dev->wwan_rfk) {
|
|
|
+ rfkill_unregister(dev->wwan_rfk);
|
|
|
+ rfkill_destroy(dev->wwan_rfk);
|
|
|
+ }
|
|
|
+
|
|
|
if (toshiba_acpi)
|
|
|
toshiba_acpi = NULL;
|
|
|
|
|
@@ -2852,6 +2920,8 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
|
|
|
dev->fan_supported = !ret;
|
|
|
|
|
|
toshiba_wwan_available(dev);
|
|
|
+ if (dev->wwan_supported)
|
|
|
+ toshiba_acpi_setup_wwan_rfkill(dev);
|
|
|
|
|
|
print_supported_features(dev);
|
|
|
|
|
@@ -2950,12 +3020,15 @@ static int toshiba_acpi_resume(struct device *device)
|
|
|
struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device));
|
|
|
|
|
|
if (dev->hotkey_dev) {
|
|
|
- int error = toshiba_acpi_enable_hotkeys(dev);
|
|
|
-
|
|
|
- if (error)
|
|
|
+ if (toshiba_acpi_enable_hotkeys(dev))
|
|
|
pr_info("Unable to re-enable hotkeys\n");
|
|
|
}
|
|
|
|
|
|
+ if (dev->wwan_rfk) {
|
|
|
+ if (!toshiba_wireless_status(dev))
|
|
|
+ rfkill_set_hw_state(dev->wwan_rfk, !dev->killswitch);
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
#endif
|