diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2015-01-28 23:27:34 -0500 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2015-01-29 02:27:50 -0500 |
commit | 893ba5440a25ebe3376f0b2ee5a74e0a6423f00e (patch) | |
tree | a6be31766ed8483b53b7a72a8f65a4fcd1face84 /drivers/bluetooth/btusb.c | |
parent | d0ac9eb72b6dceae318c15ee82ef2aaee233666d (diff) |
Bluetooth: btusb: Add support for USB based AMP controllers
The Bluetooth HCI transport specification for USB device defines on how
a standard AMP controller is identified and operated. This patch adds
the needed handling to hook it up to the Bluetooth stack.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'drivers/bluetooth/btusb.c')
-rw-r--r-- | drivers/bluetooth/btusb.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 9d2d059a7540..d114786490b1 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -51,11 +51,15 @@ static struct usb_driver btusb_driver; | |||
51 | #define BTUSB_MARVELL 0x800 | 51 | #define BTUSB_MARVELL 0x800 |
52 | #define BTUSB_SWAVE 0x1000 | 52 | #define BTUSB_SWAVE 0x1000 |
53 | #define BTUSB_INTEL_NEW 0x2000 | 53 | #define BTUSB_INTEL_NEW 0x2000 |
54 | #define BTUSB_AMP 0x4000 | ||
54 | 55 | ||
55 | static const struct usb_device_id btusb_table[] = { | 56 | static const struct usb_device_id btusb_table[] = { |
56 | /* Generic Bluetooth USB device */ | 57 | /* Generic Bluetooth USB device */ |
57 | { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, | 58 | { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, |
58 | 59 | ||
60 | /* Generic Bluetooth AMP device */ | ||
61 | { USB_DEVICE_INFO(0xe0, 0x01, 0x04), .driver_info = BTUSB_AMP }, | ||
62 | |||
59 | /* Apple-specific (Broadcom) devices */ | 63 | /* Apple-specific (Broadcom) devices */ |
60 | { USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) }, | 64 | { USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) }, |
61 | 65 | ||
@@ -320,6 +324,7 @@ struct btusb_data { | |||
320 | struct usb_endpoint_descriptor *isoc_rx_ep; | 324 | struct usb_endpoint_descriptor *isoc_rx_ep; |
321 | 325 | ||
322 | __u8 cmdreq_type; | 326 | __u8 cmdreq_type; |
327 | __u8 cmdreq; | ||
323 | 328 | ||
324 | unsigned int sco_num; | 329 | unsigned int sco_num; |
325 | int isoc_altsetting; | 330 | int isoc_altsetting; |
@@ -973,7 +978,7 @@ static struct urb *alloc_ctrl_urb(struct hci_dev *hdev, struct sk_buff *skb) | |||
973 | } | 978 | } |
974 | 979 | ||
975 | dr->bRequestType = data->cmdreq_type; | 980 | dr->bRequestType = data->cmdreq_type; |
976 | dr->bRequest = 0; | 981 | dr->bRequest = data->cmdreq; |
977 | dr->wIndex = 0; | 982 | dr->wIndex = 0; |
978 | dr->wValue = 0; | 983 | dr->wValue = 0; |
979 | dr->wLength = __cpu_to_le16(skb->len); | 984 | dr->wLength = __cpu_to_le16(skb->len); |
@@ -2640,7 +2645,13 @@ static int btusb_probe(struct usb_interface *intf, | |||
2640 | if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) | 2645 | if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) |
2641 | return -ENODEV; | 2646 | return -ENODEV; |
2642 | 2647 | ||
2643 | data->cmdreq_type = USB_TYPE_CLASS; | 2648 | if (id->driver_info & BTUSB_AMP) { |
2649 | data->cmdreq_type = USB_TYPE_CLASS | 0x01; | ||
2650 | data->cmdreq = 0x2b; | ||
2651 | } else { | ||
2652 | data->cmdreq_type = USB_TYPE_CLASS; | ||
2653 | data->cmdreq = 0x00; | ||
2654 | } | ||
2644 | 2655 | ||
2645 | data->udev = interface_to_usbdev(intf); | 2656 | data->udev = interface_to_usbdev(intf); |
2646 | data->intf = intf; | 2657 | data->intf = intf; |
@@ -2672,6 +2683,11 @@ static int btusb_probe(struct usb_interface *intf, | |||
2672 | hdev->bus = HCI_USB; | 2683 | hdev->bus = HCI_USB; |
2673 | hci_set_drvdata(hdev, data); | 2684 | hci_set_drvdata(hdev, data); |
2674 | 2685 | ||
2686 | if (id->driver_info & BTUSB_AMP) | ||
2687 | hdev->dev_type = HCI_AMP; | ||
2688 | else | ||
2689 | hdev->dev_type = HCI_BREDR; | ||
2690 | |||
2675 | data->hdev = hdev; | 2691 | data->hdev = hdev; |
2676 | 2692 | ||
2677 | SET_HCIDEV_DEV(hdev, &intf->dev); | 2693 | SET_HCIDEV_DEV(hdev, &intf->dev); |
@@ -2718,8 +2734,13 @@ static int btusb_probe(struct usb_interface *intf, | |||
2718 | if (id->driver_info & BTUSB_ATH3012) | 2734 | if (id->driver_info & BTUSB_ATH3012) |
2719 | hdev->set_bdaddr = btusb_set_bdaddr_ath3012; | 2735 | hdev->set_bdaddr = btusb_set_bdaddr_ath3012; |
2720 | 2736 | ||
2721 | /* Interface numbers are hardcoded in the specification */ | 2737 | if (id->driver_info & BTUSB_AMP) { |
2722 | data->isoc = usb_ifnum_to_if(data->udev, 1); | 2738 | /* AMP controllers do not support SCO packets */ |
2739 | data->isoc = NULL; | ||
2740 | } else { | ||
2741 | /* Interface numbers are hardcoded in the specification */ | ||
2742 | data->isoc = usb_ifnum_to_if(data->udev, 1); | ||
2743 | } | ||
2723 | 2744 | ||
2724 | if (!reset) | 2745 | if (!reset) |
2725 | set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); | 2746 | set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); |