mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 05:32:00 +00:00
Bluetooth: qca: use the power sequencer for QCA6390
Use the pwrseq subsystem's consumer API to run the power-up sequence for the Bluetooth module of the QCA6390 package. Tested-by: Amit Pundir <amit.pundir@linaro.org> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD, SM8650-QRD & SM8650-HDK Tested-by: Caleb Connolly <caleb.connolly@linaro.org> # OnePlus 8T Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
66ef82c66e
commit
9a15ce6857
@ -28,6 +28,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwrseq/consumer.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/serdev.h>
|
||||
#include <linux/mutex.h>
|
||||
@ -214,6 +215,7 @@ struct qca_power {
|
||||
struct regulator_bulk_data *vreg_bulk;
|
||||
int num_vregs;
|
||||
bool vregs_on;
|
||||
struct pwrseq_desc *pwrseq;
|
||||
};
|
||||
|
||||
struct qca_serdev {
|
||||
@ -1684,6 +1686,27 @@ static bool qca_wakeup(struct hci_dev *hdev)
|
||||
return wakeup;
|
||||
}
|
||||
|
||||
static int qca_port_reopen(struct hci_uart *hu)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Now the device is in ready state to communicate with host.
|
||||
* To sync host with device we need to reopen port.
|
||||
* Without this, we will have RTS and CTS synchronization
|
||||
* issues.
|
||||
*/
|
||||
serdev_device_close(hu->serdev);
|
||||
ret = serdev_device_open(hu->serdev);
|
||||
if (ret) {
|
||||
bt_dev_err(hu->hdev, "failed to open port");
|
||||
return ret;
|
||||
}
|
||||
|
||||
hci_uart_set_flow_control(hu, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qca_regulator_init(struct hci_uart *hu)
|
||||
{
|
||||
enum qca_btsoc_type soc_type = qca_soc_type(hu);
|
||||
@ -1752,21 +1775,7 @@ static int qca_regulator_init(struct hci_uart *hu)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Now the device is in ready state to communicate with host.
|
||||
* To sync host with device we need to reopen port.
|
||||
* Without this, we will have RTS and CTS synchronization
|
||||
* issues.
|
||||
*/
|
||||
serdev_device_close(hu->serdev);
|
||||
ret = serdev_device_open(hu->serdev);
|
||||
if (ret) {
|
||||
bt_dev_err(hu->hdev, "failed to open port");
|
||||
return ret;
|
||||
}
|
||||
|
||||
hci_uart_set_flow_control(hu, false);
|
||||
|
||||
return 0;
|
||||
return qca_port_reopen(hu);
|
||||
}
|
||||
|
||||
static int qca_power_on(struct hci_dev *hdev)
|
||||
@ -1794,6 +1803,17 @@ static int qca_power_on(struct hci_dev *hdev)
|
||||
ret = qca_regulator_init(hu);
|
||||
break;
|
||||
|
||||
case QCA_QCA6390:
|
||||
qcadev = serdev_device_get_drvdata(hu->serdev);
|
||||
ret = pwrseq_power_on(qcadev->bt_power->pwrseq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = qca_port_reopen(hu);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
|
||||
default:
|
||||
qcadev = serdev_device_get_drvdata(hu->serdev);
|
||||
if (qcadev->bt_en) {
|
||||
@ -2168,6 +2188,10 @@ static void qca_power_shutdown(struct hci_uart *hu)
|
||||
}
|
||||
break;
|
||||
|
||||
case QCA_QCA6390:
|
||||
pwrseq_power_off(qcadev->bt_power->pwrseq);
|
||||
break;
|
||||
|
||||
default:
|
||||
gpiod_set_value_cansleep(qcadev->bt_en, 0);
|
||||
}
|
||||
@ -2309,12 +2333,25 @@ static int qca_serdev_probe(struct serdev_device *serdev)
|
||||
case QCA_WCN6750:
|
||||
case QCA_WCN6855:
|
||||
case QCA_WCN7850:
|
||||
case QCA_QCA6390:
|
||||
qcadev->bt_power = devm_kzalloc(&serdev->dev,
|
||||
sizeof(struct qca_power),
|
||||
GFP_KERNEL);
|
||||
if (!qcadev->bt_power)
|
||||
return -ENOMEM;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (qcadev->btsoc_type) {
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
case QCA_WCN3998:
|
||||
case QCA_WCN6750:
|
||||
case QCA_WCN6855:
|
||||
case QCA_WCN7850:
|
||||
qcadev->bt_power->dev = &serdev->dev;
|
||||
err = qca_init_regulators(qcadev->bt_power, data->vregs,
|
||||
data->num_vregs);
|
||||
@ -2360,6 +2397,13 @@ static int qca_serdev_probe(struct serdev_device *serdev)
|
||||
}
|
||||
break;
|
||||
|
||||
case QCA_QCA6390:
|
||||
qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->dev,
|
||||
"bluetooth");
|
||||
if (IS_ERR(qcadev->bt_power->pwrseq))
|
||||
return PTR_ERR(qcadev->bt_power->pwrseq);
|
||||
fallthrough;
|
||||
|
||||
default:
|
||||
qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
|
||||
GPIOD_OUT_LOW);
|
||||
|
Loading…
Reference in New Issue
Block a user