1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Toshiba Bluetooth Enable Driver 4 * 5 * Copyright (C) 2009 Jes Sorensen <Jes.Sorensen@gmail.com> 6 * Copyright (C) 2015 Azael Avalos <coproscefalo@gmail.com> 7 * 8 * Thanks to Matthew Garrett for background info on ACPI innards which 9 * normal people aren't meant to understand :-) 10 */ 11 12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/init.h> 17 #include <linux/types.h> 18 #include <linux/acpi.h> 19 #include <linux/rfkill.h> 20 21 #define BT_KILLSWITCH_MASK 0x01 22 #define BT_PLUGGED_MASK 0x40 23 #define BT_POWER_MASK 0x80 24 25 MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@gmail.com>"); 26 MODULE_DESCRIPTION("Toshiba Laptop ACPI Bluetooth Enable Driver"); 27 MODULE_LICENSE("GPL"); 28 29 struct toshiba_bluetooth_dev { 30 struct acpi_device *acpi_dev; 31 struct rfkill *rfk; 32 33 bool killswitch; 34 bool plugged; 35 bool powered; 36 }; 37 38 static int toshiba_bt_rfkill_add(struct acpi_device *device); 39 static void toshiba_bt_rfkill_remove(struct acpi_device *device); 40 static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event); 41 42 static const struct acpi_device_id bt_device_ids[] = { 43 { "TOS6205", 0}, 44 { "", 0}, 45 }; 46 MODULE_DEVICE_TABLE(acpi, bt_device_ids); 47 48 #ifdef CONFIG_PM_SLEEP 49 static int toshiba_bt_resume(struct device *dev); 50 #endif 51 static SIMPLE_DEV_PM_OPS(toshiba_bt_pm, NULL, toshiba_bt_resume); 52 53 static struct acpi_driver toshiba_bt_rfkill_driver = { 54 .name = "Toshiba BT", 55 .class = "Toshiba", 56 .ids = bt_device_ids, 57 .ops = { 58 .add = toshiba_bt_rfkill_add, 59 .remove = toshiba_bt_rfkill_remove, 60 .notify = toshiba_bt_rfkill_notify, 61 }, 62 .owner = THIS_MODULE, 63 .drv.pm = &toshiba_bt_pm, 64 }; 65 66 static int toshiba_bluetooth_present(acpi_handle handle) 67 { 68 acpi_status result; 69 u64 bt_present; 70 71 /* 72 * Some Toshiba laptops may have a fake TOS6205 device in 73 * their ACPI BIOS, so query the _STA method to see if there 74 * is really anything there. 75 */ 76 result = acpi_evaluate_integer(handle, "_STA", NULL, &bt_present); 77 if (ACPI_FAILURE(result)) { 78 pr_err("ACPI call to query Bluetooth presence failed\n"); 79 return -ENXIO; 80 } 81 82 if (!bt_present) { 83 pr_info("Bluetooth device not present\n"); 84 return -ENODEV; 85 } 86 87 return 0; 88 } 89 90 static int toshiba_bluetooth_status(acpi_handle handle) 91 { 92 acpi_status result; 93 u64 status; 94 95 result = acpi_evaluate_integer(handle, "BTST", NULL, &status); 96 if (ACPI_FAILURE(result)) { 97 pr_err("Could not get Bluetooth device status\n"); 98 return -ENXIO; 99 } 100 101 return status; 102 } 103 104 static int toshiba_bluetooth_enable(acpi_handle handle) 105 { 106 acpi_status result; 107 108 result = acpi_evaluate_object(handle, "AUSB", NULL, NULL); 109 if (ACPI_FAILURE(result)) { 110 pr_err("Could not attach USB Bluetooth device\n"); 111 return -ENXIO; 112 } 113 114 result = acpi_evaluate_object(handle, "BTPO", NULL, NULL); 115 if (ACPI_FAILURE(result)) { 116 pr_err("Could not power ON Bluetooth device\n"); 117 return -ENXIO; 118 } 119 120 return 0; 121 } 122 123 static int toshiba_bluetooth_disable(acpi_handle handle) 124 { 125 acpi_status result; 126 127 result = acpi_evaluate_object(handle, "BTPF", NULL, NULL); 128 if (ACPI_FAILURE(result)) { 129 pr_err("Could not power OFF Bluetooth device\n"); 130 return -ENXIO; 131 } 132 133 result = acpi_evaluate_object(handle, "DUSB", NULL, NULL); 134 if (ACPI_FAILURE(result)) { 135 pr_err("Could not detach USB Bluetooth device\n"); 136 return -ENXIO; 137 } 138 139 return 0; 140 } 141 142 /* Helper function */ 143 static int toshiba_bluetooth_sync_status(struct toshiba_bluetooth_dev *bt_dev) 144 { 145 int status; 146 147 status = toshiba_bluetooth_status(bt_dev->acpi_dev->handle); 148 if (status < 0) { 149 pr_err("Could not sync bluetooth device status\n"); 150 return status; 151 } 152 153 bt_dev->killswitch = (status & BT_KILLSWITCH_MASK) ? true : false; 154 bt_dev->plugged = (status & BT_PLUGGED_MASK) ? true : false; 155 bt_dev->powered = (status & BT_POWER_MASK) ? true : false; 156 157 pr_debug("Bluetooth status %d killswitch %d plugged %d powered %d\n", 158 status, bt_dev->killswitch, bt_dev->plugged, bt_dev->powered); 159 160 return 0; 161 } 162 163 /* RFKill handlers */ 164 static int bt_rfkill_set_block(void *data, bool blocked) 165 { 166 struct toshiba_bluetooth_dev *bt_dev = data; 167 int ret; 168 169 ret = toshiba_bluetooth_sync_status(bt_dev); 170 if (ret) 171 return ret; 172 173 if (!bt_dev->killswitch) 174 return 0; 175 176 if (blocked) 177 ret = toshiba_bluetooth_disable(bt_dev->acpi_dev->handle); 178 else 179 ret = toshiba_bluetooth_enable(bt_dev->acpi_dev->handle); 180 181 return ret; 182 } 183 184 static void bt_rfkill_poll(struct rfkill *rfkill, void *data) 185 { 186 struct toshiba_bluetooth_dev *bt_dev = data; 187 188 if (toshiba_bluetooth_sync_status(bt_dev)) 189 return; 190 191 /* 192 * Note the Toshiba Bluetooth RFKill switch seems to be a strange 193 * fish. It only provides a BT event when the switch is flipped to 194 * the 'on' position. When flipping it to 'off', the USB device is 195 * simply pulled away underneath us, without any BT event being 196 * delivered. 197 */ 198 rfkill_set_hw_state(bt_dev->rfk, !bt_dev->killswitch); 199 } 200 201 static const struct rfkill_ops rfk_ops = { 202 .set_block = bt_rfkill_set_block, 203 .poll = bt_rfkill_poll, 204 }; 205 206 /* ACPI driver functions */ 207 static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event) 208 { 209 struct toshiba_bluetooth_dev *bt_dev = acpi_driver_data(device); 210 211 if (toshiba_bluetooth_sync_status(bt_dev)) 212 return; 213 214 rfkill_set_hw_state(bt_dev->rfk, !bt_dev->killswitch); 215 } 216 217 #ifdef CONFIG_PM_SLEEP 218 static int toshiba_bt_resume(struct device *dev) 219 { 220 struct toshiba_bluetooth_dev *bt_dev; 221 int ret; 222 223 bt_dev = acpi_driver_data(to_acpi_device(dev)); 224 225 ret = toshiba_bluetooth_sync_status(bt_dev); 226 if (ret) 227 return ret; 228 229 rfkill_set_hw_state(bt_dev->rfk, !bt_dev->killswitch); 230 231 return 0; 232 } 233 #endif 234 235 static int toshiba_bt_rfkill_add(struct acpi_device *device) 236 { 237 struct toshiba_bluetooth_dev *bt_dev; 238 int result; 239 240 result = toshiba_bluetooth_present(device->handle); 241 if (result) 242 return result; 243 244 pr_info("Toshiba ACPI Bluetooth device driver\n"); 245 246 bt_dev = kzalloc(sizeof(*bt_dev), GFP_KERNEL); 247 if (!bt_dev) 248 return -ENOMEM; 249 bt_dev->acpi_dev = device; 250 device->driver_data = bt_dev; 251 dev_set_drvdata(&device->dev, bt_dev); 252 253 result = toshiba_bluetooth_sync_status(bt_dev); 254 if (result) { 255 kfree(bt_dev); 256 return result; 257 } 258 259 bt_dev->rfk = rfkill_alloc("Toshiba Bluetooth", 260 &device->dev, 261 RFKILL_TYPE_BLUETOOTH, 262 &rfk_ops, 263 bt_dev); 264 if (!bt_dev->rfk) { 265 pr_err("Unable to allocate rfkill device\n"); 266 kfree(bt_dev); 267 return -ENOMEM; 268 } 269 270 rfkill_set_hw_state(bt_dev->rfk, !bt_dev->killswitch); 271 272 result = rfkill_register(bt_dev->rfk); 273 if (result) { 274 pr_err("Unable to register rfkill device\n"); 275 rfkill_destroy(bt_dev->rfk); 276 kfree(bt_dev); 277 } 278 279 return result; 280 } 281 282 static void toshiba_bt_rfkill_remove(struct acpi_device *device) 283 { 284 struct toshiba_bluetooth_dev *bt_dev = acpi_driver_data(device); 285 286 /* clean up */ 287 if (bt_dev->rfk) { 288 rfkill_unregister(bt_dev->rfk); 289 rfkill_destroy(bt_dev->rfk); 290 } 291 292 kfree(bt_dev); 293 294 toshiba_bluetooth_disable(device->handle); 295 } 296 297 module_acpi_driver(toshiba_bt_rfkill_driver); 298