data->isoc = NULL;
 
        if (id->driver_info & BTUSB_WIDEBAND_SPEECH)
-               set_bit(HCI_QUIRK_WIDE_BAND_SPEECH_SUPPORTED, &hdev->quirks);
+               set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
 
        if (id->driver_info & BTUSB_DIGIANSWER) {
                data->cmdreq_type = USB_TYPE_VENDOR;
 
         *
         * This quirk must be set before hci_register_dev is called.
         */
-       HCI_QUIRK_WIDE_BAND_SPEECH_SUPPORTED,
+       HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
 };
 
 /* HCI device flags */
        HCI_FAST_CONNECTABLE,
        HCI_BREDR_ENABLED,
        HCI_LE_SCAN_INTERRUPTED,
+       HCI_WIDEBAND_SPEECH_ENABLED,
 
        HCI_DUT_MODE,
        HCI_VENDOR_DIAG,
        __s8     tx_power;
 } __packed;
 
+#define HCI_OP_READ_DEF_ERR_DATA_REPORTING     0x0c5a
+       #define ERR_DATA_REPORTING_DISABLED     0x00
+       #define ERR_DATA_REPORTING_ENABLED      0x01
+struct hci_rp_read_def_err_data_reporting {
+       __u8     status;
+       __u8     err_data_reporting;
+} __packed;
+
+#define HCI_OP_WRITE_DEF_ERR_DATA_REPORTING    0x0c5b
+struct hci_cp_write_def_err_data_reporting {
+       __u8     err_data_reporting;
+} __packed;
+
 #define HCI_OP_SET_EVENT_MASK_PAGE_2   0x0c63
 
 #define HCI_OP_READ_LOCATION_DATA      0x0c64
 
        __u8            stored_num_keys;
        __u8            io_capability;
        __s8            inq_tx_power;
+       __u8            err_data_reporting;
        __u16           page_scan_interval;
        __u16           page_scan_window;
        __u8            page_scan_type;
 
 #define MGMT_SETTING_CONFIGURATION     0x00004000
 #define MGMT_SETTING_STATIC_ADDRESS    0x00008000
 #define MGMT_SETTING_PHY_CONFIGURATION 0x00010000
-#define MGMT_SETTING_WIDE_BAND_SPEECH  0x00020000
+#define MGMT_SETTING_WIDEBAND_SPEECH   0x00020000
 
 #define MGMT_OP_READ_INFO              0x0004
 #define MGMT_READ_INFO_SIZE            0
 } __packed;
 #define MGMT_OP_SET_BLOCKED_KEYS_SIZE 2
 
+#define MGMT_OP_SET_WIDEBAND_SPEECH    0x0047
+
 #define MGMT_EV_CMD_COMPLETE           0x0001
 struct mgmt_ev_cmd_complete {
        __le16  opcode;
 
        if (hdev->commands[8] & 0x01)
                hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
 
+       if (hdev->commands[18] & 0x02)
+               hci_req_add(req, HCI_OP_READ_DEF_ERR_DATA_REPORTING, 0, NULL);
+
        /* Some older Broadcom based Bluetooth 1.2 controllers do not
         * support the Read Page Scan Type command. Check support for
         * this command in the bit mask of supported commands.
                            sizeof(support), &support);
        }
 
+       /* Set erroneous data reporting if supported to the wideband speech
+        * setting value
+        */
+       if (hdev->commands[18] & 0x04) {
+               bool enabled = hci_dev_test_flag(hdev,
+                                                HCI_WIDEBAND_SPEECH_ENABLED);
+
+               if (enabled !=
+                   (hdev->err_data_reporting == ERR_DATA_REPORTING_ENABLED)) {
+                       struct hci_cp_write_def_err_data_reporting cp;
+
+                       cp.err_data_reporting = enabled ?
+                                               ERR_DATA_REPORTING_ENABLED :
+                                               ERR_DATA_REPORTING_DISABLED;
+
+                       hci_req_add(req, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING,
+                                   sizeof(cp), &cp);
+               }
+       }
+
        /* Set Suggested Default Data Length to maximum if supported */
        if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
                struct hci_cp_le_write_def_data_len cp;
 
        hdev->inq_tx_power = rp->tx_power;
 }
 
+static void hci_cc_read_def_err_data_reporting(struct hci_dev *hdev,
+                                              struct sk_buff *skb)
+{
+       struct hci_rp_read_def_err_data_reporting *rp = (void *)skb->data;
+
+       BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
+
+       if (rp->status)
+               return;
+
+       hdev->err_data_reporting = rp->err_data_reporting;
+}
+
+static void hci_cc_write_def_err_data_reporting(struct hci_dev *hdev,
+                                               struct sk_buff *skb)
+{
+       __u8 status = *((__u8 *)skb->data);
+       struct hci_cp_write_def_err_data_reporting *cp;
+
+       BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+       if (status)
+               return;
+
+       cp = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING);
+       if (!cp)
+               return;
+
+       hdev->err_data_reporting = cp->err_data_reporting;
+}
+
 static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_rp_pin_code_reply *rp = (void *) skb->data;
                hci_cc_read_inq_rsp_tx_power(hdev, skb);
                break;
 
+       case HCI_OP_READ_DEF_ERR_DATA_REPORTING:
+               hci_cc_read_def_err_data_reporting(hdev, skb);
+               break;
+
+       case HCI_OP_WRITE_DEF_ERR_DATA_REPORTING:
+               hci_cc_write_def_err_data_reporting(hdev, skb);
+               break;
+
        case HCI_OP_PIN_CODE_REPLY:
                hci_cc_pin_code_reply(hdev, skb);
                break;
 
        MGMT_OP_READ_EXT_INFO,
        MGMT_OP_SET_APPEARANCE,
        MGMT_OP_SET_BLOCKED_KEYS,
+       MGMT_OP_SET_WIDEBAND_SPEECH,
 };
 
 static const u16 mgmt_events[] = {
                if (lmp_sc_capable(hdev))
                        settings |= MGMT_SETTING_SECURE_CONN;
 
-               if (test_bit(HCI_QUIRK_WIDE_BAND_SPEECH_SUPPORTED,
+               if (test_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
                             &hdev->quirks))
-                       settings |= MGMT_SETTING_WIDE_BAND_SPEECH;
+                       settings |= MGMT_SETTING_WIDEBAND_SPEECH;
        }
 
        if (lmp_le_capable(hdev)) {
                        settings |= MGMT_SETTING_STATIC_ADDRESS;
        }
 
+       if (hci_dev_test_flag(hdev, HCI_WIDEBAND_SPEECH_ENABLED))
+               settings |= MGMT_SETTING_WIDEBAND_SPEECH;
+
        return settings;
 }
 
                                err, NULL, 0);
 }
 
+static int set_wideband_speech(struct sock *sk, struct hci_dev *hdev,
+                              void *data, u16 len)
+{
+       struct mgmt_mode *cp = data;
+       int err;
+       bool changed = false;
+
+       BT_DBG("request for %s", hdev->name);
+
+       if (!test_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks))
+               return mgmt_cmd_status(sk, hdev->id,
+                                      MGMT_OP_SET_WIDEBAND_SPEECH,
+                                      MGMT_STATUS_NOT_SUPPORTED);
+
+       if (cp->val != 0x00 && cp->val != 0x01)
+               return mgmt_cmd_status(sk, hdev->id,
+                                      MGMT_OP_SET_WIDEBAND_SPEECH,
+                                      MGMT_STATUS_INVALID_PARAMS);
+
+       hci_dev_lock(hdev);
+
+       if (pending_find(MGMT_OP_SET_WIDEBAND_SPEECH, hdev)) {
+               err = mgmt_cmd_status(sk, hdev->id,
+                                     MGMT_OP_SET_WIDEBAND_SPEECH,
+                                     MGMT_STATUS_BUSY);
+               goto unlock;
+       }
+
+       if (hdev_is_powered(hdev) &&
+           !!cp->val != hci_dev_test_flag(hdev,
+                                          HCI_WIDEBAND_SPEECH_ENABLED)) {
+               err = mgmt_cmd_status(sk, hdev->id,
+                                     MGMT_OP_SET_WIDEBAND_SPEECH,
+                                     MGMT_STATUS_REJECTED);
+               goto unlock;
+       }
+
+       if (cp->val)
+               changed = !hci_dev_test_and_set_flag(hdev,
+                                                  HCI_WIDEBAND_SPEECH_ENABLED);
+       else
+               changed = hci_dev_test_and_clear_flag(hdev,
+                                                  HCI_WIDEBAND_SPEECH_ENABLED);
+
+       err = send_settings_rsp(sk, MGMT_OP_SET_WIDEBAND_SPEECH, hdev);
+       if (err < 0)
+               goto unlock;
+
+       if (changed)
+               err = new_settings(hdev, sk);
+
+unlock:
+       hci_dev_unlock(hdev);
+       return err;
+}
+
 static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
                                         u16 opcode, struct sk_buff *skb)
 {
        { set_phy_configuration,   MGMT_SET_PHY_CONFIGURATION_SIZE },
        { set_blocked_keys,        MGMT_OP_SET_BLOCKED_KEYS_SIZE,
                                                HCI_MGMT_VAR_LEN },
+       { set_wideband_speech,     MGMT_SETTING_SIZE },
 };
 
 void mgmt_index_added(struct hci_dev *hdev)