Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Toshiba Bluetooth Enable Driver
0004  *
0005  * Copyright (C) 2009 Jes Sorensen <Jes.Sorensen@gmail.com>
0006  * Copyright (C) 2015 Azael Avalos <coproscefalo@gmail.com>
0007  *
0008  * Thanks to Matthew Garrett for background info on ACPI innards which
0009  * normal people aren't meant to understand :-)
0010  */
0011 
0012 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0013 
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/init.h>
0017 #include <linux/types.h>
0018 #include <linux/acpi.h>
0019 #include <linux/rfkill.h>
0020 
0021 #define BT_KILLSWITCH_MASK  0x01
0022 #define BT_PLUGGED_MASK     0x40
0023 #define BT_POWER_MASK       0x80
0024 
0025 MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@gmail.com>");
0026 MODULE_DESCRIPTION("Toshiba Laptop ACPI Bluetooth Enable Driver");
0027 MODULE_LICENSE("GPL");
0028 
0029 struct toshiba_bluetooth_dev {
0030     struct acpi_device *acpi_dev;
0031     struct rfkill *rfk;
0032 
0033     bool killswitch;
0034     bool plugged;
0035     bool powered;
0036 };
0037 
0038 static int toshiba_bt_rfkill_add(struct acpi_device *device);
0039 static int toshiba_bt_rfkill_remove(struct acpi_device *device);
0040 static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event);
0041 
0042 static const struct acpi_device_id bt_device_ids[] = {
0043     { "TOS6205", 0},
0044     { "", 0},
0045 };
0046 MODULE_DEVICE_TABLE(acpi, bt_device_ids);
0047 
0048 #ifdef CONFIG_PM_SLEEP
0049 static int toshiba_bt_resume(struct device *dev);
0050 #endif
0051 static SIMPLE_DEV_PM_OPS(toshiba_bt_pm, NULL, toshiba_bt_resume);
0052 
0053 static struct acpi_driver toshiba_bt_rfkill_driver = {
0054     .name =     "Toshiba BT",
0055     .class =    "Toshiba",
0056     .ids =      bt_device_ids,
0057     .ops =      {
0058                 .add =      toshiba_bt_rfkill_add,
0059                 .remove =   toshiba_bt_rfkill_remove,
0060                 .notify =   toshiba_bt_rfkill_notify,
0061             },
0062     .owner =    THIS_MODULE,
0063     .drv.pm =   &toshiba_bt_pm,
0064 };
0065 
0066 static int toshiba_bluetooth_present(acpi_handle handle)
0067 {
0068     acpi_status result;
0069     u64 bt_present;
0070 
0071     /*
0072      * Some Toshiba laptops may have a fake TOS6205 device in
0073      * their ACPI BIOS, so query the _STA method to see if there
0074      * is really anything there.
0075      */
0076     result = acpi_evaluate_integer(handle, "_STA", NULL, &bt_present);
0077     if (ACPI_FAILURE(result)) {
0078         pr_err("ACPI call to query Bluetooth presence failed\n");
0079         return -ENXIO;
0080     }
0081 
0082     if (!bt_present) {
0083         pr_info("Bluetooth device not present\n");
0084         return -ENODEV;
0085     }
0086 
0087     return 0;
0088 }
0089 
0090 static int toshiba_bluetooth_status(acpi_handle handle)
0091 {
0092     acpi_status result;
0093     u64 status;
0094 
0095     result = acpi_evaluate_integer(handle, "BTST", NULL, &status);
0096     if (ACPI_FAILURE(result)) {
0097         pr_err("Could not get Bluetooth device status\n");
0098         return -ENXIO;
0099     }
0100 
0101     return status;
0102 }
0103 
0104 static int toshiba_bluetooth_enable(acpi_handle handle)
0105 {
0106     acpi_status result;
0107 
0108     result = acpi_evaluate_object(handle, "AUSB", NULL, NULL);
0109     if (ACPI_FAILURE(result)) {
0110         pr_err("Could not attach USB Bluetooth device\n");
0111         return -ENXIO;
0112     }
0113 
0114     result = acpi_evaluate_object(handle, "BTPO", NULL, NULL);
0115     if (ACPI_FAILURE(result)) {
0116         pr_err("Could not power ON Bluetooth device\n");
0117         return -ENXIO;
0118     }
0119 
0120     return 0;
0121 }
0122 
0123 static int toshiba_bluetooth_disable(acpi_handle handle)
0124 {
0125     acpi_status result;
0126 
0127     result = acpi_evaluate_object(handle, "BTPF", NULL, NULL);
0128     if (ACPI_FAILURE(result)) {
0129         pr_err("Could not power OFF Bluetooth device\n");
0130         return -ENXIO;
0131     }
0132 
0133     result = acpi_evaluate_object(handle, "DUSB", NULL, NULL);
0134     if (ACPI_FAILURE(result)) {
0135         pr_err("Could not detach USB Bluetooth device\n");
0136         return -ENXIO;
0137     }
0138 
0139     return 0;
0140 }
0141 
0142 /* Helper function */
0143 static int toshiba_bluetooth_sync_status(struct toshiba_bluetooth_dev *bt_dev)
0144 {
0145     int status;
0146 
0147     status = toshiba_bluetooth_status(bt_dev->acpi_dev->handle);
0148     if (status < 0) {
0149         pr_err("Could not sync bluetooth device status\n");
0150         return status;
0151     }
0152 
0153     bt_dev->killswitch = (status & BT_KILLSWITCH_MASK) ? true : false;
0154     bt_dev->plugged = (status & BT_PLUGGED_MASK) ? true : false;
0155     bt_dev->powered = (status & BT_POWER_MASK) ? true : false;
0156 
0157     pr_debug("Bluetooth status %d killswitch %d plugged %d powered %d\n",
0158          status, bt_dev->killswitch, bt_dev->plugged, bt_dev->powered);
0159 
0160     return 0;
0161 }
0162 
0163 /* RFKill handlers */
0164 static int bt_rfkill_set_block(void *data, bool blocked)
0165 {
0166     struct toshiba_bluetooth_dev *bt_dev = data;
0167     int ret;
0168 
0169     ret = toshiba_bluetooth_sync_status(bt_dev);
0170     if (ret)
0171         return ret;
0172 
0173     if (!bt_dev->killswitch)
0174         return 0;
0175 
0176     if (blocked)
0177         ret = toshiba_bluetooth_disable(bt_dev->acpi_dev->handle);
0178     else
0179         ret = toshiba_bluetooth_enable(bt_dev->acpi_dev->handle);
0180 
0181     return ret;
0182 }
0183 
0184 static void bt_rfkill_poll(struct rfkill *rfkill, void *data)
0185 {
0186     struct toshiba_bluetooth_dev *bt_dev = data;
0187 
0188     if (toshiba_bluetooth_sync_status(bt_dev))
0189         return;
0190 
0191     /*
0192      * Note the Toshiba Bluetooth RFKill switch seems to be a strange
0193      * fish. It only provides a BT event when the switch is flipped to
0194      * the 'on' position. When flipping it to 'off', the USB device is
0195      * simply pulled away underneath us, without any BT event being
0196      * delivered.
0197      */
0198     rfkill_set_hw_state(bt_dev->rfk, !bt_dev->killswitch);
0199 }
0200 
0201 static const struct rfkill_ops rfk_ops = {
0202     .set_block = bt_rfkill_set_block,
0203     .poll = bt_rfkill_poll,
0204 };
0205 
0206 /* ACPI driver functions */
0207 static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event)
0208 {
0209     struct toshiba_bluetooth_dev *bt_dev = acpi_driver_data(device);
0210 
0211     if (toshiba_bluetooth_sync_status(bt_dev))
0212         return;
0213 
0214     rfkill_set_hw_state(bt_dev->rfk, !bt_dev->killswitch);
0215 }
0216 
0217 #ifdef CONFIG_PM_SLEEP
0218 static int toshiba_bt_resume(struct device *dev)
0219 {
0220     struct toshiba_bluetooth_dev *bt_dev;
0221     int ret;
0222 
0223     bt_dev = acpi_driver_data(to_acpi_device(dev));
0224 
0225     ret = toshiba_bluetooth_sync_status(bt_dev);
0226     if (ret)
0227         return ret;
0228 
0229     rfkill_set_hw_state(bt_dev->rfk, !bt_dev->killswitch);
0230 
0231     return 0;
0232 }
0233 #endif
0234 
0235 static int toshiba_bt_rfkill_add(struct acpi_device *device)
0236 {
0237     struct toshiba_bluetooth_dev *bt_dev;
0238     int result;
0239 
0240     result = toshiba_bluetooth_present(device->handle);
0241     if (result)
0242         return result;
0243 
0244     pr_info("Toshiba ACPI Bluetooth device driver\n");
0245 
0246     bt_dev = kzalloc(sizeof(*bt_dev), GFP_KERNEL);
0247     if (!bt_dev)
0248         return -ENOMEM;
0249     bt_dev->acpi_dev = device;
0250     device->driver_data = bt_dev;
0251     dev_set_drvdata(&device->dev, bt_dev);
0252 
0253     result = toshiba_bluetooth_sync_status(bt_dev);
0254     if (result) {
0255         kfree(bt_dev);
0256         return result;
0257     }
0258 
0259     bt_dev->rfk = rfkill_alloc("Toshiba Bluetooth",
0260                    &device->dev,
0261                    RFKILL_TYPE_BLUETOOTH,
0262                    &rfk_ops,
0263                    bt_dev);
0264     if (!bt_dev->rfk) {
0265         pr_err("Unable to allocate rfkill device\n");
0266         kfree(bt_dev);
0267         return -ENOMEM;
0268     }
0269 
0270     rfkill_set_hw_state(bt_dev->rfk, !bt_dev->killswitch);
0271 
0272     result = rfkill_register(bt_dev->rfk);
0273     if (result) {
0274         pr_err("Unable to register rfkill device\n");
0275         rfkill_destroy(bt_dev->rfk);
0276         kfree(bt_dev);
0277     }
0278 
0279     return result;
0280 }
0281 
0282 static int toshiba_bt_rfkill_remove(struct acpi_device *device)
0283 {
0284     struct toshiba_bluetooth_dev *bt_dev = acpi_driver_data(device);
0285 
0286     /* clean up */
0287     if (bt_dev->rfk) {
0288         rfkill_unregister(bt_dev->rfk);
0289         rfkill_destroy(bt_dev->rfk);
0290     }
0291 
0292     kfree(bt_dev);
0293 
0294     return toshiba_bluetooth_disable(device->handle);
0295 }
0296 
0297 module_acpi_driver(toshiba_bt_rfkill_driver);