Devicetree
 help / color / mirror / Atom feed
* [PATCH v2 0/2] regulator: Add TPS65185
@ 2025-12-27 10:20 Andreas Kemnade
  2025-12-27 10:20 ` [PATCH v2 1/2] dt-bindings: regulator: Document TI TPS65185 Andreas Kemnade
  2025-12-27 10:20 ` [PATCH v2 2/2] regulator: Add TPS65185 driver Andreas Kemnade
  0 siblings, 2 replies; 7+ messages in thread
From: Andreas Kemnade @ 2025-12-27 10:20 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Guenter Roeck
  Cc: linux-kernel, devicetree, linux-hwmon, Andreas Kemnade

Add a driver for the TPS65185 regulator which provides the
comparatively high voltages needed for electronic paper displays.

Datasheet for the TPS65185 is at https://www.ti.com/lit/gpn/tps65185

To simplify things, include the hwmon part directly which is only
one temperature sensor and there are no other functions besides regulators
in this chip.

Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
---
Changes in v2:
- try to find a more common subject line for bindings patch
- align pwr-good name to pin name
- remove runtime pm
- make vin supply non-optional
- use more standard regulator ops
- Link to v1: https://patch.msgid.link/20251222-tps65185-submit-v1-0-34986b504d5f@kemnade.info

---
Andreas Kemnade (2):
      dt-bindings: regulator: Document TI TPS65185
      regulator: Add TPS65185 driver

 .../devicetree/bindings/regulator/ti,tps65185.yaml |  99 +++++
 drivers/regulator/Kconfig                          |  11 +
 drivers/regulator/Makefile                         |   1 +
 drivers/regulator/tps65185.c                       | 454 +++++++++++++++++++++
 4 files changed, 565 insertions(+)
---
base-commit: 9448598b22c50c8a5bb77a9103e2d49f134c9578
change-id: 20251222-tps65185-submit-272cc756e0ad

Best regards,
--  
Andreas Kemnade <andreas@kemnade.info>


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

* [PATCH v2 1/2] dt-bindings: regulator: Document TI TPS65185
  2025-12-27 10:20 [PATCH v2 0/2] regulator: Add TPS65185 Andreas Kemnade
@ 2025-12-27 10:20 ` Andreas Kemnade
  2025-12-30  9:08   ` Krzysztof Kozlowski
  2025-12-27 10:20 ` [PATCH v2 2/2] regulator: Add TPS65185 driver Andreas Kemnade
  1 sibling, 1 reply; 7+ messages in thread
From: Andreas Kemnade @ 2025-12-27 10:20 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Guenter Roeck
  Cc: linux-kernel, devicetree, linux-hwmon, Andreas Kemnade

Document the TPS65185. GPIO names are same as in the datasheet except for
the PWRUP pad which is described as "enable". That pin is optional because
the rising edge corresponds to setting one register bit and falling edge
to another register bit.

Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
---
 .../devicetree/bindings/regulator/ti,tps65185.yaml | 99 ++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/Documentation/devicetree/bindings/regulator/ti,tps65185.yaml b/Documentation/devicetree/bindings/regulator/ti,tps65185.yaml
new file mode 100644
index 000000000000..7cc5a895c2fc
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/ti,tps65185.yaml
@@ -0,0 +1,99 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/ti,tps65185.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI TPS65185 Power Management Integrated Circuit
+
+maintainers:
+  - Andreas Kemnade <andreas@kemnade.info>
+
+description:
+  TPS65185 is a Power Management IC to provide Power for EPDs with one 3.3V
+  switch, 2 symmetric LDOs behind 2 DC/DC converters, and one unsymmetric
+  regulator for a compensation voltage.
+
+properties:
+  compatible:
+    const: ti,tps65185
+
+  reg:
+    maxItems: 1
+
+  enable-gpios:
+    description:
+      PWRUP pin
+    maxItems: 1
+
+  pwr-good-gpios:
+    maxItems: 1
+
+  vcom-ctrl-gpios:
+    maxItems: 1
+
+  wakeup-gpios:
+    maxItems: 1
+
+  vin-supply:
+    description:
+      Supply for the whole chip. Some vendor kernels and devicetrees
+      declare this as a non-existing GPIO named "pwrall".
+
+  interrupts:
+    maxItems: 1
+
+  regulators:
+    type: object
+    additionalProperties: false
+    patternProperties:
+      "^(vcom|vposneg|v3p3)$":
+        unevaluatedProperties: false
+        type: object
+        $ref: /schemas/regulator/regulator.yaml
+
+required:
+  - compatible
+  - reg
+  - pwr-good-gpios
+  - vin-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pmic@18 {
+            compatible = "ti,tps65185";
+            reg = <0x18>;
+            pinctrl-names = "default";
+            pinctrl-0 = <&pinctrl_tps65185_gpio>;
+            pwr-good-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>;
+            vcom-ctrl-gpios = <&gpio2 9 GPIO_ACTIVE_HIGH>;
+            enable-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>;
+            wakeup-gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>;
+            vin-supply = <&epdc_pmic_supply>;
+            interrupts-extended = <&gpio2 0 IRQ_TYPE_LEVEL_LOW>;
+
+            regulators {
+                vcom {
+                    regulator-name = "vcom";
+                };
+
+                vposneg {
+                    regulator-name = "vposneg";
+                    regulator-min-microvolt = <15000000>;
+                    regulator-max-microvolt = <15000000>;
+                };
+
+                v3p3 {
+                    regulator-name = "v3p3";
+                };
+            };
+        };
+    };

-- 
2.47.3


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

* [PATCH v2 2/2] regulator: Add TPS65185 driver
  2025-12-27 10:20 [PATCH v2 0/2] regulator: Add TPS65185 Andreas Kemnade
  2025-12-27 10:20 ` [PATCH v2 1/2] dt-bindings: regulator: Document TI TPS65185 Andreas Kemnade
@ 2025-12-27 10:20 ` Andreas Kemnade
  2025-12-27 16:33   ` Josua Mayer
  1 sibling, 1 reply; 7+ messages in thread
From: Andreas Kemnade @ 2025-12-27 10:20 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Guenter Roeck
  Cc: linux-kernel, devicetree, linux-hwmon, Andreas Kemnade

Add a driver for the TPS65185 regulator. Implement handling of the various
gpio pins. Because the PWRUP (=enable) pin functionality can be achieved
by just using two bits instead, just ensure that it is set to a stable
value.
Implement the pair of symmetric LDOs as a single regulator because they
share a single voltage set register. As the VCOM regulator sits behind that
machinery, just define that one as a supply.
For simplicity, just add the temperature sensor (depending on external NTC)
directly.

There is a mechanism to measure some kick-back voltage during a defined EPD
operation, to calibrate the VCOM voltage setting and store that
non-volatile in the chip to be the power up default setup. That is not
implemented yet in the driver, but that also means that there is a
non-factory default value in these registers after power-up.

Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
---
 drivers/regulator/Kconfig    |  11 ++
 drivers/regulator/Makefile   |   1 +
 drivers/regulator/tps65185.c | 454 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 466 insertions(+)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index d2335276cce5..5c539782e48d 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1690,6 +1690,17 @@ config REGULATOR_TPS65132
 	  This driver supports TPS65132 single inductor - dual output
 	  power supply specifically designed for display panels.
 
+config REGULATOR_TPS65185
+	tristate "TI TPS65185 EPD regulator"
+	depends on I2C
+	select REGMAP_I2C
+	help
+	  This driver supports the TPS65185 voltage regulator chip
+	  which is used to provide power to Electronic Paper Displays
+	  so it is found in E-Book readers.
+	  If HWWON is enabled, it also provides temperature measurement.
+
+
 config REGULATOR_TPS65217
 	tristate "TI TPS65217 Power regulators"
 	depends on MFD_TPS65217
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 1beba1493241..240de94cd432 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -192,6 +192,7 @@ obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65086) += tps65086-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65090) += tps65090-regulator.o
+obj-$(CONFIG_REGULATOR_TPS65185) += tps65185.o
 obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65218) += tps65218-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65219) += tps65219-regulator.o
diff --git a/drivers/regulator/tps65185.c b/drivers/regulator/tps65185.c
new file mode 100644
index 000000000000..3286c9ab33d0
--- /dev/null
+++ b/drivers/regulator/tps65185.c
@@ -0,0 +1,454 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (C) 2025 Andreas Kemnade
+
+/* Datasheet: https://www.ti.com/lit/gpn/tps65185 */
+
+#include <linux/cleanup.h>
+#include <linux/completion.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/hwmon.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regmap.h>
+
+#define TPS65185_REG_TMST_VALUE 0
+#define TPS65185_REG_ENABLE 1
+#define TPS65185_REG_VADJ 2
+#define TPS65185_REG_VCOM1 3
+#define TPS65185_REG_VCOM2 4
+#define TPS65185_REG_INT_EN1 5
+#define TPS65185_REG_INT_EN2 6
+#define TPS65185_REG_INT1 7
+#define TPS65185_REG_INT2 8
+#define TPS65185_REG_TMST1 0xd
+#define TPS65185_REG_TMST2 0xe
+#define TPS65185_REG_PG 0xf
+#define TPS65185_REG_REVID 0x10
+
+#define TPS65185_READ_THERM BIT(7)
+#define TPS65185_CONV_END BIT(5)
+
+#define TPS65185_ENABLE_ACTIVE BIT(7)
+#define TPS65185_ENABLE_STANDBY BIT(6)
+
+#define PGOOD_TIMEOUT_MSECS 200
+
+struct tps65185_data {
+	struct device *dev;
+	struct regmap *regmap;
+	struct gpio_desc *pgood_gpio;
+	struct gpio_desc *pwrup_gpio;
+	struct gpio_desc *vcom_ctrl_gpio;
+	struct gpio_desc *wakeup_gpio;
+	struct completion pgood_completion;
+	int pgood_irq;
+	struct completion tmst_completion;
+};
+
+static const struct hwmon_channel_info *tps65185_info[] = {
+	HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
+	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
+	NULL
+};
+
+static int tps65185_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+			       u32 attr, int channel, long *temp)
+{
+	struct tps65185_data *data = dev_get_drvdata(dev);
+	unsigned int val;
+	int ret;
+
+	reinit_completion(&data->tmst_completion);
+	/* start acquisition */
+	regmap_update_bits(data->regmap, TPS65185_REG_TMST1,
+			   TPS65185_READ_THERM, TPS65185_READ_THERM);
+	wait_for_completion_timeout(&data->tmst_completion,
+				    msecs_to_jiffies(PGOOD_TIMEOUT_MSECS));
+	ret = regmap_read(data->regmap, TPS65185_REG_TMST1, &val);
+	if (!(val & TPS65185_CONV_END))
+		return -ETIMEDOUT;
+
+	ret = regmap_read(data->regmap, TPS65185_REG_TMST_VALUE, &val);
+	if (ret)
+		return ret;
+
+	*temp = (s8)val * 1000;
+
+	return 0;
+}
+
+static umode_t tps65185_hwmon_is_visible(const void *data,
+					 enum hwmon_sensor_types type,
+					 u32 attr, int channel)
+{
+	return 0444;
+}
+
+static const struct hwmon_ops tps65185_hwmon_ops = {
+	.is_visible = tps65185_hwmon_is_visible,
+	.read = tps65185_hwmon_read,
+};
+
+static const struct hwmon_chip_info tps65185_chip_info = {
+	.ops = &tps65185_hwmon_ops,
+	.info = tps65185_info,
+};
+
+static bool tps65185_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TPS65185_REG_TMST_VALUE:
+	case TPS65185_REG_ENABLE:
+	case TPS65185_REG_VCOM2:
+	case TPS65185_REG_INT1:
+	case TPS65185_REG_INT2:
+	case TPS65185_REG_TMST1:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct regmap_config regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = 0x10,
+	.cache_type = REGCACHE_MAPLE,
+	.volatile_reg = tps65185_volatile_reg,
+};
+
+static const struct regulator_ops tps65185_v3p3ops = {
+	.list_voltage = regulator_list_voltage_linear,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+};
+
+static int tps65185_check_powergood(struct regulator_dev *rdev)
+{
+	struct tps65185_data *data = rdev_get_drvdata(rdev);
+
+	return gpiod_get_value_cansleep(data->pgood_gpio);
+}
+
+static int tps65185_vposneg_get_voltage_sel(struct regulator_dev *rdev)
+{
+	int ret;
+
+	ret = regulator_get_voltage_sel_regmap(rdev);
+	if (ret < 0)
+		return ret;
+
+	/* highest value is lowest voltage */
+	return 6 - ret;
+}
+
+static int tps65185_vposneg_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector)
+{
+	return regulator_set_voltage_sel_regmap(rdev, 6 - selector);
+}
+
+static irqreturn_t pgood_handler(int irq, void *dev_id)
+{
+	struct tps65185_data *data = dev_id;
+
+	complete(&data->pgood_completion);
+
+	return IRQ_HANDLED;
+}
+
+static int tps65185_vposneg_enable(struct regulator_dev *rdev)
+{
+	struct tps65185_data *data = rdev_get_drvdata(rdev);
+	int ret;
+
+	reinit_completion(&data->pgood_completion);
+	if (data->pwrup_gpio)
+		ret = gpiod_set_value_cansleep(data->pwrup_gpio, 1);
+	else
+		ret = regmap_update_bits(data->regmap, TPS65185_REG_ENABLE,
+					 TPS65185_ENABLE_ACTIVE,
+					 TPS65185_ENABLE_ACTIVE);
+
+	if (ret)
+		return ret;
+
+	dev_dbg(data->dev, "turning on...");
+	wait_for_completion_timeout(&data->pgood_completion,
+				    msecs_to_jiffies(PGOOD_TIMEOUT_MSECS));
+	dev_dbg(data->dev, "turned on");
+	if (gpiod_get_value_cansleep(data->pgood_gpio) != 1)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int tps65185_vposneg_disable(struct regulator_dev *rdev)
+{
+	struct tps65185_data *data = rdev_get_drvdata(rdev);
+	int ret;
+
+	if (data->pwrup_gpio)
+		ret = gpiod_set_value_cansleep(data->pwrup_gpio, 0);
+	else
+		ret = regmap_update_bits(data->regmap, TPS65185_REG_ENABLE,
+					 TPS65185_ENABLE_STANDBY,
+					 TPS65185_ENABLE_STANDBY);
+
+	return ret;
+}
+
+static int tps65185_vcom_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector)
+{
+	struct tps65185_data *data = rdev_get_drvdata(rdev);
+	int ret;
+
+	ret = regmap_update_bits(data->regmap, TPS65185_REG_VCOM2, BIT(0), selector >> 8);
+	if (ret < 0)
+		return ret;
+
+	return regmap_write(data->regmap, TPS65185_REG_VCOM1, selector & 0xFF);
+}
+
+static int tps65185_vcom_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct tps65185_data *data = rdev_get_drvdata(rdev);
+	int ret;
+	unsigned int sel, sel2;
+
+	ret = regmap_read(data->regmap, TPS65185_REG_VCOM1, &sel);
+	if (ret < 0)
+		return ret;
+
+	ret = regmap_read(data->regmap, TPS65185_REG_VCOM2, &sel2);
+	if (ret < 0)
+		return ret;
+
+	if (sel2 & BIT(0))
+		sel |= 0x100;
+
+	return sel;
+}
+
+static const struct regulator_ops tps65185_vcom_ops = {
+	.list_voltage = regulator_list_voltage_linear,
+	.map_voltage = regulator_map_voltage_linear,
+	.set_voltage_sel = tps65185_vcom_set_voltage_sel,
+	.get_voltage_sel = tps65185_vcom_get_voltage_sel,
+};
+
+static const struct regulator_ops tps65185_vposneg_ops = {
+	.list_voltage = regulator_list_voltage_linear,
+	.map_voltage = regulator_map_voltage_linear,
+	.enable = tps65185_vposneg_enable,
+	.disable = tps65185_vposneg_disable,
+	.is_enabled = tps65185_check_powergood,
+	.set_voltage_sel = tps65185_vposneg_set_voltage_sel,
+	.get_voltage_sel = tps65185_vposneg_get_voltage_sel,
+};
+
+static const struct regulator_desc regulators[] = {
+	{
+		.name = "v3p3",
+		.of_match = of_match_ptr("v3p3"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = 0,
+		.ops = &tps65185_v3p3ops,
+		.type = REGULATOR_VOLTAGE,
+		.owner = THIS_MODULE,
+		.enable_reg = TPS65185_REG_ENABLE,
+		.enable_mask = BIT(5),
+		.n_voltages = 1,
+		.min_uV = 3300000,
+	},
+	{
+		.name = "vposneg",
+		.of_match = of_match_ptr("vposneg"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = 1,
+		.ops = &tps65185_vposneg_ops,
+		.type = REGULATOR_VOLTAGE,
+		.owner = THIS_MODULE,
+		.n_voltages = 4,
+		.vsel_reg = TPS65185_REG_VADJ,
+		.vsel_mask = 0x7,
+		.min_uV = 14250000,
+		.uV_step = 250000,
+	}
+};
+
+static const struct regulator_desc vcom_regulator_desc = {
+	.name = "vcom",
+	.of_match = of_match_ptr("vcom"),
+	.regulators_node = of_match_ptr("regulators"),
+	.supply_name = "vposneg",
+	.id = 2,
+	.ops = &tps65185_vcom_ops,
+	.type = REGULATOR_VOLTAGE,
+	.owner = THIS_MODULE,
+	.n_voltages = 511,
+	.min_uV = 0,
+	.uV_step = 10000,
+};
+
+static irqreturn_t tps65185_irq_thread(int irq, void *dev_id)
+{
+	struct tps65185_data *data = dev_id;
+	unsigned int int_status_1, int_status_2;
+	int ret;
+
+	/* read both status to have irq cleared */
+	ret = regmap_read(data->regmap, TPS65185_REG_INT1, &int_status_1);
+	if (ret)
+		return IRQ_NONE;
+
+	ret = regmap_read(data->regmap, TPS65185_REG_INT2, &int_status_2);
+	if (ret)
+		return IRQ_NONE;
+
+	if (int_status_2 & BIT(0))
+		complete(&data->tmst_completion);
+
+	dev_dbg(data->dev, "irq status %02x %02x\n", int_status_1, int_status_2);
+
+	if (int_status_1 || int_status_2)
+		return IRQ_HANDLED;
+
+	return IRQ_NONE;
+}
+
+static int tps65185_probe(struct i2c_client *client)
+{
+	struct tps65185_data *data;
+	struct regulator_config config = { };
+	struct regulator_dev *rdev;
+	int ret = 0;
+	int i;
+
+	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+	data->regmap = devm_regmap_init_i2c(client, &regmap_config);
+	if (IS_ERR(data->regmap))
+		return dev_err_probe(&client->dev, PTR_ERR(data->regmap),
+				     "failed to allocate regmap!\n");
+
+	data->pgood_gpio = devm_gpiod_get(&client->dev, "pwr-good", GPIOD_IN);
+	if (IS_ERR(data->pgood_gpio))
+		return dev_err_probe(&client->dev,
+				     PTR_ERR(data->pgood_gpio),
+				     "failed to get power good gpio\n");
+
+	data->pgood_irq = gpiod_to_irq(data->pgood_gpio);
+	if (data->pgood_irq < 0)
+		return data->pgood_irq;
+
+	data->pwrup_gpio = devm_gpiod_get_optional(&client->dev, "enable", GPIOD_OUT_LOW);
+	if (IS_ERR(data->pwrup_gpio))
+		return dev_err_probe(&client->dev, PTR_ERR(data->pwrup_gpio),
+				     "failed to get pwrup gpio\n");
+
+	data->wakeup_gpio = devm_gpiod_get_optional(&client->dev, "wakeup", GPIOD_OUT_HIGH);
+	if (IS_ERR(data->wakeup_gpio))
+		return dev_err_probe(&client->dev,
+				     PTR_ERR(data->wakeup_gpio),
+				     "failed to get wakeup gpio\n");
+
+	data->vcom_ctrl_gpio = devm_gpiod_get_optional(&client->dev, "vcom-ctrl", GPIOD_OUT_LOW);
+	if (IS_ERR(data->vcom_ctrl_gpio))
+		return dev_err_probe(&client->dev,
+				     PTR_ERR(data->vcom_ctrl_gpio),
+				     "failed to get vcm ctrl gpio\n");
+
+	ret = devm_regulator_get_enable(&client->dev, "vin");
+	if (ret)
+		return dev_err_probe(&client->dev, ret,
+				     "failed to get vin regulator\n");
+
+	data->dev = &client->dev;
+	i2c_set_clientdata(client, data);
+
+	init_completion(&data->pgood_completion);
+	init_completion(&data->tmst_completion);
+
+	ret = devm_request_threaded_irq(&client->dev, data->pgood_irq, NULL,
+					pgood_handler,
+					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+					"PGOOD", data);
+	if (ret)
+		return dev_err_probe(&client->dev, ret,
+				     "failed to request power good irq\n");
+
+	if (client->irq) {
+		ret = devm_request_threaded_irq(&client->dev, client->irq,
+						NULL, tps65185_irq_thread,
+						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+						"tps65185", data);
+		if (ret)
+			return dev_err_probe(&client->dev, ret,
+					     "failed to request irq\n");
+	}
+
+	ret = regmap_update_bits(data->regmap, TPS65185_REG_INT_EN2, BIT(0), BIT(0));
+	if (ret)
+		return dev_err_probe(&client->dev, ret,
+				     "failed to enable temp irq\n");
+
+	config.driver_data = data;
+	config.dev = &client->dev;
+	config.regmap = data->regmap;
+
+	for (i = 0; i < ARRAY_SIZE(regulators); i++) {
+		rdev = devm_regulator_register(&client->dev, &regulators[i],
+					       &config);
+		if (IS_ERR(rdev))
+			return dev_err_probe(&client->dev, PTR_ERR(rdev),
+					     "failed to register %s regulator\n",
+					     regulators[i].name);
+	}
+
+	config.ena_gpiod = data->vcom_ctrl_gpio;
+	rdev = devm_regulator_register(&client->dev, &vcom_regulator_desc, &config);
+	if (IS_ERR(rdev))
+		return dev_err_probe(&client->dev, PTR_ERR(rdev),
+				     "failed to register vcom regulator\n");
+
+	if (IS_REACHABLE(CONFIG_HWMON)) {
+		struct device *hwmon_dev;
+
+		hwmon_dev = devm_hwmon_device_register_with_info(&client->dev, "tps65185", data,
+								 &tps65185_chip_info, NULL);
+		if (IS_ERR(hwmon_dev))
+			dev_notice(&client->dev, "failed to register hwmon\n");
+	}
+
+	return 0;
+}
+
+static const struct of_device_id tps65185_dt_ids[] = {
+	{
+		.compatible = "ti,tps65185",
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, tps65185_dt_ids);
+
+static struct i2c_driver tps65185_i2c_driver = {
+	.driver = {
+		   .name = "tps65185",
+		   .of_match_table = tps65185_dt_ids,
+	},
+	.probe = tps65185_probe,
+};
+
+module_i2c_driver(tps65185_i2c_driver);
+
+/* Module information */
+MODULE_DESCRIPTION("TPS65185 regulator driver");
+MODULE_LICENSE("GPL");
+

-- 
2.47.3


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

* Re: [PATCH v2 2/2] regulator: Add TPS65185 driver
  2025-12-27 10:20 ` [PATCH v2 2/2] regulator: Add TPS65185 driver Andreas Kemnade
@ 2025-12-27 16:33   ` Josua Mayer
  0 siblings, 0 replies; 7+ messages in thread
From: Josua Mayer @ 2025-12-27 16:33 UTC (permalink / raw)
  To: Andreas Kemnade, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Guenter Roeck
  Cc: linux-kernel, devicetree, linux-hwmon

Am 27.12.25 um 11:20 schrieb Andreas Kemnade:

> Add a driver for the TPS65185 regulator. Implement handling of the various
> gpio pins. Because the PWRUP (=enable) pin functionality can be achieved
> by just using two bits instead, just ensure that it is set to a stable
> value.
> Implement the pair of symmetric LDOs as a single regulator because they
> share a single voltage set register. As the VCOM regulator sits behind that
> machinery, just define that one as a supply.
> For simplicity, just add the temperature sensor (depending on external NTC)
> directly.
>
> There is a mechanism to measure some kick-back voltage during a defined EPD
> operation, to calibrate the VCOM voltage setting and store that
> non-volatile in the chip to be the power up default setup. That is not
> implemented yet in the driver, but that also means that there is a
> non-factory default value in these registers after power-up.
>
> Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
> ---
>   drivers/regulator/Kconfig    |  11 ++
>   drivers/regulator/Makefile   |   1 +
>   drivers/regulator/tps65185.c | 454 +++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 466 insertions(+)

Tested on Kobo Aura (N514).

Tested-by: Josua Mayer <josua.mayer@jm0.eu>


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

* Re: [PATCH v2 1/2] dt-bindings: regulator: Document TI TPS65185
  2025-12-27 10:20 ` [PATCH v2 1/2] dt-bindings: regulator: Document TI TPS65185 Andreas Kemnade
@ 2025-12-30  9:08   ` Krzysztof Kozlowski
  2025-12-30  9:49     ` Andreas Kemnade
  0 siblings, 1 reply; 7+ messages in thread
From: Krzysztof Kozlowski @ 2025-12-30  9:08 UTC (permalink / raw)
  To: Andreas Kemnade
  Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Guenter Roeck, linux-kernel, devicetree,
	linux-hwmon

On Sat, Dec 27, 2025 at 11:20:36AM +0100, Andreas Kemnade wrote:
> Document the TPS65185. GPIO names are same as in the datasheet except for
> the PWRUP pad which is described as "enable". That pin is optional because
> the rising edge corresponds to setting one register bit and falling edge
> to another register bit.

Nothing improved in the subject. Mark asked for proper prefix and you
used exactly the same prefix, so the same problem stays.

Please use subject prefixes matching the subsystem. You can get them for
example with 'git log --oneline -- DIRECTORY_OR_FILE' on the directory
your patch is touching. For bindings, the preferred subjects are
explained here:
https://www.kernel.org/doc/html/latest/devicetree/bindings/submitting-patches.html#i-for-patch-submitters


> 
> Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
> ---
>  .../devicetree/bindings/regulator/ti,tps65185.yaml | 99 ++++++++++++++++++++++
>  1 file changed, 99 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/regulator/ti,tps65185.yaml b/Documentation/devicetree/bindings/regulator/ti,tps65185.yaml
> new file mode 100644
> index 000000000000..7cc5a895c2fc
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/ti,tps65185.yaml
> @@ -0,0 +1,99 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/regulator/ti,tps65185.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: TI TPS65185 Power Management Integrated Circuit
> +
> +maintainers:
> +  - Andreas Kemnade <andreas@kemnade.info>
> +
> +description:
> +  TPS65185 is a Power Management IC to provide Power for EPDs with one 3.3V
> +  switch, 2 symmetric LDOs behind 2 DC/DC converters, and one unsymmetric
> +  regulator for a compensation voltage.
> +
> +properties:
> +  compatible:
> +    const: ti,tps65185
> +
> +  reg:
> +    maxItems: 1
> +
> +  enable-gpios:
> +    description:
> +      PWRUP pin
> +    maxItems: 1
> +
> +  pwr-good-gpios:
> +    maxItems: 1
> +
> +  vcom-ctrl-gpios:
> +    maxItems: 1
> +
> +  wakeup-gpios:
> +    maxItems: 1
> +
> +  vin-supply:
> +    description:
> +      Supply for the whole chip. Some vendor kernels and devicetrees
> +      declare this as a non-existing GPIO named "pwrall".

GPIO cannot be non-existing. Anyway, use name matching the datasheet.

With these two things fixed:

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Best regards,
Krzysztof


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

* Re: [PATCH v2 1/2] dt-bindings: regulator: Document TI TPS65185
  2025-12-30  9:08   ` Krzysztof Kozlowski
@ 2025-12-30  9:49     ` Andreas Kemnade
  2025-12-30 10:40       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 7+ messages in thread
From: Andreas Kemnade @ 2025-12-30  9:49 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Guenter Roeck, linux-kernel, devicetree,
	linux-hwmon

On Tue, 30 Dec 2025 10:08:57 +0100
Krzysztof Kozlowski <krzk@kernel.org> wrote:

> On Sat, Dec 27, 2025 at 11:20:36AM +0100, Andreas Kemnade wrote:
> > Document the TPS65185. GPIO names are same as in the datasheet except for
> > the PWRUP pad which is described as "enable". That pin is optional because
> > the rising edge corresponds to setting one register bit and falling edge
> > to another register bit.  
> 
> Nothing improved in the subject. Mark asked for proper prefix and you
> used exactly the same prefix, so the same problem stays.
> 
Quoting:
The Documentation/ and include/dt-bindings/ portion of the patch should be a separate patch. The preferred subject prefix for binding patches is:
"dt-bindings: <binding dir>: ..."

That looks like what I am using.

> Please use subject prefixes matching the subsystem. You can get them for
> example with 'git log --oneline -- DIRECTORY_OR_FILE' on the directory
> your patch is touching. For bindings, the preferred subjects are
> explained here:
> https://www.kernel.org/doc/html/latest/devicetree/bindings/submitting-patches.html#i-for-patch-submitters

besides merge commits, patches with subjects doing the same seems to be:

d0f9f5b7a335 dt-bindings: regulator: Document MediaTek MT6363 PMIC Regulators
0f1010284076 dt-bindings: regulator: document max77838 pmic

That looks like mine. So no idea what to improve...

[...]
> > +  vin-supply:
> > +    description:
> > +      Supply for the whole chip. Some vendor kernels and devicetrees
> > +      declare this as a non-existing GPIO named "pwrall".  
> 
> GPIO cannot be non-existing. Anyway, use name matching the datasheet.
> 
That is correct, GPIO cannot be non-existing. That comment was just
meant as a help for people trying to convert the dirty devicetree mess
out there into proper, submittable material. But I will remove that help
as you request.

Regards,
Andreas

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

* Re: [PATCH v2 1/2] dt-bindings: regulator: Document TI TPS65185
  2025-12-30  9:49     ` Andreas Kemnade
@ 2025-12-30 10:40       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 7+ messages in thread
From: Krzysztof Kozlowski @ 2025-12-30 10:40 UTC (permalink / raw)
  To: Andreas Kemnade
  Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Guenter Roeck, linux-kernel, devicetree,
	linux-hwmon

On 30/12/2025 10:49, Andreas Kemnade wrote:
> On Tue, 30 Dec 2025 10:08:57 +0100
> Krzysztof Kozlowski <krzk@kernel.org> wrote:
> 
>> On Sat, Dec 27, 2025 at 11:20:36AM +0100, Andreas Kemnade wrote:
>>> Document the TPS65185. GPIO names are same as in the datasheet except for
>>> the PWRUP pad which is described as "enable". That pin is optional because
>>> the rising edge corresponds to setting one register bit and falling edge
>>> to another register bit.  
>>
>> Nothing improved in the subject. Mark asked for proper prefix and you
>> used exactly the same prefix, so the same problem stays.
>>
> Quoting:
> The Documentation/ and include/dt-bindings/ portion of the patch should be a separate patch. The preferred subject prefix for binding patches is:
> "dt-bindings: <binding dir>: ..."
> 
> That looks like what I am using.

Please read entire paragraph not just half of it.

Best regards,
Krzysztof

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

end of thread, other threads:[~2025-12-30 10:40 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-27 10:20 [PATCH v2 0/2] regulator: Add TPS65185 Andreas Kemnade
2025-12-27 10:20 ` [PATCH v2 1/2] dt-bindings: regulator: Document TI TPS65185 Andreas Kemnade
2025-12-30  9:08   ` Krzysztof Kozlowski
2025-12-30  9:49     ` Andreas Kemnade
2025-12-30 10:40       ` Krzysztof Kozlowski
2025-12-27 10:20 ` [PATCH v2 2/2] regulator: Add TPS65185 driver Andreas Kemnade
2025-12-27 16:33   ` Josua Mayer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox