linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
To: Andy Gross <agross@kernel.org>,
	Bjorn Andersson <bjorn.andersson@linaro.org>,
	Rob Herring <robh+dt@kernel.org>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Mark Brown <broonie@kernel.org>,
	Marcel Holtmann <marcel@holtmann.org>,
	Johan Hedberg <johan.hedberg@gmail.com>,
	Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Cc: linux-arm-msm@vger.kernel.org,
	Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-bluetooth@vger.kernel.org
Subject: [PATCH v3 2/7] regulator: qca6390: add support for QCA639x powerup sequence
Date: Tue, 22 Jun 2021 01:31:36 +0300	[thread overview]
Message-ID: <20210621223141.1638189-3-dmitry.baryshkov@linaro.org> (raw)
In-Reply-To: <20210621223141.1638189-1-dmitry.baryshkov@linaro.org>

Qualcomm QCA6390/1 is a family of WiFi + Bluetooth SoCs, with BT part
being controlled through the UART and WiFi being present on PCIe
bus. Both blocks share common power sources. Add device driver handling
power sequencing of QCA6390/1.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/regulator/Kconfig        |  13 +++
 drivers/regulator/Makefile       |   1 +
 drivers/regulator/qcom-qca639x.c | 157 +++++++++++++++++++++++++++++++
 3 files changed, 171 insertions(+)
 create mode 100644 drivers/regulator/qcom-qca639x.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 3e7a38525cb3..7a560cddea7a 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -909,6 +909,19 @@ config REGULATOR_PWM
 	  This driver supports PWM controlled voltage regulators. PWM
 	  duty cycle can increase or decrease the voltage.
 
+config REGULATOR_QCOM_QCA639X
+	tristate "Qualcomm QCA639x WiFi/Bluetooth module support"
+	help
+	  If you say yes to this option, support will be included for Qualcomm
+	  QCA639x family of WiFi and Bluetooth SoCs. Note, this driver supports
+	  only power control for this SoC, you still have to enable individual
+	  Bluetooth and WiFi drivers. This driver is only necessary on ARM
+	  platforms with this chip. PCIe cards handle power sequencing on their
+	  own.
+
+	  Say M here if you want to include support for QCA639x chips as a
+	  module. This will build a module called "qcom-qca639x".
+
 config REGULATOR_QCOM_RPM
 	tristate "Qualcomm RPM regulator driver"
 	depends on MFD_QCOM_RPM
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 580b015296ea..129c2110b78d 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_REGULATOR_MT6380)	+= mt6380-regulator.o
 obj-$(CONFIG_REGULATOR_MT6397)	+= mt6397-regulator.o
 obj-$(CONFIG_REGULATOR_MTK_DVFSRC) += mtk-dvfsrc-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_LABIBB) += qcom-labibb-regulator.o
+obj-$(CONFIG_REGULATOR_QCOM_QCA639X) += qcom-qca639x.o
 obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
diff --git a/drivers/regulator/qcom-qca639x.c b/drivers/regulator/qcom-qca639x.c
new file mode 100644
index 000000000000..a2c78c0f8baa
--- /dev/null
+++ b/drivers/regulator/qcom-qca639x.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, Linaro Limited
+ */
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/slab.h>
+
+#define MAX_NUM_REGULATORS	8
+
+static struct vreg {
+	const char *name;
+	unsigned int load_uA;
+} vregs[MAX_NUM_REGULATORS] = {
+	/* 2.0 V */
+	{ "vddpcie2", 15000 },
+	{ "vddrfa3", 400000 },
+
+	/* 0.95 V */
+	{ "vddaon", 100000 },
+	{ "vddpmu", 1250000 },
+	{ "vddrfa1", 200000 },
+
+	/* 1.35 V */
+	{ "vddrfa2", 400000 },
+	{ "vddpcie1", 35000 },
+
+	/* 1.8 V */
+	{ "vddio", 20000 },
+};
+
+struct qca6390_data {
+	struct device *dev;
+	struct regulator_bulk_data regulators[MAX_NUM_REGULATORS];
+	size_t num_vregs;
+
+	struct regulator_desc desc;
+	struct regulator_dev *regulator_dev;
+	unsigned int enable_counter;
+};
+
+#define domain_to_data(domain) container_of(domain, struct qca6390_data, pd)
+
+static int qca6390_enable(struct regulator_dev *rdev)
+{
+	struct qca6390_data *data = rdev_get_drvdata(rdev);
+	int ret;
+
+	ret = regulator_bulk_enable(data->num_vregs, data->regulators);
+	if (ret) {
+		dev_err(data->dev, "Failed to enable regulators");
+		return ret;
+	}
+
+	/* Wait for 1ms before toggling enable pins. */
+	usleep_range(1000, 2000);
+
+	data->enable_counter++;
+
+	return 0;
+}
+
+static int qca6390_disable(struct regulator_dev *rdev)
+{
+	struct qca6390_data *data = rdev_get_drvdata(rdev);
+
+	regulator_bulk_disable(data->num_vregs, data->regulators);
+
+	data->enable_counter--;
+
+	return 0;
+}
+
+static int qca6390_is_enabled(struct regulator_dev *rdev)
+{
+	struct qca6390_data *data = rdev_get_drvdata(rdev);
+
+	return data->enable_counter > 0;
+}
+
+static const struct regulator_ops qca6390_ops = {
+	.enable = qca6390_enable,
+	.disable = qca6390_disable,
+	.is_enabled = qca6390_is_enabled,
+};
+
+static int qca6390_probe(struct platform_device *pdev)
+{
+	struct qca6390_data *data;
+	struct device *dev = &pdev->dev;
+	struct regulator_config cfg = { };
+	int i, ret;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->dev = dev;
+	data->num_vregs = ARRAY_SIZE(vregs);
+
+	for (i = 0; i < data->num_vregs; i++)
+		data->regulators[i].supply = vregs[i].name;
+
+	ret = devm_regulator_bulk_get(dev, data->num_vregs, data->regulators);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < data->num_vregs; i++) {
+		ret = regulator_set_load(data->regulators[i].consumer, vregs[i].load_uA);
+		if (ret)
+			return ret;
+	}
+
+	data->desc.name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
+	if (!data->desc.name)
+		return -ENOMEM;
+
+	data->desc.type = REGULATOR_VOLTAGE;
+	data->desc.owner = THIS_MODULE;
+	data->desc.ops = &qca6390_ops;
+
+	cfg.dev = dev;
+	cfg.of_node = dev->of_node;
+	cfg.driver_data = data;
+	cfg.init_data = of_get_regulator_init_data(dev, dev->of_node, &data->desc);
+
+	data->regulator_dev = devm_regulator_register(dev, &data->desc, &cfg);
+	if (IS_ERR(data->regulator_dev)) {
+		ret = PTR_ERR(data->regulator_dev);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, data);
+
+	return 0;
+}
+
+static const struct of_device_id qca6390_of_match[] = {
+	{ .compatible = "qcom,qca6390" },
+};
+
+static struct platform_driver qca6390_driver = {
+	.probe = qca6390_probe,
+	.driver = {
+		.name = "qca6390",
+		.of_match_table = qca6390_of_match,
+	},
+};
+
+module_platform_driver(qca6390_driver);
+MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov@linaro.org>");
+MODULE_DESCRIPTION("Power control for Qualcomm QCA6390/1 BT/WiFi chip");
+MODULE_LICENSE("GPL v2");
-- 
2.30.2


  parent reply	other threads:[~2021-06-21 22:31 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-21 22:31 [PATCH v3 0/7] Add support for Qualcomm QCA639x chips family Dmitry Baryshkov
2021-06-21 22:31 ` [PATCH v3 1/7] dt-bindings: regulator: qcom,qca6390: add binding for QCA6390 device Dmitry Baryshkov
2021-06-21 23:11   ` Add support for Qualcomm QCA639x chips family bluez.test.bot
2021-06-21 22:31 ` Dmitry Baryshkov [this message]
2021-06-22 11:28   ` [PATCH v3 2/7] regulator: qca6390: add support for QCA639x powerup sequence Mark Brown
2021-06-22 14:17     ` Dmitry Baryshkov
2021-06-22 14:38       ` Mark Brown
2021-06-22 16:46         ` Dmitry Baryshkov
2021-06-22 17:08           ` Mark Brown
2021-07-06  7:54   ` Ulf Hansson
2021-07-06 11:55     ` Mark Brown
2021-07-08 10:09       ` Ulf Hansson
2021-07-08 11:37         ` Dmitry Baryshkov
2021-07-14 16:47           ` Rob Herring
2021-07-14 17:10             ` Bjorn Andersson
2021-08-10 11:55             ` Ulf Hansson
2021-08-10 16:03               ` Bjorn Andersson
2021-08-12  9:48                 ` Ulf Hansson
2021-08-12 11:51                   ` Dmitry Baryshkov
2021-07-14 17:23         ` Bjorn Andersson
2021-06-21 22:31 ` [PATCH v3 3/7] Bluetooth: hci_qca: provide default device data Dmitry Baryshkov
2021-07-14 17:27   ` Bjorn Andersson
2021-06-21 22:31 ` [PATCH v3 4/7] Bluetooth: hci_qca: merge qca_power into qca_serdev Dmitry Baryshkov
2021-07-14 17:25   ` Bjorn Andersson
2021-06-21 22:31 ` [PATCH v3 5/7] Bluetooth: hci_qca: merge wcn & non-wcn code paths Dmitry Baryshkov
2021-06-21 22:31 ` [PATCH v3 6/7] Bluetooth: hci_qca: add power sequencer support to qca6390 Dmitry Baryshkov
2021-06-21 22:31 ` [PATCH v3 7/7] arm64: dts: qcom: qrb5165-rb5: add QCA6391 WiFi+BT SoC Dmitry Baryshkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210621223141.1638189-3-dmitry.baryshkov@linaro.org \
    --to=dmitry.baryshkov@linaro.org \
    --cc=agross@kernel.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=broonie@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=johan.hedberg@gmail.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luiz.dentz@gmail.com \
    --cc=manivannan.sadhasivam@linaro.org \
    --cc=marcel@holtmann.org \
    --cc=robh+dt@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).