summaryrefslogtreecommitdiff
path: root/drivers/bluetooth/btusb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/btusb.c')
-rw-r--r--drivers/bluetooth/btusb.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 3d62f17111cb..c3eaaa35185b 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -2489,11 +2489,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;
@@ -2508,7 +2506,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_ERR("%s: Failed to access otp area (%d)", hdev->name, err);
+ dev_err(&udev->dev, "Failed to access otp area (%d)", err);
goto done;
}
@@ -2664,20 +2662,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];
@@ -2688,7 +2704,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;
@@ -2834,7 +2850,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;
}
@@ -2981,6 +2998,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);