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 .drv.pm = &toshiba_bt_pm, 63 }; 64 65 static int toshiba_bluetooth_present(acpi_handle handle) 66 { 67 acpi_status result; 68 u64 bt_present; 69 70 /* 71 * Some Toshiba laptops may have a fake TOS6205 device in 72 * their ACPI BIOS, so query the _STA method to see if there 73 * is really anything there. 74 */ 75 result = acpi_evaluate_integer(handle, "_STA", NULL, &bt_present); 76 if (ACPI_FAILURE(result)) { 77 pr_err("ACPI call to query Bluetooth presence failed\n"); 78 return -ENXIO; 79 } 80 81 if (!bt_present) { 82 pr_info("Bluetooth device not present\n"); 83 return -ENODEV; 84 } 85 86 return 0; 87 } 88 89 static int toshiba_bluetooth_status(acpi_handle handle) 90 { 91 acpi_status result; 92 u64 status; 93 94 result = acpi_evaluate_integer(handle, "BTST", NULL, &status); 95 if (ACPI_FAILURE(result)) { 96 pr_err("Could not get Bluetooth device status\n"); 97 return -ENXIO; 98 } 99 100 return status; 101 } 102 103 static int toshiba_bluetooth_enable(acpi_handle handle) 104 { 105 acpi_status result; 106 107 result = acpi_evaluate_object(handle, "AUSB", NULL, NULL); 108 if (ACPI_FAILURE(result)) { 109 pr_err("Could not attach USB Bluetooth device\n"); 110 return -ENXIO; 111 } 112 113 result = acpi_evaluate_object(handle, "BTPO", NULL, NULL); 114 if (ACPI_FAILURE(result)) { 115 pr_err("Could not power ON Bluetooth device\n"); 116 return -ENXIO; 117 } 118 119 return 0; 120 } 121 122 static int toshiba_bluetooth_disable(acpi_handle handle) 123 { 124 acpi_status result; 125 126 result = acpi_evaluate_object(handle, "BTPF", NULL, NULL); 127 if (ACPI_FAILURE(result)) { 128 pr_err("Could not power OFF Bluetooth device\n"); 129 return -ENXIO; 130 } 131 132 result = acpi_evaluate_object(handle, "DUSB", NULL, NULL); 133 if (ACPI_FAILURE(result)) { 134 pr_err("Could not detach USB Bluetooth device\n"); 135 return -ENXIO; 136 } 137 138 return 0; 139 } 140 141 /* Helper function */ 142 static int toshiba_bluetooth_sync_status(struct toshiba_bluetooth_dev *bt_dev) 143 { 144 int status; 145 146 status = toshiba_bluetooth_status(bt_dev->acpi_dev->handle); 147 if (status < 0) { 148 pr_err("Could not sync bluetooth device status\n"); 149 return status; 150 } 151 152 bt_dev->killswitch = (status & BT_KILLSWITCH_MASK) ? true : false; 153 bt_dev->plugged = (status & BT_PLUGGED_MASK) ? true : false; 154 bt_dev->powered = (status & BT_POWER_MASK) ? true : false; 155 156 pr_debug("Bluetooth status %d killswitch %d plugged %d powered %d\n", 157 status, bt_dev->killswitch, bt_dev->plugged, bt_dev->powered); 158 159 return 0; 160 } 161 162 /* RFKill handlers */ 163 static int bt_rfkill_set_block(void *data, bool blocked) 164 { 165 struct toshiba_bluetooth_dev *bt_dev = data; 166 int ret; 167 168 ret = toshiba_bluetooth_sync_status(bt_dev); 169 if (ret) 170 return ret; 171 172 if (!bt_dev->killswitch) 173 return 0; 174 175 if (blocked) 176 ret = toshiba_bluetooth_disable(bt_dev->acpi_dev->handle); 177 else 178 ret = toshiba_bluetooth_enable(bt_dev->acpi_dev->handle); 179 180 return ret; 181 } 182 183 static void bt_rfkill_poll(struct rfkill *rfkill, void *data) 184 { 185 struct toshiba_bluetooth_dev *bt_dev = data; 186 187 if (toshiba_bluetooth_sync_status(bt_dev)) 188 return; 189 190 /* 191 * Note the Toshiba Bluetooth RFKill switch seems to be a strange 192 * fish. It only provides a BT event when the switch is flipped to 193 * the 'on' position. When flipping it to 'off', the USB device is 194 * simply pulled away underneath us, without any BT event being 195 * delivered. 196 */ 197 rfkill_set_hw_state(bt_dev->rfk, !bt_dev->killswitch); 198 } 199 200 static const struct rfkill_ops rfk_ops = { 201 .set_block = bt_rfkill_set_block, 202 .poll = bt_rfkill_poll, 203 }; 204 205 /* ACPI driver functions */ 206 static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event) 207 { 208 struct toshiba_bluetooth_dev *bt_dev = acpi_driver_data(device); 209 210 if (toshiba_bluetooth_sync_status(bt_dev)) 211 return; 212 213 rfkill_set_hw_state(bt_dev->rfk, !bt_dev->killswitch); 214 } 215 216 #ifdef CONFIG_PM_SLEEP 217 static int toshiba_bt_resume(struct device *dev) 218 { 219 struct toshiba_bluetooth_dev *bt_dev; 220 int ret; 221 222 bt_dev = acpi_driver_data(to_acpi_device(dev)); 223 224 ret = toshiba_bluetooth_sync_status(bt_dev); 225 if (ret) 226 return ret; 227 228 rfkill_set_hw_state(bt_dev->rfk, !bt_dev->killswitch); 229 230 return 0; 231 } 232 #endif 233 234 static int toshiba_bt_rfkill_add(struct acpi_device *device) 235 { 236 struct toshiba_bluetooth_dev *bt_dev; 237 int result; 238 239 result = toshiba_bluetooth_present(device->handle); 240 if (result) 241 return result; 242 243 pr_info("Toshiba ACPI Bluetooth device driver\n"); 244 245 bt_dev = kzalloc(sizeof(*bt_dev), GFP_KERNEL); 246 if (!bt_dev) 247 return -ENOMEM; 248 bt_dev->acpi_dev = device; 249 device->driver_data = bt_dev; 250 dev_set_drvdata(&device->dev, bt_dev); 251 252 result = toshiba_bluetooth_sync_status(bt_dev); 253 if (result) { 254 kfree(bt_dev); 255 return result; 256 } 257 258 bt_dev->rfk = rfkill_alloc("Toshiba Bluetooth", 259 &device->dev, 260 RFKILL_TYPE_BLUETOOTH, 261 &rfk_ops, 262 bt_dev); 263 if (!bt_dev->rfk) { 264 pr_err("Unable to allocate rfkill device\n"); 265 kfree(bt_dev); 266 return -ENOMEM; 267 } 268 269 rfkill_set_hw_state(bt_dev->rfk, !bt_dev->killswitch); 270 271 result = rfkill_register(bt_dev->rfk); 272 if (result) { 273 pr_err("Unable to register rfkill device\n"); 274 rfkill_destroy(bt_dev->rfk); 275 kfree(bt_dev); 276 } 277 278 return result; 279 } 280 281 static void toshiba_bt_rfkill_remove(struct acpi_device *device) 282 { 283 struct toshiba_bluetooth_dev *bt_dev = acpi_driver_data(device); 284 285 /* clean up */ 286 if (bt_dev->rfk) { 287 rfkill_unregister(bt_dev->rfk); 288 rfkill_destroy(bt_dev->rfk); 289 } 290 291 kfree(bt_dev); 292 293 toshiba_bluetooth_disable(device->handle); 294 } 295 296 module_acpi_driver(toshiba_bt_rfkill_driver); 297