]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/bluetooth/btusb.c
Merge remote-tracking branch 'sound-current/for-linus'
[karo-tx-linux.git] / drivers / bluetooth / btusb.c
index 27830da67063be28af0b8cb46ed2e609ee72f965..e33dacf5bd98765178ddac60f7d50d742de555ac 100644 (file)
@@ -60,6 +60,8 @@ static struct usb_driver btusb_driver;
 #define BTUSB_QCA_ROME         0x8000
 #define BTUSB_BCM_APPLE                0x10000
 #define BTUSB_REALTEK          0x20000
+#define BTUSB_BCM2045          0x40000
+#define BTUSB_IFNUM_2          0x80000
 
 static const struct usb_device_id btusb_table[] = {
        /* Generic Bluetooth USB device */
@@ -73,7 +75,7 @@ static const struct usb_device_id btusb_table[] = {
 
        /* Apple-specific (Broadcom) devices */
        { USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01),
-         .driver_info = BTUSB_BCM_APPLE },
+         .driver_info = BTUSB_BCM_APPLE | BTUSB_IFNUM_2 },
 
        /* MediaTek MT76x0E */
        { USB_DEVICE(0x0e8d, 0x763f) },
@@ -124,6 +126,9 @@ static const struct usb_device_id btusb_table[] = {
        /* Broadcom BCM20702B0 (Dynex/Insignia) */
        { USB_DEVICE(0x19ff, 0x0239), .driver_info = BTUSB_BCM_PATCHRAM },
 
+       /* Broadcom BCM43142A0 (Foxconn/Lenovo) */
+       { USB_DEVICE(0x105b, 0xe065), .driver_info = BTUSB_BCM_PATCHRAM },
+
        /* Foxconn - Hon Hai */
        { USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01),
          .driver_info = BTUSB_BCM_PATCHRAM },
@@ -164,6 +169,9 @@ static const struct usb_device_id blacklist_table[] = {
        /* Broadcom BCM2033 without firmware */
        { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE },
 
+       /* Broadcom BCM2045 devices */
+       { USB_DEVICE(0x0a5c, 0x2045), .driver_info = BTUSB_BCM2045 },
+
        /* Atheros 3011 with sflash firmware */
        { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE },
        { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE },
@@ -195,6 +203,7 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
@@ -206,6 +215,7 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x0cf3, 0x311f), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x817b), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
@@ -1691,8 +1701,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
                BT_INFO("%s: Intel device is already patched. patch num: %02x",
                        hdev->name, ver->fw_patch_num);
                kfree_skb(skb);
-               btintel_check_bdaddr(hdev);
-               return 0;
+               goto complete;
        }
 
        /* Opens the firmware patch file based on the firmware version read
@@ -1704,8 +1713,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
        fw = btusb_setup_intel_get_fw(hdev, ver);
        if (!fw) {
                kfree_skb(skb);
-               btintel_check_bdaddr(hdev);
-               return 0;
+               goto complete;
        }
        fw_ptr = fw->data;
 
@@ -1778,8 +1786,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
        BT_INFO("%s: Intel Bluetooth firmware patch completed and activated",
                hdev->name);
 
-       btintel_check_bdaddr(hdev);
-       return 0;
+       goto complete;
 
 exit_mfg_disable:
        /* Disable the manufacturer mode without reset */
@@ -1794,8 +1801,7 @@ exit_mfg_disable:
 
        BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name);
 
-       btintel_check_bdaddr(hdev);
-       return 0;
+       goto complete;
 
 exit_mfg_deactivate:
        release_firmware(fw);
@@ -1815,6 +1821,12 @@ exit_mfg_deactivate:
        BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated",
                hdev->name);
 
+complete:
+       /* Set the event mask for Intel specific vendor events. This enables
+        * a few extra events that are useful during general operation.
+        */
+       btintel_set_event_mask_mfg(hdev, false);
+
        btintel_check_bdaddr(hdev);
        return 0;
 }
@@ -2329,6 +2341,15 @@ done:
         */
        btintel_load_ddc_config(hdev, fwname);
 
+       /* Set the event mask for Intel specific vendor events. This enables
+        * a few extra events that are useful during general operation. It
+        * does not enable any debugging related events.
+        *
+        * The device will function correctly without these events enabled
+        * and thus no need to fail the setup.
+        */
+       btintel_set_event_mask(hdev, false);
+
        return 0;
 }
 
@@ -2749,13 +2770,20 @@ static int btusb_probe(struct usb_interface *intf,
        struct usb_endpoint_descriptor *ep_desc;
        struct btusb_data *data;
        struct hci_dev *hdev;
+       unsigned ifnum_base;
        int i, err;
 
        BT_DBG("intf %p id %p", intf, id);
 
        /* interface numbers are hardcoded in the spec */
-       if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
-               return -ENODEV;
+       if (intf->cur_altsetting->desc.bInterfaceNumber != 0) {
+               if (!(id->driver_info & BTUSB_IFNUM_2))
+                       return -ENODEV;
+               if (intf->cur_altsetting->desc.bInterfaceNumber != 2)
+                       return -ENODEV;
+       }
+
+       ifnum_base = intf->cur_altsetting->desc.bInterfaceNumber;
 
        if (!id->driver_info) {
                const struct usb_device_id *match;
@@ -2857,43 +2885,53 @@ static int btusb_probe(struct usb_interface *intf,
        hdev->send   = btusb_send_frame;
        hdev->notify = btusb_notify;
 
+       if (id->driver_info & BTUSB_BCM2045)
+               set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
+
        if (id->driver_info & BTUSB_BCM92035)
                hdev->setup = btusb_setup_bcm92035;
 
 #ifdef CONFIG_BT_HCIBTUSB_BCM
        if (id->driver_info & BTUSB_BCM_PATCHRAM) {
+               hdev->manufacturer = 15;
                hdev->setup = btbcm_setup_patchram;
                hdev->set_diag = btusb_bcm_set_diag;
                hdev->set_bdaddr = btbcm_set_bdaddr;
 
                /* Broadcom LM_DIAG Interface numbers are hardcoded */
-               data->diag = usb_ifnum_to_if(data->udev, 2);
+               data->diag = usb_ifnum_to_if(data->udev, ifnum_base + 2);
        }
 
        if (id->driver_info & BTUSB_BCM_APPLE) {
+               hdev->manufacturer = 15;
                hdev->setup = btbcm_setup_apple;
                hdev->set_diag = btusb_bcm_set_diag;
 
                /* Broadcom LM_DIAG Interface numbers are hardcoded */
-               data->diag = usb_ifnum_to_if(data->udev, 2);
+               data->diag = usb_ifnum_to_if(data->udev, ifnum_base + 2);
        }
 #endif
 
        if (id->driver_info & BTUSB_INTEL) {
+               hdev->manufacturer = 2;
                hdev->setup = btusb_setup_intel;
                hdev->shutdown = btusb_shutdown_intel;
+               hdev->set_diag = btintel_set_diag_mfg;
                hdev->set_bdaddr = btintel_set_bdaddr;
                set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
                set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
+               set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks);
        }
 
        if (id->driver_info & BTUSB_INTEL_NEW) {
+               hdev->manufacturer = 2;
                hdev->send = btusb_send_frame_intel;
                hdev->setup = btusb_setup_intel_new;
                hdev->hw_error = btintel_hw_error;
                hdev->set_diag = btintel_set_diag;
                hdev->set_bdaddr = btintel_set_bdaddr;
                set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
+               set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks);
        }
 
        if (id->driver_info & BTUSB_MARVELL)
@@ -2904,8 +2942,10 @@ static int btusb_probe(struct usb_interface *intf,
                set_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks);
        }
 
-       if (id->driver_info & BTUSB_INTEL_BOOT)
+       if (id->driver_info & BTUSB_INTEL_BOOT) {
+               hdev->manufacturer = 2;
                set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
+       }
 
        if (id->driver_info & BTUSB_ATH3012) {
                hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
@@ -2934,8 +2974,8 @@ static int btusb_probe(struct usb_interface *intf,
                /* AMP controllers do not support SCO packets */
                data->isoc = NULL;
        } else {
-               /* Interface numbers are hardcoded in the specification */
-               data->isoc = usb_ifnum_to_if(data->udev, 1);
+               /* Interface orders are hardcoded in the specification */
+               data->isoc = usb_ifnum_to_if(data->udev, ifnum_base + 1);
        }
 
        if (!reset)