aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/btusb.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2015-01-28 23:27:34 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2015-01-29 02:27:50 -0500
commit893ba5440a25ebe3376f0b2ee5a74e0a6423f00e (patch)
treea6be31766ed8483b53b7a72a8f65a4fcd1face84 /drivers/bluetooth/btusb.c
parentd0ac9eb72b6dceae318c15ee82ef2aaee233666d (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.c29
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
55static const struct usb_device_id btusb_table[] = { 56static 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);