/* Reset device */ static int hci_uart_flush(struct hci_dev *hdev) { struct hci_uart *hu = hci_get_drvdata(hdev); BT_DBG("hdev %p serdev %p", hdev, hu->serdev); if (hu->tx_skb) { kfree_skb(hu->tx_skb); hu->tx_skb = NULL; } /* Flush any pending characters in the driver and discipline. */ serdev_device_write_flush(hu->serdev); if (test_bit(HCI_UART_PROTO_READY, &hu->flags)) hu->proto->flush(hu); return 0; }
static int nokia_reset(struct hci_uart *hu) { struct nokia_bt_dev *btdev = hu->priv; struct device *dev = &btdev->serdev->dev; int err; /* reset routine */ gpiod_set_value_cansleep(btdev->reset, 1); gpiod_set_value_cansleep(btdev->wakeup_bt, 1); msleep(100); /* safety check */ err = gpiod_get_value_cansleep(btdev->wakeup_host); if (err == 1) { dev_err(dev, "reset: host wakeup not low!"); return -EPROTO; } /* flush queue */ serdev_device_write_flush(btdev->serdev); /* init uart */ nokia_flow_control(btdev->serdev, false); serdev_device_set_baudrate(btdev->serdev, INIT_BAUD_RATE); gpiod_set_value_cansleep(btdev->reset, 0); /* wait for cts */ err = serdev_device_wait_for_cts(btdev->serdev, true, 200); if (err < 0) { dev_err(dev, "CTS not received: %d", err); return err; } nokia_flow_control(btdev->serdev, true); return 0; }
static int qca_send_power_pulse(struct hci_uart *hu, bool on) { int ret; int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS); u8 cmd = on ? QCA_WCN3990_POWERON_PULSE : QCA_WCN3990_POWEROFF_PULSE; /* These power pulses are single byte command which are sent * at required baudrate to wcn3990. On wcn3990, we have an external * circuit at Tx pin which decodes the pulse sent at specific baudrate. * For example, wcn3990 supports RF COEX antenna for both Wi-Fi/BT * and also we use the same power inputs to turn on and off for * Wi-Fi/BT. Powering up the power sources will not enable BT, until * we send a power on pulse at 115200 bps. This algorithm will help to * save power. Disabling hardware flow control is mandatory while * sending power pulses to SoC. */ bt_dev_dbg(hu->hdev, "sending power pulse %02x to controller", cmd); serdev_device_write_flush(hu->serdev); hci_uart_set_flow_control(hu, true); ret = serdev_device_write_buf(hu->serdev, &cmd, sizeof(cmd)); if (ret < 0) { bt_dev_err(hu->hdev, "failed to send power pulse %02x", cmd); return ret; } serdev_device_wait_until_sent(hu->serdev, timeout); hci_uart_set_flow_control(hu, false); /* Give to controller time to boot/shutdown */ if (on) msleep(100); else msleep(10); return 0; }