All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 1/2] regulator: rt6160: Add DT binding document for Richtek RT6160
@ 2021-05-26  5:47 cy_huang
  2021-05-26  5:47 ` [PATCH v4 2/2] regulator: rt6160: Add support " cy_huang
  0 siblings, 1 reply; 7+ messages in thread
From: cy_huang @ 2021-05-26  5:47 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt; +Cc: linux-kernel, cy_huang, devicetree

From: ChiYuan Huang <cy_huang@richtek.com>

Add DT binding document for Richtek RT6160 voltage regulator.

Signed-off-by: ChiYuan Huang <cy_huang@richtek.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
since v4
- Add Reviewed-by.

since v3
- Move all regulator related properties to the upper node.

since v2
- Move buckboost node from patternProperties to Properties.
---
 .../regulator/richtek,rt6160-regulator.yaml        | 61 ++++++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/richtek,rt6160-regulator.yaml

diff --git a/Documentation/devicetree/bindings/regulator/richtek,rt6160-regulator.yaml b/Documentation/devicetree/bindings/regulator/richtek,rt6160-regulator.yaml
new file mode 100644
index 00000000..0534b0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/richtek,rt6160-regulator.yaml
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/richtek,rt6160-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT6160 BuckBoost converter
+
+maintainers:
+  - ChiYuan Huang <cy_huang@richtek.com>
+
+description: |
+  The RT6160 is a high-efficiency buck-boost converter that can provide
+  up to 3A output current from 2025mV to 5200mV. And it support the wide
+  input voltage range from 2200mV to 5500mV.
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT6160A/DS6160A-00.pdf
+
+allOf:
+  - $ref: regulator.yaml#
+
+properties:
+  compatible:
+    enum:
+      - richtek,rt6160
+
+  reg:
+    maxItems: 1
+
+  enable-gpios:
+    description: A connection of the 'enable' gpio line.
+    maxItems: 1
+
+  richtek,vsel-active-low:
+    description: |
+      Used to indicate the 'vsel' pin active level. if not specified, use
+      high active level as the default.
+    type: boolean
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      rt6160@75 {
+        compatible = "richtek,rt6160";
+        reg = <0x75>;
+        enable-gpios = <&gpio26 2 0>;
+        regulator-name = "rt6160-buckboost";
+        regulator-min-microvolt = <2025000>;
+        regulator-max-microvolt = <5200000>;
+      };
+    };
-- 
2.7.4


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

* [PATCH v4 2/2] regulator: rt6160: Add support for Richtek RT6160
  2021-05-26  5:47 [PATCH v4 1/2] regulator: rt6160: Add DT binding document for Richtek RT6160 cy_huang
@ 2021-05-26  5:47 ` cy_huang
  2021-05-26 10:51   ` Mark Brown
  0 siblings, 1 reply; 7+ messages in thread
From: cy_huang @ 2021-05-26  5:47 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt; +Cc: linux-kernel, cy_huang, devicetree

From: ChiYuan Huang <cy_huang@richtek.com>

Add support for Richtek RT6160 voltage regulator. It can provide up
to 3A output current within the adjustable voltage from 2025mV
to 5200mV. It integrate a buckboost converter to support wide input
voltage range from 2200mV to 5500mV.

Signed-off-by: ChiYuan Huang <cy_huang@richtek.com>
---
since v4
- Add of_node into regulator_config to fix regulator_get by device tree node parsing.

since v3
- Use more header file like as of_regulator.h and property.h.
- Change the parsing string from 'richtek,vsel_active_low' to 'richtek,vsel-active-low'.
- Use of_get_regulator_init_data to get the regulator init_data.

since v2
- Fix W=1 warning for of_device_id.
---
 drivers/regulator/Kconfig            |  11 ++
 drivers/regulator/Makefile           |   1 +
 drivers/regulator/rt6160-regulator.c | 270 +++++++++++++++++++++++++++++++++++
 3 files changed, 282 insertions(+)
 create mode 100644 drivers/regulator/rt6160-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 9d84d92..4fe7ddc 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1030,6 +1030,17 @@ config REGULATOR_RT5033
 	  RT5033 PMIC. The device supports multiple regulators like
 	  current source, LDO and Buck.
 
+config REGULATOR_RT6160
+	tristate "Richtek RT6160 BuckBoost voltage regulator"
+	depends on I2C
+	select REGMAP_I2C
+	help
+	  This adds support for voltage regulator in Richtek RT6160.
+	  This device automatically change voltage output mode from
+	  Buck or Boost. The mode transistion depend on the input source voltage.
+	  The wide output range is from 2025mV to 5200mV and can be used on most
+	  common application scenario.
+
 config REGULATOR_RTMV20
 	tristate "RTMV20 Laser Diode Regulator"
 	depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 580b015..5b2c93e 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -124,6 +124,7 @@ obj-$(CONFIG_REGULATOR_ROHM)	+= rohm-regulator.o
 obj-$(CONFIG_REGULATOR_RT4801)	+= rt4801-regulator.o
 obj-$(CONFIG_REGULATOR_RT4831)	+= rt4831-regulator.o
 obj-$(CONFIG_REGULATOR_RT5033)	+= rt5033-regulator.o
+obj-$(CONFIG_REGULATOR_RT6160)	+= rt6160-regulator.o
 obj-$(CONFIG_REGULATOR_RTMV20)	+= rtmv20-regulator.o
 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
diff --git a/drivers/regulator/rt6160-regulator.c b/drivers/regulator/rt6160-regulator.c
new file mode 100644
index 00000000..579e183
--- /dev/null
+++ b/drivers/regulator/rt6160-regulator.c
@@ -0,0 +1,270 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+
+#define RT6160_MODE_AUTO	0
+#define RT6160_MODE_FPWM	1
+
+#define RT6160_REG_CNTL		0x01
+#define RT6160_REG_STATUS	0x02
+#define RT6160_REG_DEVID	0x03
+#define RT6160_REG_VSELL	0x04
+#define RT6160_REG_VSELH	0x05
+
+#define RT6160_FPWM_MASK	BIT(3)
+#define RT6160_RAMPRATE_MASK	GENMASK(1, 0)
+#define RT6160_VID_MASK		GENMASK(7, 4)
+#define RT6160_VSEL_MASK	GENMASK(6, 0)
+#define RT6160_HDSTAT_MASK	BIT(4)
+#define RT6160_UVSTAT_MASK	BIT(3)
+#define RT6160_OCSTAT_MASK	BIT(2)
+#define RT6160_TSDSTAT_MASK	BIT(1)
+#define RT6160_PGSTAT_MASK	BIT(0)
+
+#define RT6160_RAMPRATE_1VMS	0
+#define RT6160_RAMPRATE_2P5VMS	1
+#define RT6160_RAMPRATE_5VMS	2
+#define RT6160_RAMPRATE_10VMS	3
+#define RT6160_VENDOR_ID	0xA0
+#define RT6160_VOUT_MINUV	2025000
+#define RT6160_VOUT_MAXUV	5200000
+#define RT6160_VOUT_STPUV	25000
+#define RT6160_N_VOUTS		((RT6160_VOUT_MAXUV - RT6160_VOUT_MINUV) / RT6160_VOUT_STPUV + 1)
+
+struct rt6160_priv {
+	struct regulator_desc desc;
+	bool vsel_active_low;
+};
+
+static int rt6160_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	struct regmap *regmap = rdev_get_regmap(rdev);
+	unsigned int mode_val;
+
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		mode_val = RT6160_FPWM_MASK;
+		break;
+	case REGULATOR_MODE_NORMAL:
+		mode_val = 0;
+		break;
+	default:
+		dev_err(&rdev->dev, "mode not supported\n");
+		return -EINVAL;
+	}
+
+	return regmap_update_bits(regmap, RT6160_REG_CNTL, RT6160_FPWM_MASK, mode_val);
+}
+
+static unsigned int rt6160_get_mode(struct regulator_dev *rdev)
+{
+	struct regmap *regmap = rdev_get_regmap(rdev);
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(regmap, RT6160_REG_CNTL, &val);
+	if (ret)
+		return ret;
+
+	if (val & RT6160_FPWM_MASK)
+		return REGULATOR_MODE_FAST;
+
+	return REGULATOR_MODE_NORMAL;
+}
+
+static int rt6160_set_suspend_voltage(struct regulator_dev *rdev, int uV)
+{
+	struct rt6160_priv *priv = rdev_get_drvdata(rdev);
+	struct regmap *regmap = rdev_get_regmap(rdev);
+	unsigned int reg = RT6160_REG_VSELH;
+	int vsel;
+
+	vsel = regulator_map_voltage_linear(rdev, uV, uV);
+	if (vsel < 0)
+		return vsel;
+
+	if (priv->vsel_active_low)
+		reg = RT6160_REG_VSELL;
+
+	return regmap_update_bits(regmap, reg, RT6160_VSEL_MASK, vsel);
+}
+
+static int rt6160_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
+{
+	struct regmap *regmap = rdev_get_regmap(rdev);
+	unsigned int ramp_value = RT6160_RAMPRATE_1VMS;
+
+	switch (ramp_delay) {
+	case 1 ... 1000:
+		ramp_value = RT6160_RAMPRATE_1VMS;
+		break;
+	case 1001 ... 2500:
+		ramp_value = RT6160_RAMPRATE_2P5VMS;
+		break;
+	case 2501 ... 5000:
+		ramp_value = RT6160_RAMPRATE_5VMS;
+		break;
+	case 5001 ... 10000:
+		ramp_value = RT6160_RAMPRATE_10VMS;
+		break;
+	default:
+		dev_warn(&rdev->dev, "ramp_delay %d not supported, setting 1000\n", ramp_delay);
+	}
+
+	return regmap_update_bits(regmap, RT6160_REG_CNTL, RT6160_RAMPRATE_MASK, ramp_value);
+}
+
+static int rt6160_get_error_flags(struct regulator_dev *rdev, unsigned int *flags)
+{
+	struct regmap *regmap = rdev_get_regmap(rdev);
+	unsigned int val, events = 0;
+	int ret;
+
+	ret = regmap_read(regmap, RT6160_REG_STATUS, &val);
+	if (ret)
+		return ret;
+
+	if (val & (RT6160_HDSTAT_MASK | RT6160_TSDSTAT_MASK))
+		events |= REGULATOR_ERROR_OVER_TEMP;
+
+	if (val & RT6160_UVSTAT_MASK)
+		events |= REGULATOR_ERROR_UNDER_VOLTAGE;
+
+	if (val & RT6160_OCSTAT_MASK)
+		events |= REGULATOR_ERROR_OVER_CURRENT;
+
+	if (val & RT6160_PGSTAT_MASK)
+		events |= REGULATOR_ERROR_FAIL;
+
+	*flags = events;
+	return 0;
+}
+
+static const struct regulator_ops rt6160_regulator_ops = {
+	.list_voltage = regulator_list_voltage_linear,
+	.set_voltage_sel = regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+
+	.set_mode = rt6160_set_mode,
+	.get_mode = rt6160_get_mode,
+	.set_suspend_voltage = rt6160_set_suspend_voltage,
+	.set_ramp_delay = rt6160_set_ramp_delay,
+	.get_error_flags = rt6160_get_error_flags,
+};
+
+static unsigned int rt6160_of_map_mode(unsigned int mode)
+{
+	if (mode == RT6160_MODE_FPWM)
+		return REGULATOR_MODE_FAST;
+	else if (mode == RT6160_MODE_AUTO)
+		return REGULATOR_MODE_NORMAL;
+
+	return REGULATOR_MODE_INVALID;
+}
+
+static bool rt6160_is_accessible_reg(struct device *dev, unsigned int reg)
+{
+	if (reg >= RT6160_REG_CNTL && reg <= RT6160_REG_VSELH)
+		return true;
+	return false;
+}
+
+static const struct regmap_config rt6160_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = RT6160_REG_VSELH,
+
+	.writeable_reg = rt6160_is_accessible_reg,
+	.readable_reg = rt6160_is_accessible_reg,
+};
+
+static int rt6160_probe(struct i2c_client *i2c)
+{
+	struct rt6160_priv *priv;
+	struct regmap *regmap;
+	struct gpio_desc *enable_gpio;
+	struct regulator_config regulator_cfg = {};
+	struct regulator_dev *rdev;
+	unsigned int devid;
+	int ret;
+
+	priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->vsel_active_low = device_property_present(&i2c->dev, "richtek,vsel-active-low");
+
+	enable_gpio = devm_gpiod_get_optional(&i2c->dev, "enable", GPIOD_OUT_HIGH);
+	if (IS_ERR(enable_gpio)) {
+		dev_err(&i2c->dev, "Failed to get 'enable' gpio\n");
+		return PTR_ERR(enable_gpio);
+	}
+
+	regmap = devm_regmap_init_i2c(i2c, &rt6160_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(&i2c->dev, "Failed to init regmap\n");
+		return PTR_ERR(regmap);
+	}
+
+	ret = regmap_read(regmap, RT6160_REG_DEVID, &devid);
+	if (ret)
+		return ret;
+
+	if ((devid & RT6160_VID_MASK) != RT6160_VENDOR_ID) {
+		dev_err(&i2c->dev, "VID not correct [0x%02x]\n", devid);
+		return -ENODEV;
+	}
+
+	priv->desc.name = "rt6160-buckboost";
+	priv->desc.type = REGULATOR_VOLTAGE;
+	priv->desc.owner = THIS_MODULE;
+	priv->desc.min_uV = RT6160_VOUT_MINUV;
+	priv->desc.uV_step = RT6160_VOUT_STPUV;
+	priv->desc.vsel_reg = RT6160_REG_VSELH;
+	priv->desc.vsel_mask = RT6160_VSEL_MASK;
+	priv->desc.n_voltages = RT6160_N_VOUTS;
+	priv->desc.of_map_mode = rt6160_of_map_mode;
+	priv->desc.ops = &rt6160_regulator_ops;
+	if (priv->vsel_active_low)
+		priv->desc.vsel_reg = RT6160_REG_VSELL;
+
+	regulator_cfg.dev = &i2c->dev;
+	regulator_cfg.of_node = i2c->dev.of_node;
+	regulator_cfg.regmap = regmap;
+	regulator_cfg.driver_data = priv;
+	regulator_cfg.init_data = of_get_regulator_init_data(&i2c->dev, i2c->dev.of_node,
+							     &priv->desc);
+
+	rdev = devm_regulator_register(&i2c->dev, &priv->desc, &regulator_cfg);
+	if (IS_ERR(rdev)) {
+		dev_err(&i2c->dev, "Failed to register regulator\n");
+		return PTR_ERR(rdev);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id __maybe_unused rt6160_of_match_table[] = {
+	{ .compatible = "richtek,rt6160", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, rt6160_of_match_table);
+
+static struct i2c_driver rt6160_driver = {
+	.driver = {
+		.name = "rt6160",
+		.of_match_table = rt6160_of_match_table,
+	},
+	.probe_new = rt6160_probe,
+};
+module_i2c_driver(rt6160_driver);
+
+MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4


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

* Re: [PATCH v4 2/2] regulator: rt6160: Add support for Richtek RT6160
  2021-05-26  5:47 ` [PATCH v4 2/2] regulator: rt6160: Add support " cy_huang
@ 2021-05-26 10:51   ` Mark Brown
  2021-05-26 15:04     ` ChiYuan Huang
  0 siblings, 1 reply; 7+ messages in thread
From: Mark Brown @ 2021-05-26 10:51 UTC (permalink / raw)
  To: cy_huang; +Cc: lgirdwood, robh+dt, linux-kernel, cy_huang, devicetree

[-- Attachment #1: Type: text/plain, Size: 1993 bytes --]

On Wed, May 26, 2021 at 01:47:48PM +0800, cy_huang wrote:

This looks mostly good, a few small issues below:

> +static int rt6160_set_suspend_voltage(struct regulator_dev *rdev, int uV)
> +{
> +	struct rt6160_priv *priv = rdev_get_drvdata(rdev);
> +	struct regmap *regmap = rdev_get_regmap(rdev);
> +	unsigned int reg = RT6160_REG_VSELH;
> +	int vsel;
> +
> +	vsel = regulator_map_voltage_linear(rdev, uV, uV);
> +	if (vsel < 0)
> +		return vsel;
> +
> +	if (priv->vsel_active_low)
> +		reg = RT6160_REG_VSELL;
> +
> +	return regmap_update_bits(regmap, reg, RT6160_VSEL_MASK, vsel);
> +}

This seems to just be updating the normal voltage configuration
regulator, the suspend mode operations are there for devices that
have a hardware suspend mode that's entered as part of the very
low level system suspend process.

> +static int rt6160_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
> +{
> +	struct regmap *regmap = rdev_get_regmap(rdev);
> +	unsigned int ramp_value = RT6160_RAMPRATE_1VMS;
> +
> +	switch (ramp_delay) {
> +	case 1 ... 1000:
> +		ramp_value = RT6160_RAMPRATE_1VMS;
> +		break;

This looks like it could be converted to regulator_set_ramp_delay_regmap()

> +static unsigned int rt6160_of_map_mode(unsigned int mode)
> +{
> +	if (mode == RT6160_MODE_FPWM)
> +		return REGULATOR_MODE_FAST;
> +	else if (mode == RT6160_MODE_AUTO)
> +		return REGULATOR_MODE_NORMAL;
> +

This would be more idiomatically written as a switch statement.

> +	enable_gpio = devm_gpiod_get_optional(&i2c->dev, "enable", GPIOD_OUT_HIGH);
> +	if (IS_ERR(enable_gpio)) {
> +		dev_err(&i2c->dev, "Failed to get 'enable' gpio\n");
> +		return PTR_ERR(enable_gpio);
> +	}

There's no other references to enable_gpio?

> +	regmap = devm_regmap_init_i2c(i2c, &rt6160_regmap_config);
> +	if (IS_ERR(regmap)) {
> +		dev_err(&i2c->dev, "Failed to init regmap\n");
> +		return PTR_ERR(regmap);
> +	}

It's better to print the error code to help anyone who runs into
issues figure out what's wrong.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH v4 2/2] regulator: rt6160: Add support for Richtek RT6160
  2021-05-26 10:51   ` Mark Brown
@ 2021-05-26 15:04     ` ChiYuan Huang
  2021-05-27  3:14       ` ChiYuan Huang
  0 siblings, 1 reply; 7+ messages in thread
From: ChiYuan Huang @ 2021-05-26 15:04 UTC (permalink / raw)
  To: Mark Brown
  Cc: lgirdwood, Rob Herring, lkml, cy_huang,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS

HI:

Mark Brown <broonie@kernel.org> 於 2021年5月26日 週三 下午6:50寫道:
>
> On Wed, May 26, 2021 at 01:47:48PM +0800, cy_huang wrote:
>
> This looks mostly good, a few small issues below:
>
> > +static int rt6160_set_suspend_voltage(struct regulator_dev *rdev, int uV)
> > +{
> > +     struct rt6160_priv *priv = rdev_get_drvdata(rdev);
> > +     struct regmap *regmap = rdev_get_regmap(rdev);
> > +     unsigned int reg = RT6160_REG_VSELH;
> > +     int vsel;
> > +
> > +     vsel = regulator_map_voltage_linear(rdev, uV, uV);
> > +     if (vsel < 0)
> > +             return vsel;
> > +
> > +     if (priv->vsel_active_low)
> > +             reg = RT6160_REG_VSELL;
> > +
> > +     return regmap_update_bits(regmap, reg, RT6160_VSEL_MASK, vsel);
> > +}
>
> This seems to just be updating the normal voltage configuration
> regulator, the suspend mode operations are there for devices that
> have a hardware suspend mode that's entered as part of the very
> low level system suspend process.
>
There's a independent 'vsel' pin. It depend on user's HW design.
And that's why there's a 'richtek,vsel_active_low' property.
Its normal application is to use vsel high active level, and it means
the opposite level can be used for the suspend voltage

And there're also two voltage registers for vsel level high and low.
> > +static int rt6160_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
> > +{
> > +     struct regmap *regmap = rdev_get_regmap(rdev);
> > +     unsigned int ramp_value = RT6160_RAMPRATE_1VMS;
> > +
> > +     switch (ramp_delay) {
> > +     case 1 ... 1000:
> > +             ramp_value = RT6160_RAMPRATE_1VMS;
> > +             break;
>
> This looks like it could be converted to regulator_set_ramp_delay_regmap()
>
I didn't notice there's the regulator_set_ramp_delay_regmap API that
can be used in kernel 5.13.
Ack in next.
> > +static unsigned int rt6160_of_map_mode(unsigned int mode)
> > +{
> > +     if (mode == RT6160_MODE_FPWM)
> > +             return REGULATOR_MODE_FAST;
> > +     else if (mode == RT6160_MODE_AUTO)
> > +             return REGULATOR_MODE_NORMAL;
> > +
>
> This would be more idiomatically written as a switch statement.
>
Ack in next. Change the if-else to switch case. Thx.
> > +     enable_gpio = devm_gpiod_get_optional(&i2c->dev, "enable", GPIOD_OUT_HIGH);
> > +     if (IS_ERR(enable_gpio)) {
> > +             dev_err(&i2c->dev, "Failed to get 'enable' gpio\n");
> > +             return PTR_ERR(enable_gpio);
> > +     }
>
> There's no other references to enable_gpio?
>
The IC is designed for low IQ.
So from the driver probe, I only need to keep 'enable' pin high.
Or if user specify the 'enable' gpio, it will block i2c communication,
register also be reset,
and add more delay time on enable/disable.
That's why there's no other references to 'enable' gpio.
> > +     regmap = devm_regmap_init_i2c(i2c, &rt6160_regmap_config);
> > +     if (IS_ERR(regmap)) {
> > +             dev_err(&i2c->dev, "Failed to init regmap\n");
> > +             return PTR_ERR(regmap);
> > +     }
>
> It's better to print the error code to help anyone who runs into
> issues figure out what's wrong.
Sure, change it to dev_err(&i2c->dev, "Failed to init regmap (%d)\n",
PTR_ERR(regmap));
Ack in next, thx.

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

* Re: [PATCH v4 2/2] regulator: rt6160: Add support for Richtek RT6160
  2021-05-26 15:04     ` ChiYuan Huang
@ 2021-05-27  3:14       ` ChiYuan Huang
  2021-06-01 15:52         ` Mark Brown
  0 siblings, 1 reply; 7+ messages in thread
From: ChiYuan Huang @ 2021-05-27  3:14 UTC (permalink / raw)
  To: Mark Brown
  Cc: lgirdwood, Rob Herring, lkml, cy_huang,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS

HI, Mark:

ChiYuan Huang <u0084500@gmail.com> 於 2021年5月26日 週三 下午11:04寫道:
>
> HI:
>
> Mark Brown <broonie@kernel.org> 於 2021年5月26日 週三 下午6:50寫道:
> >
> > On Wed, May 26, 2021 at 01:47:48PM +0800, cy_huang wrote:
> >
> > This looks mostly good, a few small issues below:
> >
> > > +static int rt6160_set_suspend_voltage(struct regulator_dev *rdev, int uV)
> > > +{
> > > +     struct rt6160_priv *priv = rdev_get_drvdata(rdev);
> > > +     struct regmap *regmap = rdev_get_regmap(rdev);
> > > +     unsigned int reg = RT6160_REG_VSELH;
> > > +     int vsel;
> > > +
> > > +     vsel = regulator_map_voltage_linear(rdev, uV, uV);
> > > +     if (vsel < 0)
> > > +             return vsel;
> > > +
> > > +     if (priv->vsel_active_low)
> > > +             reg = RT6160_REG_VSELL;
> > > +
> > > +     return regmap_update_bits(regmap, reg, RT6160_VSEL_MASK, vsel);
> > > +}
> >
> > This seems to just be updating the normal voltage configuration
> > regulator, the suspend mode operations are there for devices that
> > have a hardware suspend mode that's entered as part of the very
> > low level system suspend process.
> >
> There's a independent 'vsel' pin. It depend on user's HW design.
> And that's why there's a 'richtek,vsel_active_low' property.
> Its normal application is to use vsel high active level, and it means
> the opposite level can be used for the suspend voltage
>
> And there're also two voltage registers for vsel level high and low.
> > > +static int rt6160_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
> > > +{
> > > +     struct regmap *regmap = rdev_get_regmap(rdev);
> > > +     unsigned int ramp_value = RT6160_RAMPRATE_1VMS;
> > > +
> > > +     switch (ramp_delay) {
> > > +     case 1 ... 1000:
> > > +             ramp_value = RT6160_RAMPRATE_1VMS;
> > > +             break;
> >
> > This looks like it could be converted to regulator_set_ramp_delay_regmap()
> >
> I didn't notice there's the regulator_set_ramp_delay_regmap API that
> can be used in kernel 5.13.u
> Ack in next.

I review the regulator_set_ramp_delay_regmap API.
If seems I need to fill in the ramp_delay_table by the descend order.
But this chip ramp delay table is designed the ascending value reg bit
field [0 1 2 3] by
the ascending order [1000 2500 5000 10000] uV/uS
Even if I tried to filler in descending order, I also need a inverted operation.

And I found the regulator_set_ramp_delay_regmap API has some logic error.
From the include/linux/regulator/driver.h, the set_ramp_delay function says to
set the less or equal one ramp delay value.
But your logic will get the larger or equal one from the descending
ramp delay table.

Could you help to check about this?
> > > +static unsigned int rt6160_of_map_mode(unsigned int mode)
> > > +{
> > > +     if (mode == RT6160_MODE_FPWM)
> > > +             return REGULATOR_MODE_FAST;
> > > +     else if (mode == RT6160_MODE_AUTO)
> > > +             return REGULATOR_MODE_NORMAL;
> > > +
> >
> > This would be more idiomatically written as a switch statement.
> >
> Ack in next. Change the if-else to switch case. Thx.
> > > +     enable_gpio = devm_gpiod_get_optional(&i2c->dev, "enable", GPIOD_OUT_HIGH);
> > > +     if (IS_ERR(enable_gpio)) {
> > > +             dev_err(&i2c->dev, "Failed to get 'enable' gpio\n");
> > > +             return PTR_ERR(enable_gpio);
> > > +     }
> >
> > There's no other references to enable_gpio?
> >
> The IC is designed for low IQ.
> So from the driver probe, I only need to keep 'enable' pin high.
> Or if user specify the 'enable' gpio, it will block i2c communication,
> register also be reset,
> and add more delay time on enable/disable.
> That's why there's no other references to 'enable' gpio.
> > > +     regmap = devm_regmap_init_i2c(i2c, &rt6160_regmap_config);
> > > +     if (IS_ERR(regmap)) {
> > > +             dev_err(&i2c->dev, "Failed to init regmap\n");
> > > +             return PTR_ERR(regmap);
> > > +     }
> >
> > It's better to print the error code to help anyone who runs into
> > issues figure out what's wrong.
> Sure, change it to dev_err(&i2c->dev, "Failed to init regmap (%d)\n",
> PTR_ERR(regmap));
> Ack in next, thx.

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

* Re: [PATCH v4 2/2] regulator: rt6160: Add support for Richtek RT6160
  2021-05-27  3:14       ` ChiYuan Huang
@ 2021-06-01 15:52         ` Mark Brown
  2021-06-02  1:48           ` ChiYuan Huang
  0 siblings, 1 reply; 7+ messages in thread
From: Mark Brown @ 2021-06-01 15:52 UTC (permalink / raw)
  To: ChiYuan Huang
  Cc: lgirdwood, Rob Herring, lkml, cy_huang,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS

[-- Attachment #1: Type: text/plain, Size: 1006 bytes --]

On Thu, May 27, 2021 at 11:14:17AM +0800, ChiYuan Huang wrote:

> I review the regulator_set_ramp_delay_regmap API.
> If seems I need to fill in the ramp_delay_table by the descend order.
> But this chip ramp delay table is designed the ascending value reg bit
> field [0 1 2 3] by
> the ascending order [1000 2500 5000 10000] uV/uS
> Even if I tried to filler in descending order, I also need a inverted operation.

I see... that really should be supportable, and I'd have expected
find_closest_bigger() to DTRT here, it's not obvious it's expecting
ordering.

> And I found the regulator_set_ramp_delay_regmap API has some logic error.
> From the include/linux/regulator/driver.h, the set_ramp_delay function says to
> set the less or equal one ramp delay value.
> But your logic will get the larger or equal one from the descending
> ramp delay table.

The code is correct here, the documentation should be fixed - with a
delay like this we should be erring on the side of delaying too long to
be safe.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH v4 2/2] regulator: rt6160: Add support for Richtek RT6160
  2021-06-01 15:52         ` Mark Brown
@ 2021-06-02  1:48           ` ChiYuan Huang
  0 siblings, 0 replies; 7+ messages in thread
From: ChiYuan Huang @ 2021-06-02  1:48 UTC (permalink / raw)
  To: Mark Brown
  Cc: lgirdwood, Rob Herring, lkml, cy_huang,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS

HI, Mark:

Mark Brown <broonie@kernel.org> 於 2021年6月1日 週二 下午11:52寫道:
>
> On Thu, May 27, 2021 at 11:14:17AM +0800, ChiYuan Huang wrote:
>
> > I review the regulator_set_ramp_delay_regmap API.
> > If seems I need to fill in the ramp_delay_table by the descend order.
> > But this chip ramp delay table is designed the ascending value reg bit
> > field [0 1 2 3] by
> > the ascending order [1000 2500 5000 10000] uV/uS
> > Even if I tried to filler in descending order, I also need a inverted operation.
>
> I see... that really should be supportable, and I'd have expected
> find_closest_bigger() to DTRT here, it's not obvious it's expecting
> ordering.
>
> > And I found the regulator_set_ramp_delay_regmap API has some logic error.
> > From the include/linux/regulator/driver.h, the set_ramp_delay function says to
> > set the less or equal one ramp delay value.
> > But your logic will get the larger or equal one from the descending
> > ramp delay table.
>
> The code is correct here, the documentation should be fixed - with a
> delay like this we should be erring on the side of delaying too long to
> be safe.

If so, I will upload v7 patch series to meet this selection logic.
Thanks.

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

end of thread, other threads:[~2021-06-02  1:48 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-26  5:47 [PATCH v4 1/2] regulator: rt6160: Add DT binding document for Richtek RT6160 cy_huang
2021-05-26  5:47 ` [PATCH v4 2/2] regulator: rt6160: Add support " cy_huang
2021-05-26 10:51   ` Mark Brown
2021-05-26 15:04     ` ChiYuan Huang
2021-05-27  3:14       ` ChiYuan Huang
2021-06-01 15:52         ` Mark Brown
2021-06-02  1:48           ` ChiYuan Huang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.