Bluetooth: btusb: Dynamic alternate setting
authorMikel Astiz <mikel.astiz@bmw-carit.de>
Wed, 11 Apr 2012 06:48:51 +0000 (08:48 +0200)
committerGustavo Padovan <gustavo@padovan.org>
Wed, 9 May 2012 04:40:35 +0000 (01:40 -0300)
The alternate setting must be dynamically set according to the number of
active SCO links, and the bit depth of the audio. The possible values
for the alternate setting are described in the Bluetooth Core
Specification, Volume 4, Part B, section 2.1.1.

Signed-off-by: Mikel Astiz <mikel.astiz.oss@gmail.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo Padovan <gustavo@padovan.org>
drivers/bluetooth/btusb.c

index 9217121362e10820da89b5678311b61ad6cac849..de171211a1c8fed4a25da519606473ebbe6c6695 100644 (file)
@@ -855,6 +855,7 @@ static void btusb_work(struct work_struct *work)
 {
        struct btusb_data *data = container_of(work, struct btusb_data, work);
        struct hci_dev *hdev = data->hdev;
+       int new_alts;
        int err;
 
        if (hdev->conn_hash.sco_num > 0) {
@@ -868,11 +869,19 @@ static void btusb_work(struct work_struct *work)
 
                        set_bit(BTUSB_DID_ISO_RESUME, &data->flags);
                }
-               if (data->isoc_altsetting != 2) {
+
+               if (hdev->voice_setting & 0x0020) {
+                       static const int alts[3] = { 2, 4, 5 };
+                       new_alts = alts[hdev->conn_hash.sco_num - 1];
+               } else {
+                       new_alts = hdev->conn_hash.sco_num;
+               }
+
+               if (data->isoc_altsetting != new_alts) {
                        clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
                        usb_kill_anchored_urbs(&data->isoc_anchor);
 
-                       if (__set_isoc_interface(hdev, 2) < 0)
+                       if (__set_isoc_interface(hdev, new_alts) < 0)
                                return;
                }