Commit 5e6d8401 authored by Rocky Liao's avatar Rocky Liao Committed by Marcel Holtmann
Browse files

Bluetooth: hci_qca: Add qca_power_on() API to support both wcn399x and Rome power up



This patch adds a unified API qca_power_on() to support both wcn399x and
Rome power on. For wcn399x it calls the qca_wcn3990_init() to init the
regulators, and for Rome it pulls up the bt_en GPIO to power up the btsoc.
It also moves all the power up operation from hdev->open() to
hdev->setup().

Signed-off-by: default avatarRocky Liao <rjliao@codeaurora.org>
Reviewed-by: default avatarMatthias Kaehlcke <mka@chromium.org>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent dde8010b
Loading
Loading
Loading
Loading
+33 −21
Original line number Diff line number Diff line
@@ -541,7 +541,6 @@ static int qca_open(struct hci_uart *hu)
{
	struct qca_serdev *qcadev;
	struct qca_data *qca;
	int ret;

	BT_DBG("hu %p qca_open", hu);

@@ -582,23 +581,10 @@ static int qca_open(struct hci_uart *hu)
	hu->priv = qca;

	if (hu->serdev) {

		qcadev = serdev_device_get_drvdata(hu->serdev);
		if (!qca_is_wcn399x(qcadev->btsoc_type)) {
			gpiod_set_value_cansleep(qcadev->bt_en, 1);
			/* Controller needs time to bootup. */
			msleep(150);
		} else {
		if (qca_is_wcn399x(qcadev->btsoc_type)) {
			hu->init_speed = qcadev->init_speed;
			hu->oper_speed = qcadev->oper_speed;
			ret = qca_regulator_enable(qcadev);
			if (ret) {
				destroy_workqueue(qca->workqueue);
				kfree_skb(qca->rx_skb);
				hu->priv = NULL;
				kfree(qca);
				return ret;
			}
		}
	}

@@ -1531,6 +1517,31 @@ static int qca_wcn3990_init(struct hci_uart *hu)
	return 0;
}

static int qca_power_on(struct hci_dev *hdev)
{
	struct hci_uart *hu = hci_get_drvdata(hdev);
	enum qca_btsoc_type soc_type = qca_soc_type(hu);
	struct qca_serdev *qcadev;
	int ret = 0;

	/* Non-serdev device usually is powered by external power
	 * and don't need additional action in driver for power on
	 */
	if (!hu->serdev)
		return 0;

	if (qca_is_wcn399x(soc_type)) {
		ret = qca_wcn3990_init(hu);
	} else {
		qcadev = serdev_device_get_drvdata(hu->serdev);
		gpiod_set_value_cansleep(qcadev->bt_en, 1);
		/* Controller needs time to bootup. */
		msleep(150);
	}

	return ret;
}

static int qca_setup(struct hci_uart *hu)
{
	struct hci_dev *hdev = hu->hdev;
@@ -1553,24 +1564,25 @@ static int qca_setup(struct hci_uart *hu)
	 */
	set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);

	if (qca_is_wcn399x(soc_type)) {
		bt_dev_info(hdev, "setting up wcn3990");
	bt_dev_info(hdev, "setting up %s",
		qca_is_wcn399x(soc_type) ? "wcn399x" : "ROME");

	ret = qca_power_on(hdev);
	if (ret)
		return ret;

	if (qca_is_wcn399x(soc_type)) {
		/* Enable NON_PERSISTENT_SETUP QUIRK to ensure to execute
		 * setup for every hci up.
		 */
		set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
		set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
		hu->hdev->shutdown = qca_power_off;
		ret = qca_wcn3990_init(hu);
		if (ret)
			return ret;

		ret = qca_read_soc_version(hdev, &soc_ver, soc_type);
		if (ret)
			return ret;
	} else {
		bt_dev_info(hdev, "ROME setup");
		qca_set_speed(hu, QCA_INIT_SPEED);
	}