diff options
author | Toshi Kikuchi <toshik@chromium.org> | 2014-12-12 10:58:05 -0800 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-12-18 22:42:49 +0100 |
commit | 5859223e0c4f69ab36dd931ea7058c3b1b2abb41 (patch) | |
tree | 356b992d00253cd52f5faaf633817df00cdf6dd4 /drivers/bluetooth | |
parent | 86c8fc4bbe14b8950e62d379bb57722427ad3d67 (diff) | |
download | linux-5859223e0c4f69ab36dd931ea7058c3b1b2abb41.tar.bz2 |
Bluetooth: btusb: support public address configuration for ath3012
Set hdev->set_bdaddr handler for ath3012. It sends the vendor specific HCI
command to change the public address. The change doesn't persist across
power cycle.
Signed-off-by: Toshi Kikuchi <toshik@chromium.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/btusb.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 19cf2cf22e87..c926835aec37 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -1943,6 +1943,31 @@ static int btusb_set_bdaddr_bcm(struct hci_dev *hdev, const bdaddr_t *bdaddr) return 0; } +static int btusb_set_bdaddr_ath3012(struct hci_dev *hdev, + const bdaddr_t *bdaddr) +{ + struct sk_buff *skb; + u8 buf[10]; + long ret; + + buf[0] = 0x01; + buf[1] = 0x01; + buf[2] = 0x00; + buf[3] = sizeof(bdaddr_t); + memcpy(buf + 4, bdaddr, sizeof(bdaddr_t)); + + skb = __hci_cmd_sync(hdev, 0xfc0b, sizeof(buf), buf, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + ret = PTR_ERR(skb); + BT_ERR("%s: Change address command failed (%ld)", + hdev->name, ret); + return ret; + } + kfree_skb(skb); + + return 0; +} + static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -2058,6 +2083,9 @@ static int btusb_probe(struct usb_interface *intf, if (id->driver_info & BTUSB_INTEL_BOOT) set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); + if (id->driver_info & BTUSB_ATH3012) + hdev->set_bdaddr = btusb_set_bdaddr_ath3012; + /* Interface numbers are hardcoded in the specification */ data->isoc = usb_ifnum_to_if(data->udev, 1); |