Skip to content

Commit d7ef0d1

Browse files
Alex Luholtmann
authored andcommitted
Bluetooth: btusb: Use cmd_timeout to reset Realtek device
Realtek Bluetooth controller provides a BT_DIS reset pin for hardware reset of it. The cmd_timeout is helpful on Realtek bluetooth controller where the firmware gets stuck. Signed-off-by: Alex Lu <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent cf0d9a7 commit d7ef0d1

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

drivers/bluetooth/btusb.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,36 @@ static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
524524
gpiod_set_value_cansleep(reset_gpio, 0);
525525
}
526526

527+
static void btusb_rtl_cmd_timeout(struct hci_dev *hdev)
528+
{
529+
struct btusb_data *data = hci_get_drvdata(hdev);
530+
struct gpio_desc *reset_gpio = data->reset_gpio;
531+
532+
if (++data->cmd_timeout_cnt < 5)
533+
return;
534+
535+
if (!reset_gpio) {
536+
bt_dev_err(hdev, "No gpio to reset Realtek device, ignoring");
537+
return;
538+
}
539+
540+
/* Toggle the hard reset line. The Realtek device is going to
541+
* yank itself off the USB and then replug. The cleanup is handled
542+
* correctly on the way out (standard USB disconnect), and the new
543+
* device is detected cleanly and bound to the driver again like
544+
* it should be.
545+
*/
546+
if (test_and_set_bit(BTUSB_HW_RESET_ACTIVE, &data->flags)) {
547+
bt_dev_err(hdev, "last reset failed? Not resetting again");
548+
return;
549+
}
550+
551+
bt_dev_err(hdev, "Reset Realtek device via gpio");
552+
gpiod_set_value_cansleep(reset_gpio, 0);
553+
msleep(200);
554+
gpiod_set_value_cansleep(reset_gpio, 1);
555+
}
556+
527557
static inline void btusb_free_frags(struct btusb_data *data)
528558
{
529559
unsigned long flags;
@@ -3783,6 +3813,7 @@ static int btusb_probe(struct usb_interface *intf,
37833813
if (id->driver_info & BTUSB_REALTEK) {
37843814
hdev->setup = btrtl_setup_realtek;
37853815
hdev->shutdown = btrtl_shutdown_realtek;
3816+
hdev->cmd_timeout = btusb_rtl_cmd_timeout;
37863817

37873818
/* Realtek devices lose their updated firmware over global
37883819
* suspend that means host doesn't send SET_FEATURE

0 commit comments

Comments
 (0)