Commit 9a15ce68 authored by Bartosz Golaszewski's avatar Bartosz Golaszewski Committed by Luiz Augusto von Dentz
Browse files

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: default avatarAmit 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: default avatarBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 66ef82c6
Loading
Loading
Loading
Loading
+59 −15
Original line number Diff line number Diff line
@@ -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);