|
@@ -373,6 +373,9 @@ static const struct usb_device_id blacklist_table[] = {
|
|
|
/* Additional Realtek 8723BU Bluetooth devices */
|
|
|
{ USB_DEVICE(0x7392, 0xa611), .driver_info = BTUSB_REALTEK },
|
|
|
|
|
|
+ /* Additional Realtek 8723DE Bluetooth devices */
|
|
|
+ { USB_DEVICE(0x2ff8, 0xb011), .driver_info = BTUSB_REALTEK },
|
|
|
+
|
|
|
/* Additional Realtek 8821AE Bluetooth devices */
|
|
|
{ USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
|
|
|
{ USB_DEVICE(0x13d3, 0x3414), .driver_info = BTUSB_REALTEK },
|
|
@@ -381,6 +384,7 @@ static const struct usb_device_id blacklist_table[] = {
|
|
|
{ USB_DEVICE(0x13d3, 0x3462), .driver_info = BTUSB_REALTEK },
|
|
|
|
|
|
/* Additional Realtek 8822BE Bluetooth devices */
|
|
|
+ { USB_DEVICE(0x13d3, 0x3526), .driver_info = BTUSB_REALTEK },
|
|
|
{ USB_DEVICE(0x0b05, 0x185c), .driver_info = BTUSB_REALTEK },
|
|
|
|
|
|
/* Silicon Wave based devices */
|
|
@@ -408,6 +412,13 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = {
|
|
|
DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9360"),
|
|
|
},
|
|
|
},
|
|
|
+ {
|
|
|
+ /* Dell Inspiron 5565 (QCA ROME device 0cf3:e009) */
|
|
|
+ .matches = {
|
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
|
|
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5565"),
|
|
|
+ },
|
|
|
+ },
|
|
|
{}
|
|
|
};
|
|
|
|
|
@@ -2499,11 +2510,9 @@ static const struct qca_device_info qca_devices_table[] = {
|
|
|
{ 0x00000302, 28, 4, 18 }, /* Rome 3.2 */
|
|
|
};
|
|
|
|
|
|
-static int btusb_qca_send_vendor_req(struct hci_dev *hdev, u8 request,
|
|
|
+static int btusb_qca_send_vendor_req(struct usb_device *udev, u8 request,
|
|
|
void *data, u16 size)
|
|
|
{
|
|
|
- struct btusb_data *btdata = hci_get_drvdata(hdev);
|
|
|
- struct usb_device *udev = btdata->udev;
|
|
|
int pipe, err;
|
|
|
u8 *buf;
|
|
|
|
|
@@ -2518,7 +2527,7 @@ static int btusb_qca_send_vendor_req(struct hci_dev *hdev, u8 request,
|
|
|
err = usb_control_msg(udev, pipe, request, USB_TYPE_VENDOR | USB_DIR_IN,
|
|
|
0, 0, buf, size, USB_CTRL_SET_TIMEOUT);
|
|
|
if (err < 0) {
|
|
|
- bt_dev_err(hdev, "Failed to access otp area (%d)", err);
|
|
|
+ dev_err(&udev->dev, "Failed to access otp area (%d)", err);
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
@@ -2668,20 +2677,38 @@ static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/* identify the ROM version and check whether patches are needed */
|
|
|
+static bool btusb_qca_need_patch(struct usb_device *udev)
|
|
|
+{
|
|
|
+ struct qca_version ver;
|
|
|
+
|
|
|
+ if (btusb_qca_send_vendor_req(udev, QCA_GET_TARGET_VERSION, &ver,
|
|
|
+ sizeof(ver)) < 0)
|
|
|
+ return false;
|
|
|
+ /* only low ROM versions need patches */
|
|
|
+ return !(le32_to_cpu(ver.rom_version) & ~0xffffU);
|
|
|
+}
|
|
|
+
|
|
|
static int btusb_setup_qca(struct hci_dev *hdev)
|
|
|
{
|
|
|
+ struct btusb_data *btdata = hci_get_drvdata(hdev);
|
|
|
+ struct usb_device *udev = btdata->udev;
|
|
|
const struct qca_device_info *info = NULL;
|
|
|
struct qca_version ver;
|
|
|
u32 ver_rom;
|
|
|
u8 status;
|
|
|
int i, err;
|
|
|
|
|
|
- err = btusb_qca_send_vendor_req(hdev, QCA_GET_TARGET_VERSION, &ver,
|
|
|
+ err = btusb_qca_send_vendor_req(udev, QCA_GET_TARGET_VERSION, &ver,
|
|
|
sizeof(ver));
|
|
|
if (err < 0)
|
|
|
return err;
|
|
|
|
|
|
ver_rom = le32_to_cpu(ver.rom_version);
|
|
|
+ /* Don't care about high ROM versions */
|
|
|
+ if (ver_rom & ~0xffffU)
|
|
|
+ return 0;
|
|
|
+
|
|
|
for (i = 0; i < ARRAY_SIZE(qca_devices_table); i++) {
|
|
|
if (ver_rom == qca_devices_table[i].rom_version)
|
|
|
info = &qca_devices_table[i];
|
|
@@ -2691,7 +2718,7 @@ static int btusb_setup_qca(struct hci_dev *hdev)
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
- err = btusb_qca_send_vendor_req(hdev, QCA_CHECK_STATUS, &status,
|
|
|
+ err = btusb_qca_send_vendor_req(udev, QCA_CHECK_STATUS, &status,
|
|
|
sizeof(status));
|
|
|
if (err < 0)
|
|
|
return err;
|
|
@@ -2905,7 +2932,8 @@ static int btusb_probe(struct usb_interface *intf,
|
|
|
/* Old firmware would otherwise let ath3k driver load
|
|
|
* patch and sysconfig files
|
|
|
*/
|
|
|
- if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001)
|
|
|
+ if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001 &&
|
|
|
+ !btusb_qca_need_patch(udev))
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
@@ -3067,6 +3095,7 @@ static int btusb_probe(struct usb_interface *intf,
|
|
|
}
|
|
|
|
|
|
if (id->driver_info & BTUSB_ATH3012) {
|
|
|
+ data->setup_on_usb = btusb_setup_qca;
|
|
|
hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
|
|
|
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
|
|
|
set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
|