diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2015-03-22 10:52:38 -0400 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2015-03-22 20:15:07 -0400 |
commit | 17b2772b8fe3442b46c99fb91150a480acb7ebc4 (patch) | |
tree | 143108735b2ca4ad88346ca2b26dd780b6907324 | |
parent | baf880a96859cca79208122e555e7efeabd16e4d (diff) |
Bluetooth: Read Broadcom chip info for Apple Bluetooth devices
For the Apple Bluetooth devices that are Broadcom based, it makes sense
to read the chip information. It is a single HCI command and might help
gathering more information about these devices.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
-rw-r--r-- | drivers/bluetooth/btusb.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 1521dad3d460..9bf4d6ae6c6b 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/usb.h> | 25 | #include <linux/usb.h> |
26 | #include <linux/firmware.h> | 26 | #include <linux/firmware.h> |
27 | #include <asm/unaligned.h> | ||
27 | 28 | ||
28 | #include <net/bluetooth/bluetooth.h> | 29 | #include <net/bluetooth/bluetooth.h> |
29 | #include <net/bluetooth/hci_core.h> | 30 | #include <net/bluetooth/hci_core.h> |
@@ -53,6 +54,7 @@ static struct usb_driver btusb_driver; | |||
53 | #define BTUSB_INTEL_NEW 0x2000 | 54 | #define BTUSB_INTEL_NEW 0x2000 |
54 | #define BTUSB_AMP 0x4000 | 55 | #define BTUSB_AMP 0x4000 |
55 | #define BTUSB_QCA_ROME 0x8000 | 56 | #define BTUSB_QCA_ROME 0x8000 |
57 | #define BTUSB_BCM_APPLE 0x10000 | ||
56 | 58 | ||
57 | static const struct usb_device_id btusb_table[] = { | 59 | static const struct usb_device_id btusb_table[] = { |
58 | /* Generic Bluetooth USB device */ | 60 | /* Generic Bluetooth USB device */ |
@@ -62,7 +64,8 @@ static const struct usb_device_id btusb_table[] = { | |||
62 | { USB_DEVICE_INFO(0xe0, 0x01, 0x04), .driver_info = BTUSB_AMP }, | 64 | { USB_DEVICE_INFO(0xe0, 0x01, 0x04), .driver_info = BTUSB_AMP }, |
63 | 65 | ||
64 | /* Apple-specific (Broadcom) devices */ | 66 | /* Apple-specific (Broadcom) devices */ |
65 | { USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) }, | 67 | { USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01), |
68 | .driver_info = BTUSB_BCM_APPLE }, | ||
66 | 69 | ||
67 | /* MediaTek MT76x0E */ | 70 | /* MediaTek MT76x0E */ |
68 | { USB_DEVICE(0x0e8d, 0x763f) }, | 71 | { USB_DEVICE(0x0e8d, 0x763f) }, |
@@ -2634,6 +2637,34 @@ static int btusb_set_bdaddr_bcm(struct hci_dev *hdev, const bdaddr_t *bdaddr) | |||
2634 | return 0; | 2637 | return 0; |
2635 | } | 2638 | } |
2636 | 2639 | ||
2640 | static int btusb_setup_bcm_apple(struct hci_dev *hdev) | ||
2641 | { | ||
2642 | struct sk_buff *skb; | ||
2643 | int err; | ||
2644 | |||
2645 | /* Read Verbose Config Version Info */ | ||
2646 | skb = __hci_cmd_sync(hdev, 0xfc79, 0, NULL, HCI_INIT_TIMEOUT); | ||
2647 | if (IS_ERR(skb)) { | ||
2648 | err = PTR_ERR(skb); | ||
2649 | BT_ERR("%s: BCM: Read Verbose Version failed (%d)", | ||
2650 | hdev->name, err); | ||
2651 | return err; | ||
2652 | } | ||
2653 | |||
2654 | if (skb->len != 7) { | ||
2655 | BT_ERR("%s: BCM: Read Verbose Version event length mismatch", | ||
2656 | hdev->name); | ||
2657 | kfree_skb(skb); | ||
2658 | return -EIO; | ||
2659 | } | ||
2660 | |||
2661 | BT_INFO("%s: BCM: chip id %u build %4.4u", hdev->name, skb->data[1], | ||
2662 | get_unaligned_le16(skb->data + 5)); | ||
2663 | kfree_skb(skb); | ||
2664 | |||
2665 | return 0; | ||
2666 | } | ||
2667 | |||
2637 | static int btusb_set_bdaddr_ath3012(struct hci_dev *hdev, | 2668 | static int btusb_set_bdaddr_ath3012(struct hci_dev *hdev, |
2638 | const bdaddr_t *bdaddr) | 2669 | const bdaddr_t *bdaddr) |
2639 | { | 2670 | { |
@@ -3033,6 +3064,11 @@ static int btusb_probe(struct usb_interface *intf, | |||
3033 | set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); | 3064 | set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); |
3034 | } | 3065 | } |
3035 | 3066 | ||
3067 | if (id->driver_info & BTUSB_BCM_APPLE) { | ||
3068 | hdev->setup = btusb_setup_bcm_apple; | ||
3069 | set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); | ||
3070 | } | ||
3071 | |||
3036 | if (id->driver_info & BTUSB_INTEL) { | 3072 | if (id->driver_info & BTUSB_INTEL) { |
3037 | hdev->setup = btusb_setup_intel; | 3073 | hdev->setup = btusb_setup_intel; |
3038 | hdev->shutdown = btusb_shutdown_intel; | 3074 | hdev->shutdown = btusb_shutdown_intel; |