Skip to content

Commit 3e4be65

Browse files
bgodavarholtmann
authored andcommitted
Bluetooth: hci_qca: Add poweroff support during hci down for wcn3990
This patch enables power off support for hci down and power on support for hci up. As wcn3990 power sources are ignited by regulators, we will turn off them during hci down, i.e. an complete power off of wcn3990. So while hci up, will call vendor setup which will turn on the regulators, requests BT chip version and download the firmware. Signed-off-by: Balakrishna Godavarthi <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent f778502 commit 3e4be65

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

drivers/bluetooth/hci_qca.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ struct qca_serdev {
168168

169169
static int qca_power_setup(struct hci_uart *hu, bool on);
170170
static void qca_power_shutdown(struct hci_uart *hu);
171+
static int qca_power_off(struct hci_dev *hdev);
171172

172173
static void __serial_clock_on(struct tty_struct *tty)
173174
{
@@ -1099,8 +1100,26 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
10991100
static int qca_wcn3990_init(struct hci_uart *hu)
11001101
{
11011102
struct hci_dev *hdev = hu->hdev;
1103+
struct qca_serdev *qcadev;
11021104
int ret;
11031105

1106+
/* Check for vregs status, may be hci down has turned
1107+
* off the voltage regulator.
1108+
*/
1109+
qcadev = serdev_device_get_drvdata(hu->serdev);
1110+
if (!qcadev->bt_power->vregs_on) {
1111+
serdev_device_close(hu->serdev);
1112+
ret = qca_power_setup(hu, true);
1113+
if (ret)
1114+
return ret;
1115+
1116+
ret = serdev_device_open(hu->serdev);
1117+
if (ret) {
1118+
bt_dev_err(hu->hdev, "failed to open port");
1119+
return ret;
1120+
}
1121+
}
1122+
11041123
/* Forcefully enable wcn3990 to enter in to boot mode. */
11051124
host_set_baudrate(hu, 2400);
11061125
ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWEROFF_PULSE);
@@ -1152,6 +1171,12 @@ static int qca_setup(struct hci_uart *hu)
11521171

11531172
if (qcadev->btsoc_type == QCA_WCN3990) {
11541173
bt_dev_info(hdev, "setting up wcn3990");
1174+
1175+
/* Enable NON_PERSISTENT_SETUP QUIRK to ensure to execute
1176+
* setup for every hci up.
1177+
*/
1178+
set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
1179+
hu->hdev->shutdown = qca_power_off;
11551180
ret = qca_wcn3990_init(hu);
11561181
if (ret)
11571182
return ret;
@@ -1242,6 +1267,14 @@ static void qca_power_shutdown(struct hci_uart *hu)
12421267
qca_power_setup(hu, false);
12431268
}
12441269

1270+
static int qca_power_off(struct hci_dev *hdev)
1271+
{
1272+
struct hci_uart *hu = hci_get_drvdata(hdev);
1273+
1274+
qca_power_shutdown(hu);
1275+
return 0;
1276+
}
1277+
12451278
static int qca_enable_regulator(struct qca_vreg vregs,
12461279
struct regulator *regulator)
12471280
{

0 commit comments

Comments
 (0)