linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Add support for MT6315 regulator
@ 2020-08-03  8:57 Hsin-Hsiung Wang
  2020-08-03  8:57 ` [PATCH 1/3] spmi: Add driver shutdown support Hsin-Hsiung Wang
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Hsin-Hsiung Wang @ 2020-08-03  8:57 UTC (permalink / raw)
  To: Mark Brown, Rob Herring, Matthias Brugger
  Cc: Liam Girdwood, Stephen Boyd, Hsin-Hsiung Wang, linux-kernel,
	devicetree, linux-arm-kernel, linux-mediatek, linux-arm-msm,
	srv_heupstream

This patch series add support for MediaTek PMIC MT6315 regulator driver,
which adds MT6315 related buck voltage data to the driver.

Hsin-Hsiung Wang (3):
  spmi: Add driver shutdown support
  regulator: bindings: Add document for MT6315 regulator
  regulator: mt6315: Add support for MT6315 regulator

 .../bindings/regulator/mt6315-regulator.txt        |  45 +++
 drivers/regulator/Kconfig                          |  10 +
 drivers/regulator/Makefile                         |   1 +
 drivers/regulator/mt6315-regulator.c               | 367 +++++++++++++++++++++
 drivers/spmi/spmi.c                                |  12 +
 include/linux/regulator/mt6315-regulator.h         |  45 +++
 include/linux/spmi.h                               |   1 +
 7 files changed, 481 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/mt6315-regulator.txt
 create mode 100644 drivers/regulator/mt6315-regulator.c
 create mode 100644 include/linux/regulator/mt6315-regulator.h

-- 
2.6.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/3] spmi: Add driver shutdown support
  2020-08-03  8:57 [PATCH 0/3] Add support for MT6315 regulator Hsin-Hsiung Wang
@ 2020-08-03  8:57 ` Hsin-Hsiung Wang
  2020-08-04  1:51   ` Nicolas Boichat
  2020-08-03  8:57 ` [PATCH 2/3] regulator: bindings: Add document for MT6315 regulator Hsin-Hsiung Wang
  2020-08-03  8:57 ` [PATCH 3/3] regulator: mt6315: Add support " Hsin-Hsiung Wang
  2 siblings, 1 reply; 7+ messages in thread
From: Hsin-Hsiung Wang @ 2020-08-03  8:57 UTC (permalink / raw)
  To: Mark Brown, Rob Herring, Matthias Brugger
  Cc: Liam Girdwood, Stephen Boyd, Hsin-Hsiung Wang, linux-kernel,
	devicetree, linux-arm-kernel, linux-mediatek, linux-arm-msm,
	srv_heupstream

Add new shutdown() method.  Use it in the standard driver model style.

Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
---
 drivers/spmi/spmi.c  | 12 ++++++++++++
 drivers/spmi/spmi.c  | 12 ++++++++++++
 include/linux/spmi.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index c16b60f..5fde024 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -357,6 +357,17 @@ static int spmi_drv_remove(struct device *dev)
 	return 0;
 }
 
+static void spmi_drv_shutdown(struct device *dev)
+{
+	const struct spmi_driver *sdrv = to_spmi_driver(dev->driver);
+
+	if (!sdrv)
+		return;
+
+
+	if (sdrv->shutdown)
+		sdrv->shutdown(to_spmi_device(dev));
+}
+}
+
 static int spmi_drv_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
 	int ret;
@@ -373,6 +384,7 @@ static struct bus_type spmi_bus_type = {
@@ -373,6 +384,7 @@ static struct bus_type spmi_bus_type = {
 	.match		= spmi_device_match,
 	.probe		= spmi_drv_probe,
 	.remove		= spmi_drv_remove,
+	.shutdown	= spmi_drv_shutdown,
 	.uevent		= spmi_drv_uevent,
 };
 
diff --git a/include/linux/spmi.h b/include/linux/spmi.h
index 394a3f6..729bcbf 100644
--- a/include/linux/spmi.h
+++ b/include/linux/spmi.h
@@ -138,6 +138,7 @@ struct spmi_driver {
 	struct device_driver driver;
 	int	(*probe)(struct spmi_device *sdev);
 	void	(*remove)(struct spmi_device *sdev);
+	void	(*shutdown)(struct spmi_device *sdev);
 };
 
 static inline struct spmi_driver *to_spmi_driver(struct device_driver *d)
-- 
2.6.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/3] regulator: bindings: Add document for MT6315 regulator
  2020-08-03  8:57 [PATCH 0/3] Add support for MT6315 regulator Hsin-Hsiung Wang
  2020-08-03  8:57 ` [PATCH 1/3] spmi: Add driver shutdown support Hsin-Hsiung Wang
@ 2020-08-03  8:57 ` Hsin-Hsiung Wang
  2020-08-04  2:12   ` Nicolas Boichat
  2020-08-17 21:18   ` Rob Herring
  2020-08-03  8:57 ` [PATCH 3/3] regulator: mt6315: Add support " Hsin-Hsiung Wang
  2 siblings, 2 replies; 7+ messages in thread
From: Hsin-Hsiung Wang @ 2020-08-03  8:57 UTC (permalink / raw)
  To: Mark Brown, Rob Herring, Matthias Brugger
  Cc: Liam Girdwood, Stephen Boyd, Hsin-Hsiung Wang, linux-kernel,
	devicetree, linux-arm-kernel, linux-mediatek, linux-arm-msm,
	srv_heupstream

Add device tree binding information for mt6315 regulator driver.
Example bindings for mt6315 are added.

Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
---
 .../bindings/regulator/mt6315-regulator.txt        | 45 ++++++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/mt6315-regulator.txt

diff --git a/Documentation/devicetree/bindings/regulator/mt6315-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6315-regulator.txt
new file mode 100644
index 0000000..1c14537
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/mt6315-regulator.txt
@@ -0,0 +1,45 @@
+Mediatek MT6315 Regulator
+
+Required properties:
+- compatible: Must be one of the following.
+	"mediatek,mt6315_3-regulator"
+	"mediatek,mt6315_6-regulator"
+	"mediatek,mt6315_7-regulator"
+- reg: SPMI slave id.
+- regulators: List of regulators provided by this controller.
+  The definition for each of these nodes is defined using the standard binding
+  for regulators at Documentation/devicetree/bindings/regulator/regulator.txt.
+
+The valid names for regulators are:
+BUCK:
+  vbuck1, vbuck3, vbuck4
+
+Example:
+	mt6315_3: mt6315@3 {
+		compatible = "mediatek,mt6315_3-regulator";
+		reg = <0x3 0 0xb 1>;
+
+		mt6315_3_vbuck1: vbuck1 {
+			regulator-compatible = "vbuck1";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <1193750>;
+			regulator-enable-ramp-delay = <256>;
+			regulator-allowed-modes = <0 1 2 4>;
+		};
+
+		mt6315_3_vbuck3: vbuck3 {
+			regulator-compatible = "vbuck3";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <1193750>;
+			regulator-enable-ramp-delay = <256>;
+			regulator-allowed-modes = <0 1 2 4>;
+		};
+
+		mt6315_3_vbuck3: vbuck3 {
+			regulator-compatible = "vbuck3";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <1193750>;
+			regulator-enable-ramp-delay = <256>;
+			regulator-allowed-modes = <0 1 2 4>;
+		};
+	};
-- 
2.6.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/3] regulator: mt6315: Add support for MT6315 regulator
  2020-08-03  8:57 [PATCH 0/3] Add support for MT6315 regulator Hsin-Hsiung Wang
  2020-08-03  8:57 ` [PATCH 1/3] spmi: Add driver shutdown support Hsin-Hsiung Wang
  2020-08-03  8:57 ` [PATCH 2/3] regulator: bindings: Add document for MT6315 regulator Hsin-Hsiung Wang
@ 2020-08-03  8:57 ` Hsin-Hsiung Wang
  2 siblings, 0 replies; 7+ messages in thread
From: Hsin-Hsiung Wang @ 2020-08-03  8:57 UTC (permalink / raw)
  To: Mark Brown, Rob Herring, Matthias Brugger
  Cc: Liam Girdwood, Stephen Boyd, Hsin-Hsiung Wang, linux-kernel,
	devicetree, linux-arm-kernel, linux-mediatek, linux-arm-msm,
	srv_heupstream

The MT6315 is a regulator found on boards based on MediaTek MT8192 and
probably other SoCs. It connects as a slave to SoC using SPMI.

Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
---
 drivers/regulator/Kconfig                  |  10 +
 drivers/regulator/Makefile                 |   1 +
 drivers/regulator/mt6315-regulator.c       | 367 +++++++++++++++++++++++++++++
 include/linux/regulator/mt6315-regulator.h |  45 ++++
 4 files changed, 423 insertions(+)
 create mode 100644 drivers/regulator/mt6315-regulator.c
 create mode 100644 include/linux/regulator/mt6315-regulator.h
 create mode 100644 include/linux/regulator/mt6315-regulator.h

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 8f677f5..5b8f28f7 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -673,6 +673,16 @@ config REGULATOR_MT6311
 	  This driver supports the control of different power rails of device
 	  through regulator interface.
 
+config REGULATOR_MT6315
+	tristate "MediaTek MT6315 PMIC"
+	depends on SPMI
+	select REGMAP_SPMI
+	help
+	  Say y here to select this option to enable the power regulator of
+	  MediaTek MT6315 PMIC.
+	  This driver supports the control of different power rails of device
+	  through regulator interface.
+
 config REGULATOR_MT6323
 	tristate "MediaTek MT6323 PMIC"
 	depends on MFD_MT6397
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index e8f1633..742067e 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -84,6 +84,7 @@ obj-$(CONFIG_REGULATOR_MP8859) += mp8859.o
 obj-$(CONFIG_REGULATOR_MP886X) += mp886x.o
 obj-$(CONFIG_REGULATOR_MPQ7920) += mpq7920.o
 obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
+obj-$(CONFIG_REGULATOR_MT6315) += mt6315-regulator.o
 obj-$(CONFIG_REGULATOR_MT6323)	+= mt6323-regulator.o
 obj-$(CONFIG_REGULATOR_MT6358)	+= mt6358-regulator.o
 obj-$(CONFIG_REGULATOR_MT6380)	+= mt6380-regulator.o
diff --git a/drivers/regulator/mt6315-regulator.c b/drivers/regulator/mt6315-regulator.c
new file mode 100644
index 0000000..a855e70
--- /dev/null
+++ b/drivers/regulator/mt6315-regulator.c
@@ -0,0 +1,367 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2020 MediaTek Inc.
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/mt6315-regulator.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/spmi.h>
+
+#define MT6315_REG_WIDTH	8
+
+#define MT6315_BUCK_MODE_AUTO		0
+#define MT6315_BUCK_MODE_FORCE_PWM	1
+#define MT6315_BUCK_MODE_NORMAL		0
+#define MT6315_BUCK_MODE_LP		2
+
+struct mt6315_regulator_info {
+	struct regulator_desc desc;
+	u32 da_vsel_reg;
+	u32 da_reg;
+	u32 qi;
+	u32 modeset_reg;
+	u32 modeset_mask;
+	u32 lp_mode_reg;
+	u32 lp_mode_mask;
+	u32 lp_mode_shift;
+};
+};
+
+struct mt6315_init_data {
+struct mt6315_init_data {
+	u32 id;
+	u32 size;
+	u32 buck1_modeset_mask;
+};
+
+
+struct mt6315_chip {
+	struct device *dev;
+	struct regmap *regmap;
+	u32 slave_id;
+};
+
+#define MT_BUCK(match, _name, volt_ranges, _bid, _vsel, _modeset_mask)	\
+[MT6315_ID_##_name] = {					\
+	.desc = {					\
+		.name = #_name,				\
+		.of_match = of_match_ptr(match),	\
+		.ops = &mt6315_volt_range_ops,		\
+		.type = REGULATOR_VOLTAGE,		\
+		.id = MT6315_ID_##_name,		\
+		.owner = THIS_MODULE,			\
+		.n_voltages = 0xbf,			\
+		.linear_ranges = volt_ranges,		\
+		.n_linear_ranges = ARRAY_SIZE(volt_ranges),	\
+		.vsel_reg = _vsel,			\
+		.vsel_mask = 0xff,			\
+		.enable_reg = MT6315_BUCK_TOP_CON0,	\
+		.enable_mask = BIT(_bid - 1),		\
+		.of_map_mode = mt6315_map_mode,		\
+	},						\
+	.da_vsel_reg = MT6315_BUCK_VBUCK##_bid##_DBG0,	\
+	.da_reg = MT6315_BUCK_VBUCK##_bid##_DBG4,	\
+	.qi = BIT(0),					\
+	.lp_mode_reg = MT6315_BUCK_TOP_CON1,		\
+	.lp_mode_mask = BIT(_bid - 1),			\
+	.lp_mode_shift = _bid - 1,			\
+	.modeset_reg = MT6315_BUCK_TOP_4PHASE_ANA_CON42,	\
+	.modeset_mask = _modeset_mask,			\
+}
+
+static const struct linear_range mt_volt_range1[] = {
+	REGULATOR_LINEAR_RANGE(0, 0, 0xbf, 6250),
+};
+
+static unsigned int mt6315_map_mode(u32 mode)
+{
+	switch (mode) {
+	case MT6315_BUCK_MODE_AUTO:
+		return REGULATOR_MODE_NORMAL;
+	case MT6315_BUCK_MODE_FORCE_PWM:
+		return REGULATOR_MODE_FAST;
+	case MT6315_BUCK_MODE_LP:
+		return REGULATOR_MODE_IDLE;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mt6315_regulator_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct mt6315_regulator_info *info = rdev_get_drvdata(rdev);
+	int ret = 0, reg_addr = 0, reg_val = 0, reg_en = 0;
+
+	ret = regmap_read(rdev->regmap, info->da_reg, &reg_en);
+	if (ret != 0) {
+		dev_notice(&rdev->dev, "Failed to get enable reg: %d\n", ret);
+		return ret;
+	}
+
+	if (reg_en & info->qi)
+		reg_addr = info->da_vsel_reg;
+	else
+		reg_addr = rdev->desc->vsel_reg;
+
+	ret = regmap_read(rdev->regmap, reg_addr, &reg_val);
+	if (ret != 0) {
+		dev_err(&rdev->dev,
+			"Failed to get mt6315 regulator voltage: %d\n", ret);
+		return ret;
+	}
+
+	ret = reg_val & rdev->desc->vsel_mask;
+	return ret;
+}
+
+static unsigned int mt6315_regulator_get_mode(struct regulator_dev *rdev)
+{
+	struct mt6315_regulator_info *info = rdev_get_drvdata(rdev);
+	struct mt6315_init_data *pdata = dev_get_drvdata(rdev->dev.parent);
+	int ret = 0, regval = 0;
+	u32 modeset_mask;
+
+	ret = regmap_read(rdev->regmap, info->modeset_reg, &regval);
+	if (ret != 0) {
+		dev_err(&rdev->dev,
+			"Failed to get mt6315 buck mode: %d\n", ret);
+		return ret;
+	}
+
+	if (rdev_get_id(rdev) == MT6315_ID_VBUCK1)
+		modeset_mask = pdata->buck1_modeset_mask;
+	else
+		modeset_mask = info->modeset_mask;
+
+	if ((regval & modeset_mask) == modeset_mask)
+		return REGULATOR_MODE_FAST;
+
+	ret = regmap_read(rdev->regmap, info->lp_mode_reg, &regval);
+	if (ret != 0) {
+		dev_err(&rdev->dev,
+			"Failed to get mt6315 buck lp mode: %d\n", ret);
+		return ret;
+	}
+
+	if (regval & info->lp_mode_mask)
+		return REGULATOR_MODE_IDLE;
+	else
+		return REGULATOR_MODE_NORMAL;
+}
+
+static int mt6315_regulator_set_mode(struct regulator_dev *rdev,
+				     u32 mode)
+{
+	struct mt6315_regulator_info *info = rdev_get_drvdata(rdev);
+	struct mt6315_init_data *pdata = dev_get_drvdata(rdev->dev.parent);
+	int ret = 0, val, curr_mode;
+	u32 modeset_mask;
+
+	if (rdev_get_id(rdev) == MT6315_ID_VBUCK1)
+		modeset_mask = pdata->buck1_modeset_mask;
+	else
+		modeset_mask = info->modeset_mask;
+
+	curr_mode = mt6315_regulator_get_mode(rdev);
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		ret = regmap_update_bits(rdev->regmap,
+					 info->modeset_reg,
+					 modeset_mask,
+					 modeset_mask);
+		break;
+	case REGULATOR_MODE_NORMAL:
+		if (curr_mode == REGULATOR_MODE_FAST) {
+			ret = regmap_update_bits(rdev->regmap,
+						 info->modeset_reg,
+						 modeset_mask,
+						 0);
+		} else if (curr_mode == REGULATOR_MODE_IDLE) {
+			ret = regmap_update_bits(rdev->regmap,
+						 info->lp_mode_reg,
+						 info->lp_mode_mask,
+						 0);
+			usleep_range(100, 110);
+		}
+		break;
+	case REGULATOR_MODE_IDLE:
+		val = MT6315_BUCK_MODE_LP >> 1;
+		val <<= info->lp_mode_shift;
+		ret = regmap_update_bits(rdev->regmap,
+					 info->lp_mode_reg,
+					 info->lp_mode_mask,
+					 val);
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_mode;
+	}
+
+err_mode:
+	if (ret != 0) {
+		dev_err(&rdev->dev,
+			"Failed to set mt6315 buck mode: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mt6315_get_status(struct regulator_dev *rdev)
+{
+	int ret = 0;
+	u32 regval = 0;
+	struct mt6315_regulator_info *info = rdev_get_drvdata(rdev);
+
+	ret = regmap_read(rdev->regmap, info->da_reg, &regval);
+	if (ret != 0) {
+		dev_notice(&rdev->dev, "Failed to get enable reg: %d\n", ret);
+		return ret;
+	}
+
+	return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
+}
+
+static const struct regulator_ops mt6315_volt_range_ops = {
+	.list_voltage = regulator_list_voltage_linear_range,
+	.map_voltage = regulator_map_voltage_linear_range,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = mt6315_regulator_get_voltage_sel,
+	.set_voltage_time_sel = regulator_set_voltage_time_sel,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.get_status = mt6315_get_status,
+	.set_mode = mt6315_regulator_set_mode,
+	.get_mode = mt6315_regulator_get_mode,
+};
+
+static struct mt6315_regulator_info mt6315_regulators[] = {
+	MT_BUCK("vbuck1", VBUCK1, mt_volt_range1, 1,
+		MT6315_BUCK_TOP_ELR0, 0),
+	MT_BUCK("vbuck3", VBUCK3, mt_volt_range1, 3,
+		MT6315_BUCK_TOP_ELR4, 0x4),
+	MT_BUCK("vbuck4", VBUCK4, mt_volt_range1, 4,
+		MT6315_BUCK_TOP_ELR6, 0x8),
+};
+
+static const struct mt6315_init_data mt6315_3_init_data = {
+	.id = MT6315_SLAVE_ID_3,
+	.size = MT6315_ID_3_MAX,
+	.buck1_modeset_mask = 0x3,
+};
+
+static const struct mt6315_init_data mt6315_6_init_data = {
+	.id = MT6315_SLAVE_ID_6,
+	.size = MT6315_ID_6_MAX,
+	.buck1_modeset_mask = 0xB,
+};
+
+static const struct mt6315_init_data mt6315_7_init_data = {
+	.id = MT6315_SLAVE_ID_7,
+	.size = MT6315_ID_7_MAX,
+	.buck1_modeset_mask = 0x3,
+};
+
+static const struct regmap_config mt6315_regmap_config = {
+	.reg_bits	= 16,
+	.val_bits	= 8,
+	.max_register	= 0x16d0,
+	.fast_io	= true,
+};
+
+static const struct of_device_id mt6315_of_match[] = {
+	{
+		.compatible = "mediatek,mt6315_3-regulator",
+		.data = &mt6315_3_init_data,
+	}, {
+		.compatible = "mediatek,mt6315_6-regulator",
+		.data = &mt6315_6_init_data,
+	}, {
+		.compatible = "mediatek,mt6315_7-regulator",
+		.data = &mt6315_7_init_data,
+	}, {
+		/* sentinel */
+	},
+};
+MODULE_DEVICE_TABLE(of, mt6315_of_match);
+
+static int mt6315_regulator_probe(struct spmi_device *pdev)
+{
+	const struct of_device_id *of_id;
+	struct device *dev = &pdev->dev;
+	struct regmap *regmap;
+	struct mt6315_init_data *pdata;
+	struct mt6315_chip *chip;
+	struct regulator_config config = {};
+	struct regulator_dev *rdev;
+	int i;
+
+	regmap = devm_regmap_init_spmi_ext(pdev, &mt6315_regmap_config);
+	if (!regmap)
+		return -ENODEV;
+
+	chip = devm_kzalloc(dev, sizeof(struct mt6315_chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	of_id = of_match_device(mt6315_of_match, dev);
+	if (!of_id || !of_id->data)
+		return -ENODEV;
+
+	pdata = (struct mt6315_init_data *)of_id->data;
+	chip->slave_id = pdata->id;
+	chip->dev = dev;
+	chip->regmap = regmap;
+	dev_set_drvdata(dev, chip);
+
+	for (i = 0; i < pdata->size; i++) {
+		config.dev = dev;
+		config.driver_data = (mt6315_regulators + i);
+		config.regmap = regmap;
+		rdev = devm_regulator_register(dev,
+					       &(mt6315_regulators + i)->desc, &config);
+		if (IS_ERR(rdev)) {
+			dev_err(dev, "failed to register %s\n",
+				(mt6315_regulators + i)->desc.name);
+			continue;
+		}
+	}
+
+	return 0;
+}
+
+static void mt6315_regulator_shutdown(struct spmi_device *pdev)
+{
+	struct mt6315_chip *chip = dev_get_drvdata(&pdev->dev);
+	int ret = 0;
+
+	ret |= regmap_write(chip->regmap,
+				MT6315_TOP_TMA_KEY_H, PROTECTION_KEY_H);
+	ret |= regmap_write(chip->regmap, MT6315_TOP_TMA_KEY, PROTECTION_KEY);
+	ret |= regmap_update_bits(chip->regmap, MT6315_TOP2_ELR7, 1, 1);
+	ret |= regmap_write(chip->regmap, MT6315_TOP_TMA_KEY, 0);
+	ret |= regmap_write(chip->regmap, MT6315_TOP_TMA_KEY_H, 0);
+	if (ret < 0)
+		dev_err(&pdev->dev, "%s: SLV_%d enable power off sequence failed.\n",
+			__func__, chip->slave_id);
+}
+
+static struct spmi_driver mt6315_regulator_driver = {
+	.driver		= {
+		.name	= "mt6315-regulator",
+		.of_match_table = mt6315_of_match,
+	},
+	.probe = mt6315_regulator_probe,
+	.shutdown = mt6315_regulator_shutdown,
+};
+
+module_spmi_driver(mt6315_regulator_driver);
+
+MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>");
+MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6315 PMIC");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/regulator/mt6315-regulator.h b/include/linux/regulator/mt6315-regulator.h
new file mode 100644
index 0000000..180049b0
--- /dev/null
+++ b/include/linux/regulator/mt6315-regulator.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#ifndef __LINUX_REGULATOR_MT6315_H
+#define __LINUX_REGULATOR_MT6315_H
+
+#define MT6315_SLAVE_ID_3	3
+#define MT6315_SLAVE_ID_6	6
+#define MT6315_SLAVE_ID_7	7
+
+#define MT6315_ID_3_MAX	3
+#define MT6315_ID_6_MAX	2
+#define MT6315_ID_7_MAX	2
+
+enum {
+	MT6315_ID_VBUCK1 = 0,
+	MT6315_ID_VBUCK3,
+	MT6315_ID_VBUCK4,
+	MT6315_ID_MAX,
+};
+
+/* Register */
+#define MT6315_SWCID_H	0xb
+#define MT6315_TOP2_ELR7	0x139
+#define MT6315_TOP_TMA_KEY	0x39f
+#define MT6315_TOP_TMA_KEY_H	0x3a0
+#define MT6315_BUCK_TOP_CON0	0x1440
+#define MT6315_BUCK_TOP_CON1	0x1443
+#define MT6315_BUCK_TOP_ELR0	0x1449
+#define MT6315_BUCK_TOP_ELR4	0x144d
+#define MT6315_BUCK_TOP_ELR6	0x144f
+#define MT6315_BUCK_VBUCK1_DBG0	0x1499
+#define MT6315_BUCK_VBUCK1_DBG4	0x149d
+#define MT6315_BUCK_VBUCK3_DBG0	0x1599
+#define MT6315_BUCK_VBUCK3_DBG4	0x159d
+#define MT6315_BUCK_VBUCK4_DBG0	0x1619
+#define MT6315_BUCK_VBUCK4_DBG4	0x161d
+#define MT6315_BUCK_TOP_4PHASE_ANA_CON42	0x16b1
+
+#define PROTECTION_KEY_H 0x9C
+#define PROTECTION_KEY 0xEA
+
+#endif /* __LINUX_REGULATOR_MT6315_H */
-- 
2.6.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/3] spmi: Add driver shutdown support
  2020-08-03  8:57 ` [PATCH 1/3] spmi: Add driver shutdown support Hsin-Hsiung Wang
@ 2020-08-04  1:51   ` Nicolas Boichat
  0 siblings, 0 replies; 7+ messages in thread
From: Nicolas Boichat @ 2020-08-04  1:51 UTC (permalink / raw)
  To: Hsin-Hsiung Wang
  Cc: Mark Brown, Rob Herring, Matthias Brugger, Liam Girdwood,
	Stephen Boyd, lkml, Devicetree List, linux-arm Mailing List,
	moderated list:ARM/Mediatek SoC support, linux-arm-msm,
	srv_heupstream

On Mon, Aug 3, 2020 at 4:57 PM Hsin-Hsiung Wang
<hsin-hsiung.wang@mediatek.com> wrote:
>
> Add new shutdown() method.  Use it in the standard driver model style.
>
> Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
> ---
>  drivers/spmi/spmi.c  | 12 ++++++++++++
>  drivers/spmi/spmi.c  | 12 ++++++++++++
>  include/linux/spmi.h |  1 +
>  2 files changed, 13 insertions(+)
>
> diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
> index c16b60f..5fde024 100644
> --- a/drivers/spmi/spmi.c
> +++ b/drivers/spmi/spmi.c
> @@ -357,6 +357,17 @@ static int spmi_drv_remove(struct device *dev)
>         return 0;
>  }
>
> +static void spmi_drv_shutdown(struct device *dev)
> +{
> +       const struct spmi_driver *sdrv = to_spmi_driver(dev->driver);
> +
> +       if (!sdrv)
> +               return;
> +
> +
> +       if (sdrv->shutdown)
> +               sdrv->shutdown(to_spmi_device(dev));

Slight more succinct (assuming sdrv _can_ actually be NULL, I'm not
sure about that)

if (srdv && sdrv->shutdown)

> +}
> +}
> +
>  static int spmi_drv_uevent(struct device *dev, struct kobj_uevent_env *env)
>  {
>         int ret;
> @@ -373,6 +384,7 @@ static struct bus_type spmi_bus_type = {
> @@ -373,6 +384,7 @@ static struct bus_type spmi_bus_type = {
>         .match          = spmi_device_match,
>         .probe          = spmi_drv_probe,
>         .remove         = spmi_drv_remove,
> +       .shutdown       = spmi_drv_shutdown,
>         .uevent         = spmi_drv_uevent,
>  };
>
> diff --git a/include/linux/spmi.h b/include/linux/spmi.h
> index 394a3f6..729bcbf 100644
> --- a/include/linux/spmi.h
> +++ b/include/linux/spmi.h
> @@ -138,6 +138,7 @@ struct spmi_driver {
>         struct device_driver driver;
>         int     (*probe)(struct spmi_device *sdev);
>         void    (*remove)(struct spmi_device *sdev);
> +       void    (*shutdown)(struct spmi_device *sdev);
>  };
>
>  static inline struct spmi_driver *to_spmi_driver(struct device_driver *d)
> --
> 2.6.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/3] regulator: bindings: Add document for MT6315 regulator
  2020-08-03  8:57 ` [PATCH 2/3] regulator: bindings: Add document for MT6315 regulator Hsin-Hsiung Wang
@ 2020-08-04  2:12   ` Nicolas Boichat
  2020-08-17 21:18   ` Rob Herring
  1 sibling, 0 replies; 7+ messages in thread
From: Nicolas Boichat @ 2020-08-04  2:12 UTC (permalink / raw)
  To: Hsin-Hsiung Wang
  Cc: Mark Brown, Rob Herring, Matthias Brugger, Liam Girdwood,
	Stephen Boyd, lkml, Devicetree List, linux-arm Mailing List,
	moderated list:ARM/Mediatek SoC support, linux-arm-msm,
	srv_heupstream, Fei Shao

Hi Hsin-Hsiung,

On Mon, Aug 3, 2020 at 4:57 PM Hsin-Hsiung Wang
<hsin-hsiung.wang@mediatek.com> wrote:
>
> Add device tree binding information for mt6315 regulator driver.
> Example bindings for mt6315 are added.
>
> Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
> ---
>  .../bindings/regulator/mt6315-regulator.txt        | 45 ++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/regulator/mt6315-regulator.txt
>
> diff --git a/Documentation/devicetree/bindings/regulator/mt6315-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6315-regulator.txt
> new file mode 100644
> index 0000000..1c14537
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/mt6315-regulator.txt
> @@ -0,0 +1,45 @@
> +Mediatek MT6315 Regulator
> +
> +Required properties:
> +- compatible: Must be one of the following.
> +       "mediatek,mt6315_3-regulator"
> +       "mediatek,mt6315_6-regulator"
> +       "mediatek,mt6315_7-regulator"

As highlighted on Gerrit [1], I think this is wrong. The device tree
compatible should focus on actual hardware differences, _not_ the way
the device is used.

So I looked at the datasheet, and there are 5 variants of the MT6315.
They all have the same number of VBUCKs, just with different _default_
voltages, Imax, and sequencing. Since the regulator range is the same,
I don't think you need to care about any of this, so I'd have a single
compatible "mediatek,mt6315-regulator".

The one thing that is special here, though, is that you want to
combine regulators for BUCK1, right?

That is, for MT6315PP (id 6), you want to combine BUCK1/2/4 to power
the big cores (hence 0xb = "1011" in patch 3/3), and for MT6315SP (id
7), you want to combine BUCK1/2 (hence 0x3 = 0011).

So, instead of a table here, what I'd do is to figure out a way to
indicate, in the device tree, that bucks 1, 2, 4 need to be combined.

I think the correct way to handle this is to add a
`regulator-coupled-with` property. That is you'd have a device tree
that looks like this:

mt6315_6: mt6315@6 {
    compatible = "mediatek,mt6315-regulator";
    reg = <0x6 0 0xb 1>;
    mt6315_6_vbuck1: vbuck1 {
        regulator-compatible = "vbuck1";
        ...
        regulator-coupled-with = <&mt6315_6_vbuck2, mt6315_6_vbuck4>;
    };

    mt6315_6_vbuck2: vbuck2 {
        regulator-compatible = "vbuck2";
        ...
    };

    mt6315_6_vbuck3: vbuck3 {
        regulator-compatible = "vbuck3";
        ...
    };

    mt6315_6_vbuck4: vbuck4 {
        regulator-compatible = "vbuck4";
        ...
    };
};

Then, at probe time, you can figure out which regulators are coupled
with another one, and only provide controls for the first regulator in
the list (with the proper mask).

Another, simpler way, may look like this:

mt6315_6: mt6315@6 {
    compatible = "mediatek,mt6315-regulator";
    reg = <0x6 0 0xb 1>;
    mt6315_6_vbuck1: vbuck1 {
        regulator-compatible = "vbuck1";
        regulator-mask = <0xb>;
    };
    mt6315_6_vbuck3: vbuck3 {
        regulator-compatible = "vbuck3";
        regulator-mask = <0x8>;
    };
};

But then it's a bit weird, because 0x8 = 1 << 3, which we can already
infer from "vbuck3" compatible...

[1] https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2229019/13/drivers/regulator/mt6315-regulator.c#283


> +- reg: SPMI slave id.
> +- regulators: List of regulators provided by this controller.
> +  The definition for each of these nodes is defined using the standard binding
> +  for regulators at Documentation/devicetree/bindings/regulator/regulator.txt.
> +
> +The valid names for regulators are:
> +BUCK:
> +  vbuck1, vbuck3, vbuck4
> +
> +Example:
> +       mt6315_3: mt6315@3 {
> +               compatible = "mediatek,mt6315_3-regulator";
> +               reg = <0x3 0 0xb 1>;
> +
> +               mt6315_3_vbuck1: vbuck1 {
> +                       regulator-compatible = "vbuck1";
> +                       regulator-min-microvolt = <300000>;
> +                       regulator-max-microvolt = <1193750>;
> +                       regulator-enable-ramp-delay = <256>;
> +                       regulator-allowed-modes = <0 1 2 4>;
> +               };
> +
> +               mt6315_3_vbuck3: vbuck3 {
> +                       regulator-compatible = "vbuck3";
> +                       regulator-min-microvolt = <300000>;
> +                       regulator-max-microvolt = <1193750>;
> +                       regulator-enable-ramp-delay = <256>;
> +                       regulator-allowed-modes = <0 1 2 4>;
> +               };
> +
> +               mt6315_3_vbuck3: vbuck3 {
> +                       regulator-compatible = "vbuck3";
> +                       regulator-min-microvolt = <300000>;
> +                       regulator-max-microvolt = <1193750>;
> +                       regulator-enable-ramp-delay = <256>;
> +                       regulator-allowed-modes = <0 1 2 4>;
> +               };
> +       };
> --
> 2.6.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/3] regulator: bindings: Add document for MT6315 regulator
  2020-08-03  8:57 ` [PATCH 2/3] regulator: bindings: Add document for MT6315 regulator Hsin-Hsiung Wang
  2020-08-04  2:12   ` Nicolas Boichat
@ 2020-08-17 21:18   ` Rob Herring
  1 sibling, 0 replies; 7+ messages in thread
From: Rob Herring @ 2020-08-17 21:18 UTC (permalink / raw)
  To: Hsin-Hsiung Wang
  Cc: Mark Brown, Matthias Brugger, Liam Girdwood, Stephen Boyd,
	linux-kernel, devicetree, linux-arm-kernel, linux-mediatek,
	linux-arm-msm, srv_heupstream

On Mon, Aug 03, 2020 at 04:57:26PM +0800, Hsin-Hsiung Wang wrote:
> Add device tree binding information for mt6315 regulator driver.
> Example bindings for mt6315 are added.
> 
> Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
> ---
>  .../bindings/regulator/mt6315-regulator.txt        | 45 ++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/regulator/mt6315-regulator.txt

Bindings should be DT schema format now.

Rob

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-08-17 21:18 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-03  8:57 [PATCH 0/3] Add support for MT6315 regulator Hsin-Hsiung Wang
2020-08-03  8:57 ` [PATCH 1/3] spmi: Add driver shutdown support Hsin-Hsiung Wang
2020-08-04  1:51   ` Nicolas Boichat
2020-08-03  8:57 ` [PATCH 2/3] regulator: bindings: Add document for MT6315 regulator Hsin-Hsiung Wang
2020-08-04  2:12   ` Nicolas Boichat
2020-08-17 21:18   ` Rob Herring
2020-08-03  8:57 ` [PATCH 3/3] regulator: mt6315: Add support " Hsin-Hsiung Wang

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).