linux-rtc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v8 0/8] spacemit: introduce P1 PMIC support
@ 2025-07-10 17:50 Alex Elder
  2025-07-10 17:50 ` [PATCH v8 1/8] dt-bindings: mfd: add support the SpacemiT P1 PMIC Alex Elder
                   ` (7 more replies)
  0 siblings, 8 replies; 14+ messages in thread
From: Alex Elder @ 2025-07-10 17:50 UTC (permalink / raw)
  To: lee, lgirdwood, broonie, alexandre.belloni, robh, krzk+dt,
	conor+dt
  Cc: mat.jonczyk, dlan, paul.walmsley, palmer, aou, alex,
	troymitchell988, guodong, linux-rtc, devicetree, linux-riscv,
	spacemit, linux-kernel

The SpacemiT P1 is an I2C-controlled PMIC that implements 6 buck
converters and 12 LDOs.  It contains a load switch, ADC channels,
GPIOs, a real-time clock, and a watchdog timer.

This series introduces a multifunction driver for the P1 PMIC as well
as drivers for its regulators and RTC.

Version 7 provided the ability in "simple-mfd-i2c.c" to specify the
max_register value for the regmap configuration as an alternative
to providing a "full" regmap structure.  The max_register value is
ignored if a regmap_config is also supplied in simple_mfd_data.

Lee Jones felt the logic in v7 was more complex than it needed to
be, and suggested removing the const qualifier from the global
regmap_config structure used by default.

This version does what Lee suggested, and the logic is indeed
simpler.  However in order to avoid compile warnings the const
qualifier was removed from other places as well.  (Checkpatch
even complains about this.)

Frankly I think my original solution--which simply used the
existing ability to provide a regmap_config structure--was the
best (version 5 of the series is done this way).  I don't think
adding simple_mfd_data->max_register provides real benefit.
  https://lore.kernel.org/lkml/20250625164119.1068842-1-elder@riscstar.com/

					-Alex

This series is available here:
  https://github.com/riscstar/linux/tree/outgoing/pmic-v8

Between version 7 and version 8:
  - Change the global regmap_config to not be const in patch 2.

Here is version 7 of this series:
  https://lore.kernel.org/lkml/20250702213658.545163-1-elder@riscstar.com/
  
Between version 6 and version 7:
  - Revise patch 2 to preserve the option to provide a full regmap config

Here is version 6 of this series:
  https://lore.kernel.org/lkml/20250627142309.1444135-1-elder@riscstar.com/

Between version 5 and version 6:
  - Added Rob Herring's reviewed-by to patch 1
  - Add the simple MFD functionality suggested by Lee Jones
  - Update patch 3 (previously 2) accordingly

Here is version 5 of this series:
  https://lore.kernel.org/lkml/20250625164119.1068842-1-elder@riscstar.com/

Between version 4 and version 5:
  - Only check the seconds register for change when looping on read
  - Return without re-enabling the RTC if writing registers fails
  - If the RTC is disabled when reading, return an error

Here is version 4 of this series:
  https://lore.kernel.org/lkml/20250625164119.1068842-1-elder@riscstar.com/

More complete history is available at that link.


Alex Elder (8):
  dt-bindings: mfd: add support the SpacemiT P1 PMIC
  mfd: simple-mfd-i2c: specify max_register
  mfd: simple-mfd-i2c: add SpacemiT P1 support
  regulator: spacemit: support SpacemiT P1 regulators
  rtc: spacemit: support the SpacemiT P1 RTC
  riscv: dts: spacemit: enable the i2c8 adapter
  riscv: dts: spacemit: define fixed regulators
  riscv: dts: spacemit: define regulator constraints

 .../devicetree/bindings/mfd/spacemit,p1.yaml  |  86 +++++++++
 .../boot/dts/spacemit/k1-bananapi-f3.dts      | 138 +++++++++++++++
 arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi  |   7 +
 arch/riscv/boot/dts/spacemit/k1.dtsi          |  11 ++
 drivers/mfd/Kconfig                           |  11 ++
 drivers/mfd/simple-mfd-i2c.c                  |  20 ++-
 drivers/mfd/simple-mfd-i2c.h                  |   3 +-
 drivers/regulator/Kconfig                     |  12 ++
 drivers/regulator/Makefile                    |   1 +
 drivers/regulator/spacemit-p1.c               | 157 ++++++++++++++++
 drivers/rtc/Kconfig                           |  10 ++
 drivers/rtc/Makefile                          |   1 +
 drivers/rtc/rtc-spacemit-p1.c                 | 167 ++++++++++++++++++
 13 files changed, 621 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/spacemit,p1.yaml
 create mode 100644 drivers/regulator/spacemit-p1.c
 create mode 100644 drivers/rtc/rtc-spacemit-p1.c


base-commit: b551c4e2a98a177a06148cf16505643cd2108386
-- 
2.45.2


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

* [PATCH v8 1/8] dt-bindings: mfd: add support the SpacemiT P1 PMIC
  2025-07-10 17:50 [PATCH v8 0/8] spacemit: introduce P1 PMIC support Alex Elder
@ 2025-07-10 17:50 ` Alex Elder
  2025-07-10 17:51 ` [PATCH v8 2/8] mfd: simple-mfd-i2c: specify max_register Alex Elder
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Alex Elder @ 2025-07-10 17:50 UTC (permalink / raw)
  To: lee, lgirdwood, broonie, alexandre.belloni, robh, krzk+dt,
	conor+dt
  Cc: mat.jonczyk, dlan, paul.walmsley, palmer, aou, alex,
	troymitchell988, guodong, linux-rtc, devicetree, linux-riscv,
	spacemit, linux-kernel

Enable the SpacemiT P1, which is an I2C-controlled PMIC.  Initially
only the RTC and regulators will be supported.

Signed-off-by: Alex Elder <elder@riscstar.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
---
 .../devicetree/bindings/mfd/spacemit,p1.yaml  | 86 +++++++++++++++++++
 1 file changed, 86 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/spacemit,p1.yaml

diff --git a/Documentation/devicetree/bindings/mfd/spacemit,p1.yaml b/Documentation/devicetree/bindings/mfd/spacemit,p1.yaml
new file mode 100644
index 0000000000000..5cc34d4934b54
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/spacemit,p1.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/spacemit,p1.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SpacemiT P1 Power Management Integrated Circuit
+
+maintainers:
+  - Troy Mitchell <troymitchell988@gmail.com>
+
+description:
+  P1 is an I2C-controlled PMIC produced by SpacemiT.  It implements six
+  constant-on-time buck converters and twelve low-dropout regulators.
+  It also contains a load switch, watchdog timer, real-time clock, eight
+  12-bit ADC channels, and six GPIOs.  Additional details are available
+  in the "Power Stone/P1" section at the following link.
+    https://developer.spacemit.com/documentation
+
+properties:
+  compatible:
+    const: spacemit,p1
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  vin-supply:
+    description: Input supply phandle.
+
+  regulators:
+    type: object
+
+    patternProperties:
+      "^(buck[1-6]|aldo[1-4]|dldo[1-7])$":
+        type: object
+        $ref: /schemas/regulator/regulator.yaml#
+        unevaluatedProperties: false
+
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pmic@41 {
+            compatible = "spacemit,p1";
+            reg = <0x41>;
+            interrupts = <64>;
+
+            regulators {
+                buck1 {
+                    regulator-name = "buck1";
+                    regulator-min-microvolt = <500000>;
+                    regulator-max-microvolt = <3450000>;
+                    regulator-ramp-delay = <5000>;
+                    regulator-always-on;
+                };
+
+                aldo1 {
+                    regulator-name = "aldo1";
+                    regulator-min-microvolt = <500000>;
+                    regulator-max-microvolt = <3400000>;
+                    regulator-boot-on;
+                };
+
+                dldo1 {
+                    regulator-name = "dldo1";
+                    regulator-min-microvolt = <500000>;
+                    regulator-max-microvolt = <3400000>;
+                    regulator-boot-on;
+                };
+            };
+        };
+    };
-- 
2.45.2


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

* [PATCH v8 2/8] mfd: simple-mfd-i2c: specify max_register
  2025-07-10 17:50 [PATCH v8 0/8] spacemit: introduce P1 PMIC support Alex Elder
  2025-07-10 17:50 ` [PATCH v8 1/8] dt-bindings: mfd: add support the SpacemiT P1 PMIC Alex Elder
@ 2025-07-10 17:51 ` Alex Elder
  2025-07-23  9:51   ` Lee Jones
  2025-07-10 17:51 ` [PATCH v8 3/8] mfd: simple-mfd-i2c: add SpacemiT P1 support Alex Elder
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 14+ messages in thread
From: Alex Elder @ 2025-07-10 17:51 UTC (permalink / raw)
  To: lee, lgirdwood, broonie, alexandre.belloni, robh, krzk+dt,
	conor+dt
  Cc: mat.jonczyk, dlan, paul.walmsley, palmer, aou, alex,
	troymitchell988, guodong, linux-rtc, devicetree, linux-riscv,
	spacemit, linux-kernel

All devices supported by simple MFD use the same 8-bit register 8-bit
value regmap configuration.  There is an option available for a device
to specify a custom configuration, but no existing device uses it.

Rather than specify a "full" regmap configuration to change only
the max_register value, Lee Jones suggested allowing max_register
to be specified in the simple_mfd_data structure.  If regmap_config
and max_register are both supplied, the max_register field is ignored.

Signed-off-by: Alex Elder <elder@riscstar.com>
Suggested-by: Lee Jones <lee@kernel.org>
---
v8: - Use regmap_config_8r_8v, modifying it if max_register supplied

 drivers/mfd/simple-mfd-i2c.c | 8 ++++++--
 drivers/mfd/simple-mfd-i2c.h | 3 ++-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
index 22159913bea03..5138aa72140b5 100644
--- a/drivers/mfd/simple-mfd-i2c.c
+++ b/drivers/mfd/simple-mfd-i2c.c
@@ -24,15 +24,16 @@
 
 #include "simple-mfd-i2c.h"
 
-static const struct regmap_config regmap_config_8r_8v = {
+static struct regmap_config regmap_config_8r_8v = {
 	.reg_bits = 8,
 	.val_bits = 8,
+	/* .max_register can be specified in simple_mfd_data */
 };
 
 static int simple_mfd_i2c_probe(struct i2c_client *i2c)
 {
 	const struct simple_mfd_data *simple_mfd_data;
-	const struct regmap_config *regmap_config;
+	struct regmap_config *regmap_config;
 	struct regmap *regmap;
 	int ret;
 
@@ -43,8 +44,11 @@ static int simple_mfd_i2c_probe(struct i2c_client *i2c)
 		regmap_config = &regmap_config_8r_8v;
 	else
 		regmap_config = simple_mfd_data->regmap_config;
+	if (simple_mfd_data && !simple_mfd_data->regmap_config)
+		regmap_config->max_register = simple_mfd_data->max_register;
 
 	regmap = devm_regmap_init_i2c(i2c, regmap_config);
+	regmap_config->max_register = 0;
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
diff --git a/drivers/mfd/simple-mfd-i2c.h b/drivers/mfd/simple-mfd-i2c.h
index 7cb2bdd347d97..ea2a96af8bce4 100644
--- a/drivers/mfd/simple-mfd-i2c.h
+++ b/drivers/mfd/simple-mfd-i2c.h
@@ -24,7 +24,8 @@
 #include <linux/regmap.h>
 
 struct simple_mfd_data {
-	const struct regmap_config *regmap_config;
+	struct regmap_config *regmap_config;
+	unsigned int max_register;	/* Ignored if regmap_config supplied */
 	const struct mfd_cell *mfd_cell;
 	size_t mfd_cell_size;
 };
-- 
2.45.2


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

* [PATCH v8 3/8] mfd: simple-mfd-i2c: add SpacemiT P1 support
  2025-07-10 17:50 [PATCH v8 0/8] spacemit: introduce P1 PMIC support Alex Elder
  2025-07-10 17:50 ` [PATCH v8 1/8] dt-bindings: mfd: add support the SpacemiT P1 PMIC Alex Elder
  2025-07-10 17:51 ` [PATCH v8 2/8] mfd: simple-mfd-i2c: specify max_register Alex Elder
@ 2025-07-10 17:51 ` Alex Elder
  2025-07-10 17:51 ` [PATCH v8 4/8] regulator: spacemit: support SpacemiT P1 regulators Alex Elder
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Alex Elder @ 2025-07-10 17:51 UTC (permalink / raw)
  To: lee, lgirdwood, broonie, alexandre.belloni, robh, krzk+dt,
	conor+dt
  Cc: mat.jonczyk, dlan, paul.walmsley, palmer, aou, alex,
	troymitchell988, guodong, linux-rtc, devicetree, linux-riscv,
	spacemit, linux-kernel

Enable support for the RTC and regulators found in the SpacemiT P1
PMIC.  Support is implemented by the simple I2C MFD driver.

The P1 PMIC is normally implemented with the SpacemiT K1 SoC.  This
PMIC provides 6 buck converters and 12 LDO regulators.  It also
implements a switch, watchdog timer, real-time clock, and more.
Initially its RTC and regulators are supported.

Signed-off-by: Alex Elder <elder@riscstar.com>
---
 drivers/mfd/Kconfig          | 11 +++++++++++
 drivers/mfd/simple-mfd-i2c.c | 12 ++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 6fb3768e3d71c..01805c3eec57d 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1182,6 +1182,17 @@ config MFD_QCOM_RPM
 	  Say M here if you want to include support for the Qualcomm RPM as a
 	  module. This will build a module called "qcom_rpm".
 
+config MFD_SPACEMIT_P1
+	tristate "SpacemiT P1 PMIC"
+	depends on I2C
+	select MFD_SIMPLE_MFD_I2C
+	help
+	  This option supports the I2C-based SpacemiT P1 PMIC, which
+	  contains regulators, a power switch, GPIOs, an RTC, and more.
+	  This option is selected when any of the supported sub-devices
+	  is configured.  The basic functionality is implemented by the
+	  simple MFD I2C driver.
+
 config MFD_SPMI_PMIC
 	tristate "Qualcomm SPMI PMICs"
 	depends on ARCH_QCOM || COMPILE_TEST
diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
index 5138aa72140b5..df44c2664fbfc 100644
--- a/drivers/mfd/simple-mfd-i2c.c
+++ b/drivers/mfd/simple-mfd-i2c.c
@@ -97,12 +97,24 @@ static const struct simple_mfd_data maxim_mon_max77705 = {
 	.mfd_cell_size = ARRAY_SIZE(max77705_sensor_cells),
 };
 
+static const struct mfd_cell spacemit_p1_cells[] = {
+	{ .name = "spacemit-p1-regulator", },
+	{ .name = "spacemit-p1-rtc", },
+};
+
+static const struct simple_mfd_data spacemit_p1 = {
+	.mfd_cell = spacemit_p1_cells,
+	.mfd_cell_size = ARRAY_SIZE(spacemit_p1_cells),
+	.max_register = 0xaa,
+};
+
 static const struct of_device_id simple_mfd_i2c_of_match[] = {
 	{ .compatible = "kontron,sl28cpld" },
 	{ .compatible = "silergy,sy7636a", .data = &silergy_sy7636a},
 	{ .compatible = "maxim,max5970", .data = &maxim_max5970},
 	{ .compatible = "maxim,max5978", .data = &maxim_max5970},
 	{ .compatible = "maxim,max77705-battery", .data = &maxim_mon_max77705},
+	{ .compatible = "spacemit,p1", .data = &spacemit_p1, },
 	{}
 };
 MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match);
-- 
2.45.2


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

* [PATCH v8 4/8] regulator: spacemit: support SpacemiT P1 regulators
  2025-07-10 17:50 [PATCH v8 0/8] spacemit: introduce P1 PMIC support Alex Elder
                   ` (2 preceding siblings ...)
  2025-07-10 17:51 ` [PATCH v8 3/8] mfd: simple-mfd-i2c: add SpacemiT P1 support Alex Elder
@ 2025-07-10 17:51 ` Alex Elder
  2025-07-10 17:51 ` [PATCH v8 5/8] rtc: spacemit: support the SpacemiT P1 RTC Alex Elder
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Alex Elder @ 2025-07-10 17:51 UTC (permalink / raw)
  To: lee, lgirdwood, broonie, alexandre.belloni, robh, krzk+dt,
	conor+dt
  Cc: mat.jonczyk, dlan, paul.walmsley, palmer, aou, alex,
	troymitchell988, guodong, linux-rtc, devicetree, linux-riscv,
	spacemit, linux-kernel

Add support for the regulators found in the SpacemiT P1 PMIC.  This
PMIC provides 6 buck converters and 12 LDO regulators.

The PMIC is implemented as a multi-function device.  These regulators
are probed based on this driver being named in a MFD cell in the simple
MFD I2C driver.

Signed-off-by: Alex Elder <elder@riscstar.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
---
 drivers/regulator/Kconfig       |  12 +++
 drivers/regulator/Makefile      |   1 +
 drivers/regulator/spacemit-p1.c | 157 ++++++++++++++++++++++++++++++++
 3 files changed, 170 insertions(+)
 create mode 100644 drivers/regulator/spacemit-p1.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 7423954153b07..3e7feeebf8aca 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1395,6 +1395,18 @@ config REGULATOR_SLG51000
 	  The SLG51000 is seven compact and customizable low dropout
 	  regulators.
 
+config REGULATOR_SPACEMIT_P1
+	tristate "SpacemiT P1 regulators"
+	depends on ARCH_SPACEMIT || COMPILE_TEST
+	select MFD_SPACEMIT_P1
+	default ARCH_SPACEMIT
+	help
+	  Enable support for regulators implemented by the SpacemiT P1
+	  power controller.  The P1 implements 6 high-efficiency buck
+	  converters and 12 programmable LDO regulators.  To compile this
+	  driver as a module, choose M here.  The module will be called
+	  "spacemit-pmic".
+
 config REGULATOR_STM32_BOOSTER
 	tristate "STMicroelectronics STM32 BOOSTER"
 	depends on ARCH_STM32 || COMPILE_TEST
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index be98b29d6675d..278f5b8d1c7d7 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -162,6 +162,7 @@ obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o
 obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
 obj-$(CONFIG_REGULATOR_SLG51000) += slg51000-regulator.o
+obj-$(CONFIG_REGULATOR_SPACEMIT_P1) += spacemit-p1.o
 obj-$(CONFIG_REGULATOR_STM32_BOOSTER) += stm32-booster.o
 obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
 obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o
diff --git a/drivers/regulator/spacemit-p1.c b/drivers/regulator/spacemit-p1.c
new file mode 100644
index 0000000000000..d437e6738ea1e
--- /dev/null
+++ b/drivers/regulator/spacemit-p1.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for regulators found in the SpacemiT P1 PMIC
+ *
+ * Copyright (C) 2025 by RISCstar Solutions Corporation.  All rights reserved.
+ * Derived from code from SpacemiT.
+ *	Copyright (c) 2023, SPACEMIT Co., Ltd
+ */
+
+#include <linux/array_size.h>
+#include <linux/bits.h>
+#include <linux/device.h>
+#include <linux/linear_range.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+
+#define MOD_NAME	"spacemit-p1-regulator"
+
+enum p1_regulator_id {
+	P1_BUCK1,
+	P1_BUCK2,
+	P1_BUCK3,
+	P1_BUCK4,
+	P1_BUCK5,
+	P1_BUCK6,
+
+	P1_ALDO1,
+	P1_ALDO2,
+	P1_ALDO3,
+	P1_ALDO4,
+
+	P1_DLDO1,
+	P1_DLDO2,
+	P1_DLDO3,
+	P1_DLDO4,
+	P1_DLDO5,
+	P1_DLDO6,
+	P1_DLDO7,
+};
+
+static const struct regulator_ops p1_regulator_ops = {
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.set_voltage_time_sel   = regulator_set_voltage_time_sel,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+};
+
+/* Selector value 255 can be used to disable the buck converter on sleep */
+static const struct linear_range p1_buck_ranges[] = {
+	REGULATOR_LINEAR_RANGE(500000, 0, 170, 5000),
+	REGULATOR_LINEAR_RANGE(1375000, 171, 254, 25000),
+};
+
+/* Selector value 0 can be used for suspend */
+static const struct linear_range p1_ldo_ranges[] = {
+	REGULATOR_LINEAR_RANGE(500000, 11, 127, 25000),
+};
+
+/* These define the voltage selector field for buck and LDO regulators */
+#define BUCK_MASK		GENMASK(7, 0)
+#define LDO_MASK		GENMASK(6, 0)
+
+#define P1_ID(_TYPE, _n)	P1_ ## _TYPE ## _n
+#define P1_ENABLE_REG(_off, _n)	((_off) + 3 * ((_n) - 1))
+
+#define P1_REG_DESC(_TYPE, _type, _n, _s, _off, _mask, _nv, _ranges)	\
+	{								\
+		.name			= #_type #_n,			\
+		.supply_name		= _s,				\
+		.of_match		= of_match_ptr(#_type #_n),	\
+		.regulators_node	= of_match_ptr("regulators"),	\
+		.id			= P1_ID(_TYPE, _n),		\
+		.n_voltages		= _nv,				\
+		.ops			= &p1_regulator_ops,		\
+		.owner			= THIS_MODULE,			\
+		.linear_ranges		= _ranges,			\
+		.n_linear_ranges	= ARRAY_SIZE(_ranges),		\
+		.vsel_reg		= P1_ENABLE_REG(_off, _n) + 1,	\
+		.vsel_mask		= _mask,			\
+		.enable_reg		= P1_ENABLE_REG(_off, _n),	\
+		.enable_mask		= BIT(0),			\
+	}
+
+#define P1_BUCK_DESC(_n) \
+	P1_REG_DESC(BUCK, buck, _n, "vcc", 0x47, BUCK_MASK, 254, p1_buck_ranges)
+
+#define P1_ALDO_DESC(_n) \
+	P1_REG_DESC(ALDO, aldo, _n, "vcc", 0x5b, LDO_MASK, 117, p1_ldo_ranges)
+
+#define P1_DLDO_DESC(_n) \
+	P1_REG_DESC(DLDO, dldo, _n, "buck5", 0x67, LDO_MASK, 117, p1_ldo_ranges)
+
+static const struct regulator_desc p1_regulator_desc[] = {
+	P1_BUCK_DESC(1),
+	P1_BUCK_DESC(2),
+	P1_BUCK_DESC(3),
+	P1_BUCK_DESC(4),
+	P1_BUCK_DESC(5),
+	P1_BUCK_DESC(6),
+
+	P1_ALDO_DESC(1),
+	P1_ALDO_DESC(2),
+	P1_ALDO_DESC(3),
+	P1_ALDO_DESC(4),
+
+	P1_DLDO_DESC(1),
+	P1_DLDO_DESC(2),
+	P1_DLDO_DESC(3),
+	P1_DLDO_DESC(4),
+	P1_DLDO_DESC(5),
+	P1_DLDO_DESC(6),
+	P1_DLDO_DESC(7),
+};
+
+static int p1_regulator_probe(struct platform_device *pdev)
+{
+	struct regulator_config config = { };
+	struct device *dev = &pdev->dev;
+	u32 i;
+
+	/*
+	 * The parent device (PMIC) owns the regmap.  Since we don't
+	 * provide one in the config structure, that one will be used.
+	 */
+	config.dev = dev->parent;
+
+	for (i = 0; i < ARRAY_SIZE(p1_regulator_desc); i++) {
+		const struct regulator_desc *desc = &p1_regulator_desc[i];
+		struct regulator_dev *rdev;
+
+		rdev = devm_regulator_register(dev, desc, &config);
+		if (IS_ERR(rdev))
+			return dev_err_probe(dev, PTR_ERR(rdev),
+					     "error registering regulator %s\n",
+					     desc->name);
+	}
+
+	return 0;
+}
+
+static struct platform_driver p1_regulator_driver = {
+	.probe = p1_regulator_probe,
+	.driver = {
+		.name = MOD_NAME,
+	},
+};
+
+module_platform_driver(p1_regulator_driver);
+
+MODULE_DESCRIPTION("SpacemiT P1 regulator driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" MOD_NAME);
-- 
2.45.2


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

* [PATCH v8 5/8] rtc: spacemit: support the SpacemiT P1 RTC
  2025-07-10 17:50 [PATCH v8 0/8] spacemit: introduce P1 PMIC support Alex Elder
                   ` (3 preceding siblings ...)
  2025-07-10 17:51 ` [PATCH v8 4/8] regulator: spacemit: support SpacemiT P1 regulators Alex Elder
@ 2025-07-10 17:51 ` Alex Elder
  2025-07-23 21:39   ` Alexandre Belloni
  2025-07-10 17:51 ` [PATCH v8 6/8] riscv: dts: spacemit: enable the i2c8 adapter Alex Elder
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 14+ messages in thread
From: Alex Elder @ 2025-07-10 17:51 UTC (permalink / raw)
  To: lee, lgirdwood, broonie, alexandre.belloni, robh, krzk+dt,
	conor+dt
  Cc: mat.jonczyk, dlan, paul.walmsley, palmer, aou, alex,
	troymitchell988, guodong, linux-rtc, devicetree, linux-riscv,
	spacemit, linux-kernel

Add support for the RTC found in the SpacemiT P1 PMIC.  Initially
only setting and reading the time are supported.

The PMIC is implemented as a multi-function device.  This RTC is
probed based on this driver being named in a MFD cell in the simple
MFD I2C driver.

Signed-off-by: Alex Elder <elder@riscstar.com>
---
 drivers/rtc/Kconfig           |  10 ++
 drivers/rtc/Makefile          |   1 +
 drivers/rtc/rtc-spacemit-p1.c | 167 ++++++++++++++++++++++++++++++++++
 3 files changed, 178 insertions(+)
 create mode 100644 drivers/rtc/rtc-spacemit-p1.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 9aec922613cec..93620f2c9b29c 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -406,6 +406,16 @@ config RTC_DRV_MAX77686
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-max77686.
 
+config RTC_DRV_SPACEMIT_P1
+	tristate "SpacemiT P1 RTC"
+	depends on ARCH_SPACEMIT || COMPILE_TEST
+	select MFD_SPACEMIT_P1
+	default ARCH_SPACEMIT
+	help
+	  Enable support for the RTC function in the SpacemiT P1 PMIC.
+	  This driver can also be built as a module, which will be called
+	  "spacemit-p1-rtc".
+
 config RTC_DRV_NCT3018Y
 	tristate "Nuvoton NCT3018Y"
 	depends on OF
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 4619aa2ac4697..a24ff6ad5ca58 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -171,6 +171,7 @@ obj-$(CONFIG_RTC_DRV_SD2405AL)	+= rtc-sd2405al.o
 obj-$(CONFIG_RTC_DRV_SD3078)	+= rtc-sd3078.o
 obj-$(CONFIG_RTC_DRV_SH)	+= rtc-sh.o
 obj-$(CONFIG_RTC_DRV_SNVS)	+= rtc-snvs.o
+obj-$(CONFIG_RTC_DRV_SPACEMIT_P1)	+= rtc-spacemit-p1.o
 obj-$(CONFIG_RTC_DRV_SPEAR)	+= rtc-spear.o
 obj-$(CONFIG_RTC_DRV_STARFIRE)	+= rtc-starfire.o
 obj-$(CONFIG_RTC_DRV_STK17TA8)	+= rtc-stk17ta8.o
diff --git a/drivers/rtc/rtc-spacemit-p1.c b/drivers/rtc/rtc-spacemit-p1.c
new file mode 100644
index 0000000000000..5f1bcca00549c
--- /dev/null
+++ b/drivers/rtc/rtc-spacemit-p1.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for the RTC found in the SpacemiT P1 PMIC
+ *
+ * Copyright (C) 2025 by RISCstar Solutions Corporation.  All rights reserved.
+ */
+
+#include <linux/bits.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/rtc.h>
+
+#define MOD_NAME	"spacemit-p1-rtc"
+
+/*
+ * Six consecutive 1-byte registers hold the seconds, minutes, hours,
+ * day-of-month, month, and year (respectively).
+ *
+ * The range of values in these registers is:
+ *    seconds	0-59
+ *    minutes	0-59
+ *    hours	0-59
+ *    day	0-30 (struct tm is 1-31)
+ *    month	0-11
+ *    year	years since 2000 (struct tm is since 1900)
+ *
+ * Note that the day and month must be converted after reading and
+ * before writing.
+ */
+#define RTC_TIME		0x0d	/* Offset of the seconds register */
+
+#define RTC_CTRL		0x1d
+#define RTC_EN		BIT(2)
+
+/* Number of attempts to read a consistent time stamp before giving up */
+#define RTC_READ_TRIES		20	/* At least 1 */
+
+struct p1_rtc {
+	struct regmap *regmap;
+	struct rtc_device *rtc;
+};
+
+/*
+ * The P1 hardware documentation states that the register values are
+ * latched to ensure a consistent time snapshot within the registers,
+ * but these are in fact unstable due to a bug in the hardware design.
+ * So we loop until we get two identical readings.
+ */
+static int p1_rtc_read_time(struct device *dev, struct rtc_time *t)
+{
+	struct p1_rtc *p1 = dev_get_drvdata(dev);
+	struct regmap *regmap = p1->regmap;
+	u32 count = RTC_READ_TRIES;
+	u8 seconds;
+	u8 time[6];
+	int ret;
+
+	if (!regmap_test_bits(regmap, RTC_CTRL, RTC_EN))
+		return -ENODEV;		/* RTC is disabled */
+
+	ret = regmap_bulk_read(regmap, RTC_TIME, time, sizeof(time));
+	if (ret)
+		return ret;
+
+	do {
+		seconds = time[0];
+		ret = regmap_bulk_read(regmap, RTC_TIME, time, sizeof(time));
+		if (ret)
+			return ret;
+	} while (time[0] != seconds && --count);
+
+	if (!count)
+		return -EIO;		/* Unable to get a consistent result */
+
+	t->tm_sec = time[0] & GENMASK(5, 0);
+	t->tm_min = time[1] & GENMASK(5, 0);
+	t->tm_hour = time[2] & GENMASK(4, 0);
+	t->tm_mday = (time[3] & GENMASK(4, 0)) + 1;
+	t->tm_mon = time[4] & GENMASK(3, 0);
+	t->tm_year = (time[5] & GENMASK(5, 0)) + 100;
+
+	return 0;
+}
+
+/*
+ * The P1 hardware documentation states that values in the registers are
+ * latched so when written they represent a consistent time snapshot.
+ * Nevertheless, this is not guaranteed by the implementation, so we must
+ * disable the RTC while updating it.
+ */
+static int p1_rtc_set_time(struct device *dev, struct rtc_time *t)
+{
+	struct p1_rtc *p1 = dev_get_drvdata(dev);
+	struct regmap *regmap = p1->regmap;
+	u8 time[6];
+	int ret;
+
+	time[0] = t->tm_sec;
+	time[1] = t->tm_min;
+	time[2] = t->tm_hour;
+	time[3] = t->tm_mday - 1;
+	time[4] = t->tm_mon;
+	time[5] = t->tm_year - 100;
+
+	/* Disable the RTC to update; re-enable again when done */
+	ret = regmap_clear_bits(regmap, RTC_CTRL, RTC_EN);
+	if (ret)
+		return ret;
+
+	/* If something goes wrong, leave the RTC disabled */
+	ret = regmap_bulk_write(regmap, RTC_TIME, time, sizeof(time));
+	if (ret)
+		return ret;
+
+	return regmap_set_bits(regmap, RTC_CTRL, RTC_EN);
+}
+
+static const struct rtc_class_ops p1_rtc_class_ops = {
+	.read_time = p1_rtc_read_time,
+	.set_time = p1_rtc_set_time,
+};
+
+static int p1_rtc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rtc_device *rtc;
+	struct p1_rtc *p1;
+
+	p1 = devm_kzalloc(dev, sizeof(*p1), GFP_KERNEL);
+	if (!p1)
+		return -ENOMEM;
+	dev_set_drvdata(dev, p1);
+
+	p1->regmap = dev_get_regmap(dev->parent, NULL);
+	if (!p1->regmap)
+		return dev_err_probe(dev, -ENODEV, "failed to get regmap\n");
+
+	rtc = devm_rtc_allocate_device(dev);
+	if (IS_ERR(rtc))
+		return dev_err_probe(dev, PTR_ERR(rtc),
+				     "error allocating device\n");
+	p1->rtc = rtc;
+
+	rtc->ops = &p1_rtc_class_ops;
+	rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+	rtc->range_max = RTC_TIMESTAMP_END_2063;
+
+	clear_bit(RTC_FEATURE_ALARM, rtc->features);
+	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features);
+
+	return devm_rtc_register_device(rtc);
+}
+
+static struct platform_driver p1_rtc_driver = {
+	.probe = p1_rtc_probe,
+	.driver = {
+		.name = MOD_NAME,
+	},
+};
+
+module_platform_driver(p1_rtc_driver);
+
+MODULE_DESCRIPTION("SpacemiT P1 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" MOD_NAME);
-- 
2.45.2


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

* [PATCH v8 6/8] riscv: dts: spacemit: enable the i2c8 adapter
  2025-07-10 17:50 [PATCH v8 0/8] spacemit: introduce P1 PMIC support Alex Elder
                   ` (4 preceding siblings ...)
  2025-07-10 17:51 ` [PATCH v8 5/8] rtc: spacemit: support the SpacemiT P1 RTC Alex Elder
@ 2025-07-10 17:51 ` Alex Elder
  2025-07-10 17:51 ` [PATCH v8 7/8] riscv: dts: spacemit: define fixed regulators Alex Elder
  2025-07-10 17:51 ` [PATCH v8 8/8] riscv: dts: spacemit: define regulator constraints Alex Elder
  7 siblings, 0 replies; 14+ messages in thread
From: Alex Elder @ 2025-07-10 17:51 UTC (permalink / raw)
  To: lee, lgirdwood, broonie, alexandre.belloni, robh, krzk+dt,
	conor+dt
  Cc: mat.jonczyk, dlan, paul.walmsley, palmer, aou, alex,
	troymitchell988, guodong, linux-rtc, devicetree, linux-riscv,
	spacemit, linux-kernel

Define properties for the I2C adapter that provides access to the
SpacemiT P1 PMIC.  Enable this adapter on the Banana Pi BPI-F3.

Signed-off-by: Alex Elder <elder@riscstar.com>
---
 arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts | 15 +++++++++++++++
 arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi    |  7 +++++++
 arch/riscv/boot/dts/spacemit/k1.dtsi            | 11 +++++++++++
 3 files changed, 33 insertions(+)

diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
index fe22c747c5012..7c9f91c88e01a 100644
--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
@@ -40,6 +40,21 @@ &emmc {
 	status = "okay";
 };
 
+&i2c8 {
+	pinctrl-0 = <&i2c8_cfg>;
+	pinctrl-names = "default";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	pmic@41 {
+		compatible = "spacemit,p1";
+		reg = <0x41>;
+		interrupts = <64>;
+		status = "okay";
+	};
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_2_cfg>;
diff --git a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
index 3810557374228..96d7a46d4bf77 100644
--- a/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
+++ b/arch/riscv/boot/dts/spacemit/k1-pinctrl.dtsi
@@ -11,6 +11,13 @@
 #define K1_GPIO(x)	(x / 32) (x % 32)
 
 &pinctrl {
+	i2c8_cfg: i2c8-cfg {
+		i2c8-0-pins {
+			pinmux = <K1_PADCONF(93, 0)>,	/* PWR_SCL */
+				 <K1_PADCONF(94, 0)>;	/* PWR_SDA */
+		};
+	};
+
 	uart0_2_cfg: uart0-2-cfg {
 		uart0-2-pins {
 			pinmux = <K1_PADCONF(68, 2)>,
diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi
index abde8bb07c95c..2a5a132d5a774 100644
--- a/arch/riscv/boot/dts/spacemit/k1.dtsi
+++ b/arch/riscv/boot/dts/spacemit/k1.dtsi
@@ -459,6 +459,17 @@ pwm7: pwm@d401bc00 {
 			status = "disabled";
 		};
 
+		i2c8: i2c@d401d800 {
+			compatible = "spacemit,k1-i2c";
+			reg = <0x0 0xd401d800 0x0 0x38>;
+			interrupts = <19>;
+			clocks = <&syscon_apbc CLK_TWSI8>,
+				 <&syscon_apbc CLK_TWSI8_BUS>;
+			clock-names = "func", "bus";
+			clock-frequency = <400000>;
+			status = "disabled";
+		};
+
 		pinctrl: pinctrl@d401e000 {
 			compatible = "spacemit,k1-pinctrl";
 			reg = <0x0 0xd401e000 0x0 0x400>;
-- 
2.45.2


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

* [PATCH v8 7/8] riscv: dts: spacemit: define fixed regulators
  2025-07-10 17:50 [PATCH v8 0/8] spacemit: introduce P1 PMIC support Alex Elder
                   ` (5 preceding siblings ...)
  2025-07-10 17:51 ` [PATCH v8 6/8] riscv: dts: spacemit: enable the i2c8 adapter Alex Elder
@ 2025-07-10 17:51 ` Alex Elder
  2025-07-10 17:51 ` [PATCH v8 8/8] riscv: dts: spacemit: define regulator constraints Alex Elder
  7 siblings, 0 replies; 14+ messages in thread
From: Alex Elder @ 2025-07-10 17:51 UTC (permalink / raw)
  To: lee, lgirdwood, broonie, alexandre.belloni, robh, krzk+dt,
	conor+dt
  Cc: mat.jonczyk, dlan, paul.walmsley, palmer, aou, alex,
	troymitchell988, guodong, linux-rtc, devicetree, linux-riscv,
	spacemit, linux-kernel

Define the DC power input and the 4v power as fixed supplies in the
Banana Pi BPI-F3.

Signed-off-by: Alex Elder <elder@riscstar.com>
---
 .../boot/dts/spacemit/k1-bananapi-f3.dts      | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
index 7c9f91c88e01a..a1c184b814262 100644
--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
@@ -28,6 +28,25 @@ led1 {
 			default-state = "on";
 		};
 	};
+
+	reg_dc_in: dc-in-12v {
+		compatible = "regulator-fixed";
+		regulator-name = "dc_in_12v";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	reg_vcc_4v: vcc-4v {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_4v";
+		regulator-min-microvolt = <4000000>;
+		regulator-max-microvolt = <4000000>;
+		regulator-boot-on;
+		regulator-always-on;
+		vin-supply = <&reg_dc_in>;
+	};
 };
 
 &emmc {
-- 
2.45.2


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

* [PATCH v8 8/8] riscv: dts: spacemit: define regulator constraints
  2025-07-10 17:50 [PATCH v8 0/8] spacemit: introduce P1 PMIC support Alex Elder
                   ` (6 preceding siblings ...)
  2025-07-10 17:51 ` [PATCH v8 7/8] riscv: dts: spacemit: define fixed regulators Alex Elder
@ 2025-07-10 17:51 ` Alex Elder
  7 siblings, 0 replies; 14+ messages in thread
From: Alex Elder @ 2025-07-10 17:51 UTC (permalink / raw)
  To: lee, lgirdwood, broonie, alexandre.belloni, robh, krzk+dt,
	conor+dt
  Cc: mat.jonczyk, dlan, paul.walmsley, palmer, aou, alex,
	troymitchell988, guodong, linux-rtc, devicetree, linux-riscv,
	spacemit, linux-kernel

Define basic constraints for the regulators in the SpacemiT P1 PMIC,
as implemented in the Banana Pi BPI-F3.

Signed-off-by: Alex Elder <elder@riscstar.com>
---
 .../boot/dts/spacemit/k1-bananapi-f3.dts      | 104 ++++++++++++++++++
 1 file changed, 104 insertions(+)

diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
index a1c184b814262..83907cc1d5ccf 100644
--- a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
+++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts
@@ -70,7 +70,111 @@ pmic@41 {
 		compatible = "spacemit,p1";
 		reg = <0x41>;
 		interrupts = <64>;
+		vin-supply = <&reg_vcc_4v>;
 		status = "okay";
+
+		regulators {
+			buck1 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3450000>;
+				regulator-ramp-delay = <5000>;
+				regulator-always-on;
+			};
+
+			buck2 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3450000>;
+				regulator-ramp-delay = <5000>;
+				regulator-always-on;
+			};
+
+			buck3 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-ramp-delay = <5000>;
+				regulator-always-on;
+			};
+
+			buck4 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-ramp-delay = <5000>;
+				regulator-always-on;
+			};
+
+			buck5 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3450000>;
+				regulator-ramp-delay = <5000>;
+				regulator-always-on;
+			};
+
+			buck6 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3450000>;
+				regulator-ramp-delay = <5000>;
+				regulator-always-on;
+			};
+
+			aldo1 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3400000>;
+				regulator-boot-on;
+			};
+
+			aldo2 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3400000>;
+			};
+
+			aldo3 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3400000>;
+			};
+
+			aldo4 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3400000>;
+			};
+
+			dldo1 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3400000>;
+				regulator-boot-on;
+			};
+
+			dldo2 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3400000>;
+			};
+
+			dldo3 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3400000>;
+			};
+
+			dldo4 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3400000>;
+				regulator-always-on;
+			};
+
+			dldo5 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3400000>;
+			};
+
+			dldo6 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3400000>;
+				regulator-always-on;
+			};
+
+			dldo7 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <3400000>;
+			};
+		};
 	};
 };
 
-- 
2.45.2


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

* Re: [PATCH v8 2/8] mfd: simple-mfd-i2c: specify max_register
  2025-07-10 17:51 ` [PATCH v8 2/8] mfd: simple-mfd-i2c: specify max_register Alex Elder
@ 2025-07-23  9:51   ` Lee Jones
  2025-07-23 12:42     ` Alex Elder
  0 siblings, 1 reply; 14+ messages in thread
From: Lee Jones @ 2025-07-23  9:51 UTC (permalink / raw)
  To: Alex Elder
  Cc: lgirdwood, broonie, alexandre.belloni, robh, krzk+dt, conor+dt,
	mat.jonczyk, dlan, paul.walmsley, palmer, aou, alex,
	troymitchell988, guodong, linux-rtc, devicetree, linux-riscv,
	spacemit, linux-kernel

On Thu, 10 Jul 2025, Alex Elder wrote:

> All devices supported by simple MFD use the same 8-bit register 8-bit
> value regmap configuration.  There is an option available for a device
> to specify a custom configuration, but no existing device uses it.
> 
> Rather than specify a "full" regmap configuration to change only
> the max_register value, Lee Jones suggested allowing max_register
> to be specified in the simple_mfd_data structure.  If regmap_config
> and max_register are both supplied, the max_register field is ignored.
> 
> Signed-off-by: Alex Elder <elder@riscstar.com>
> Suggested-by: Lee Jones <lee@kernel.org>
> ---
> v8: - Use regmap_config_8r_8v, modifying it if max_register supplied
> 
>  drivers/mfd/simple-mfd-i2c.c | 8 ++++++--
>  drivers/mfd/simple-mfd-i2c.h | 3 ++-
>  2 files changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
> index 22159913bea03..5138aa72140b5 100644
> --- a/drivers/mfd/simple-mfd-i2c.c
> +++ b/drivers/mfd/simple-mfd-i2c.c
> @@ -24,15 +24,16 @@
>  
>  #include "simple-mfd-i2c.h"
>  
> -static const struct regmap_config regmap_config_8r_8v = {
> +static struct regmap_config regmap_config_8r_8v = {
>  	.reg_bits = 8,
>  	.val_bits = 8,
> +	/* .max_register can be specified in simple_mfd_data */

Drop this comment please.

>  };
>  
>  static int simple_mfd_i2c_probe(struct i2c_client *i2c)
>  {
>  	const struct simple_mfd_data *simple_mfd_data;
> -	const struct regmap_config *regmap_config;
> +	struct regmap_config *regmap_config;
>  	struct regmap *regmap;
>  	int ret;
>  
> @@ -43,8 +44,11 @@ static int simple_mfd_i2c_probe(struct i2c_client *i2c)
>  		regmap_config = &regmap_config_8r_8v;
>  	else
>  		regmap_config = simple_mfd_data->regmap_config;
> +	if (simple_mfd_data && !simple_mfd_data->regmap_config)
> +		regmap_config->max_register = simple_mfd_data->max_register;

If max_register is set in simple_mfd_data, it should take precedence.

if (simple_mfd_data && simple_mfd_data->max_register)
	regmap_config->max_register = simple_mfd_data->max_register;

>  	regmap = devm_regmap_init_i2c(i2c, regmap_config);
> +	regmap_config->max_register = 0;

Does max_register definitely have persistence over subsequent calls?

>  	if (IS_ERR(regmap))
>  		return PTR_ERR(regmap);
>  
> diff --git a/drivers/mfd/simple-mfd-i2c.h b/drivers/mfd/simple-mfd-i2c.h
> index 7cb2bdd347d97..ea2a96af8bce4 100644
> --- a/drivers/mfd/simple-mfd-i2c.h
> +++ b/drivers/mfd/simple-mfd-i2c.h
> @@ -24,7 +24,8 @@
>  #include <linux/regmap.h>
>  
>  struct simple_mfd_data {
> -	const struct regmap_config *regmap_config;
> +	struct regmap_config *regmap_config;
> +	unsigned int max_register;	/* Ignored if regmap_config supplied */
>  	const struct mfd_cell *mfd_cell;
>  	size_t mfd_cell_size;
>  };
> -- 
> 2.45.2
> 

-- 
Lee Jones [李琼斯]

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

* Re: [PATCH v8 2/8] mfd: simple-mfd-i2c: specify max_register
  2025-07-23  9:51   ` Lee Jones
@ 2025-07-23 12:42     ` Alex Elder
  2025-07-24 10:14       ` Lee Jones
  0 siblings, 1 reply; 14+ messages in thread
From: Alex Elder @ 2025-07-23 12:42 UTC (permalink / raw)
  To: Lee Jones
  Cc: lgirdwood, broonie, alexandre.belloni, robh, krzk+dt, conor+dt,
	mat.jonczyk, dlan, paul.walmsley, palmer, aou, alex,
	troymitchell988, guodong, linux-rtc, devicetree, linux-riscv,
	spacemit, linux-kernel

On 7/23/25 4:51 AM, Lee Jones wrote:
> On Thu, 10 Jul 2025, Alex Elder wrote:
> 
>> All devices supported by simple MFD use the same 8-bit register 8-bit
>> value regmap configuration.  There is an option available for a device
>> to specify a custom configuration, but no existing device uses it.
>>
>> Rather than specify a "full" regmap configuration to change only
>> the max_register value, Lee Jones suggested allowing max_register
>> to be specified in the simple_mfd_data structure.  If regmap_config
>> and max_register are both supplied, the max_register field is ignored.
>>
>> Signed-off-by: Alex Elder <elder@riscstar.com>
>> Suggested-by: Lee Jones <lee@kernel.org>
>> ---
>> v8: - Use regmap_config_8r_8v, modifying it if max_register supplied
>>
>>   drivers/mfd/simple-mfd-i2c.c | 8 ++++++--
>>   drivers/mfd/simple-mfd-i2c.h | 3 ++-
>>   2 files changed, 8 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
>> index 22159913bea03..5138aa72140b5 100644
>> --- a/drivers/mfd/simple-mfd-i2c.c
>> +++ b/drivers/mfd/simple-mfd-i2c.c
>> @@ -24,15 +24,16 @@
>>   
>>   #include "simple-mfd-i2c.h"
>>   
>> -static const struct regmap_config regmap_config_8r_8v = {
>> +static struct regmap_config regmap_config_8r_8v = {
>>   	.reg_bits = 8,
>>   	.val_bits = 8,
>> +	/* .max_register can be specified in simple_mfd_data */
> 
> Drop this comment please.
> 
>>   };
>>   
>>   static int simple_mfd_i2c_probe(struct i2c_client *i2c)
>>   {
>>   	const struct simple_mfd_data *simple_mfd_data;
>> -	const struct regmap_config *regmap_config;
>> +	struct regmap_config *regmap_config;
>>   	struct regmap *regmap;
>>   	int ret;
>>   
>> @@ -43,8 +44,11 @@ static int simple_mfd_i2c_probe(struct i2c_client *i2c)
>>   		regmap_config = &regmap_config_8r_8v;
>>   	else
>>   		regmap_config = simple_mfd_data->regmap_config;
>> +	if (simple_mfd_data && !simple_mfd_data->regmap_config)
>> +		regmap_config->max_register = simple_mfd_data->max_register;
> 
> If max_register is set in simple_mfd_data, it should take precedence.

I don't really agree with that.  If simple_mfd_data->regmap_config
is provided, why not use the max_register field already available
there?

This is why I said above that I think this feature doesn't add
much value.  It provides a second way to specify something, but
in the end it complicates the code more than it's worth.

The only time this new simple_mfd_data->max_register field seems
to make sense is if it were the only thing provided (without
simple_mfd_data->regmap_config being supplied).  In that case,
I see the benefit--a null simple_mfd_data->regmap_config means
use regmap_config_8r_8v, and overlay it with the max_register
value.  The new max_register field avoids defining another huge
but mostly empty regmap_config structure.

Anyway, back to your original point:  I said in v7 "If both
are specified, the max_register value is ignored" and I think
that's the simplest.  Specify one or the other--if you want
to define things in regmap_config, then that's where you add
your max_register.  If you like regmap_config_8r_8v but want
to define a max_register value, just provide max_register.

If you insist, I'll do what you say but before I sent another
version I wanted to explain my reasoning.


> if (simple_mfd_data && simple_mfd_data->max_register)
> 	regmap_config->max_register = simple_mfd_data->max_register;
> 
>>   	regmap = devm_regmap_init_i2c(i2c, regmap_config);
>> +	regmap_config->max_register = 0;
> 
> Does max_register definitely have persistence over subsequent calls?

It is a global variable.  Isn't that how they work?  When
it was read-only there was no concern about that, nor about
any possible concurrent access (though I don't think multiple
probes can be using this code at once).

We could allocate a new one each time instead.

I think what I offered in v5 was acceptable.  If you're
willing to accept that I will be happy to keep discussing
(and implementing) the max_register feature.

					-Alex

> 
>>   	if (IS_ERR(regmap))
>>   		return PTR_ERR(regmap);
>>   
>> diff --git a/drivers/mfd/simple-mfd-i2c.h b/drivers/mfd/simple-mfd-i2c.h
>> index 7cb2bdd347d97..ea2a96af8bce4 100644
>> --- a/drivers/mfd/simple-mfd-i2c.h
>> +++ b/drivers/mfd/simple-mfd-i2c.h
>> @@ -24,7 +24,8 @@
>>   #include <linux/regmap.h>
>>   
>>   struct simple_mfd_data {
>> -	const struct regmap_config *regmap_config;
>> +	struct regmap_config *regmap_config;
>> +	unsigned int max_register;	/* Ignored if regmap_config supplied */
>>   	const struct mfd_cell *mfd_cell;
>>   	size_t mfd_cell_size;
>>   };
>> -- 
>> 2.45.2
>>
> 


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

* Re: [PATCH v8 5/8] rtc: spacemit: support the SpacemiT P1 RTC
  2025-07-10 17:51 ` [PATCH v8 5/8] rtc: spacemit: support the SpacemiT P1 RTC Alex Elder
@ 2025-07-23 21:39   ` Alexandre Belloni
  2025-07-23 23:37     ` Alex Elder
  0 siblings, 1 reply; 14+ messages in thread
From: Alexandre Belloni @ 2025-07-23 21:39 UTC (permalink / raw)
  To: Alex Elder
  Cc: lee, lgirdwood, broonie, robh, krzk+dt, conor+dt, mat.jonczyk,
	dlan, paul.walmsley, palmer, aou, alex, troymitchell988, guodong,
	linux-rtc, devicetree, linux-riscv, spacemit, linux-kernel

On 10/07/2025 12:51:03-0500, Alex Elder wrote:
> +static int p1_rtc_read_time(struct device *dev, struct rtc_time *t)
> +{
> +	struct p1_rtc *p1 = dev_get_drvdata(dev);
> +	struct regmap *regmap = p1->regmap;
> +	u32 count = RTC_READ_TRIES;
> +	u8 seconds;
> +	u8 time[6];
> +	int ret;
> +
> +	if (!regmap_test_bits(regmap, RTC_CTRL, RTC_EN))
> +		return -ENODEV;		/* RTC is disabled */

That should be -EINVAL, as all the other drivers have standardized this.

With this fixed,
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>


> +
> +	ret = regmap_bulk_read(regmap, RTC_TIME, time, sizeof(time));
> +	if (ret)
> +		return ret;
> +
> +	do {
> +		seconds = time[0];
> +		ret = regmap_bulk_read(regmap, RTC_TIME, time, sizeof(time));
> +		if (ret)
> +			return ret;
> +	} while (time[0] != seconds && --count);
> +
> +	if (!count)
> +		return -EIO;		/* Unable to get a consistent result */
> +
> +	t->tm_sec = time[0] & GENMASK(5, 0);
> +	t->tm_min = time[1] & GENMASK(5, 0);
> +	t->tm_hour = time[2] & GENMASK(4, 0);
> +	t->tm_mday = (time[3] & GENMASK(4, 0)) + 1;
> +	t->tm_mon = time[4] & GENMASK(3, 0);
> +	t->tm_year = (time[5] & GENMASK(5, 0)) + 100;
> +
> +	return 0;
> +}
> +
> +/*
> + * The P1 hardware documentation states that values in the registers are
> + * latched so when written they represent a consistent time snapshot.
> + * Nevertheless, this is not guaranteed by the implementation, so we must
> + * disable the RTC while updating it.
> + */
> +static int p1_rtc_set_time(struct device *dev, struct rtc_time *t)
> +{
> +	struct p1_rtc *p1 = dev_get_drvdata(dev);
> +	struct regmap *regmap = p1->regmap;
> +	u8 time[6];
> +	int ret;
> +
> +	time[0] = t->tm_sec;
> +	time[1] = t->tm_min;
> +	time[2] = t->tm_hour;
> +	time[3] = t->tm_mday - 1;
> +	time[4] = t->tm_mon;
> +	time[5] = t->tm_year - 100;
> +
> +	/* Disable the RTC to update; re-enable again when done */
> +	ret = regmap_clear_bits(regmap, RTC_CTRL, RTC_EN);
> +	if (ret)
> +		return ret;
> +
> +	/* If something goes wrong, leave the RTC disabled */
> +	ret = regmap_bulk_write(regmap, RTC_TIME, time, sizeof(time));
> +	if (ret)
> +		return ret;
> +
> +	return regmap_set_bits(regmap, RTC_CTRL, RTC_EN);
> +}
> +
> +static const struct rtc_class_ops p1_rtc_class_ops = {
> +	.read_time = p1_rtc_read_time,
> +	.set_time = p1_rtc_set_time,
> +};
> +
> +static int p1_rtc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct rtc_device *rtc;
> +	struct p1_rtc *p1;
> +
> +	p1 = devm_kzalloc(dev, sizeof(*p1), GFP_KERNEL);
> +	if (!p1)
> +		return -ENOMEM;
> +	dev_set_drvdata(dev, p1);
> +
> +	p1->regmap = dev_get_regmap(dev->parent, NULL);
> +	if (!p1->regmap)
> +		return dev_err_probe(dev, -ENODEV, "failed to get regmap\n");
> +
> +	rtc = devm_rtc_allocate_device(dev);
> +	if (IS_ERR(rtc))
> +		return dev_err_probe(dev, PTR_ERR(rtc),
> +				     "error allocating device\n");
> +	p1->rtc = rtc;
> +
> +	rtc->ops = &p1_rtc_class_ops;
> +	rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
> +	rtc->range_max = RTC_TIMESTAMP_END_2063;
> +
> +	clear_bit(RTC_FEATURE_ALARM, rtc->features);
> +	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features);
> +
> +	return devm_rtc_register_device(rtc);
> +}
> +
> +static struct platform_driver p1_rtc_driver = {
> +	.probe = p1_rtc_probe,
> +	.driver = {
> +		.name = MOD_NAME,
> +	},
> +};
> +
> +module_platform_driver(p1_rtc_driver);
> +
> +MODULE_DESCRIPTION("SpacemiT P1 RTC driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:" MOD_NAME);
> -- 
> 2.45.2
> 

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

* Re: [PATCH v8 5/8] rtc: spacemit: support the SpacemiT P1 RTC
  2025-07-23 21:39   ` Alexandre Belloni
@ 2025-07-23 23:37     ` Alex Elder
  0 siblings, 0 replies; 14+ messages in thread
From: Alex Elder @ 2025-07-23 23:37 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: lee, lgirdwood, broonie, robh, krzk+dt, conor+dt, mat.jonczyk,
	dlan, paul.walmsley, palmer, aou, alex, troymitchell988, guodong,
	linux-rtc, devicetree, linux-riscv, spacemit, linux-kernel

On 7/23/25 4:39 PM, Alexandre Belloni wrote:
> On 10/07/2025 12:51:03-0500, Alex Elder wrote:
>> +static int p1_rtc_read_time(struct device *dev, struct rtc_time *t)
>> +{
>> +	struct p1_rtc *p1 = dev_get_drvdata(dev);
>> +	struct regmap *regmap = p1->regmap;
>> +	u32 count = RTC_READ_TRIES;
>> +	u8 seconds;
>> +	u8 time[6];
>> +	int ret;
>> +
>> +	if (!regmap_test_bits(regmap, RTC_CTRL, RTC_EN))
>> +		return -ENODEV;		/* RTC is disabled */
> 
> That should be -EINVAL, as all the other drivers have standardized this.
> 
> With this fixed,
> Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

OK thank you.  I'll plan to send v9 with this change included.

					-Alex

> 
> 
>> +
>> +	ret = regmap_bulk_read(regmap, RTC_TIME, time, sizeof(time));
>> +	if (ret)
>> +		return ret;
>> +
>> +	do {
>> +		seconds = time[0];
>> +		ret = regmap_bulk_read(regmap, RTC_TIME, time, sizeof(time));
>> +		if (ret)
>> +			return ret;
>> +	} while (time[0] != seconds && --count);
>> +
>> +	if (!count)
>> +		return -EIO;		/* Unable to get a consistent result */
>> +
>> +	t->tm_sec = time[0] & GENMASK(5, 0);
>> +	t->tm_min = time[1] & GENMASK(5, 0);
>> +	t->tm_hour = time[2] & GENMASK(4, 0);
>> +	t->tm_mday = (time[3] & GENMASK(4, 0)) + 1;
>> +	t->tm_mon = time[4] & GENMASK(3, 0);
>> +	t->tm_year = (time[5] & GENMASK(5, 0)) + 100;
>> +
>> +	return 0;
>> +}
>> +
>> +/*
>> + * The P1 hardware documentation states that values in the registers are
>> + * latched so when written they represent a consistent time snapshot.
>> + * Nevertheless, this is not guaranteed by the implementation, so we must
>> + * disable the RTC while updating it.
>> + */
>> +static int p1_rtc_set_time(struct device *dev, struct rtc_time *t)
>> +{
>> +	struct p1_rtc *p1 = dev_get_drvdata(dev);
>> +	struct regmap *regmap = p1->regmap;
>> +	u8 time[6];
>> +	int ret;
>> +
>> +	time[0] = t->tm_sec;
>> +	time[1] = t->tm_min;
>> +	time[2] = t->tm_hour;
>> +	time[3] = t->tm_mday - 1;
>> +	time[4] = t->tm_mon;
>> +	time[5] = t->tm_year - 100;
>> +
>> +	/* Disable the RTC to update; re-enable again when done */
>> +	ret = regmap_clear_bits(regmap, RTC_CTRL, RTC_EN);
>> +	if (ret)
>> +		return ret;
>> +
>> +	/* If something goes wrong, leave the RTC disabled */
>> +	ret = regmap_bulk_write(regmap, RTC_TIME, time, sizeof(time));
>> +	if (ret)
>> +		return ret;
>> +
>> +	return regmap_set_bits(regmap, RTC_CTRL, RTC_EN);
>> +}
>> +
>> +static const struct rtc_class_ops p1_rtc_class_ops = {
>> +	.read_time = p1_rtc_read_time,
>> +	.set_time = p1_rtc_set_time,
>> +};
>> +
>> +static int p1_rtc_probe(struct platform_device *pdev)
>> +{
>> +	struct device *dev = &pdev->dev;
>> +	struct rtc_device *rtc;
>> +	struct p1_rtc *p1;
>> +
>> +	p1 = devm_kzalloc(dev, sizeof(*p1), GFP_KERNEL);
>> +	if (!p1)
>> +		return -ENOMEM;
>> +	dev_set_drvdata(dev, p1);
>> +
>> +	p1->regmap = dev_get_regmap(dev->parent, NULL);
>> +	if (!p1->regmap)
>> +		return dev_err_probe(dev, -ENODEV, "failed to get regmap\n");
>> +
>> +	rtc = devm_rtc_allocate_device(dev);
>> +	if (IS_ERR(rtc))
>> +		return dev_err_probe(dev, PTR_ERR(rtc),
>> +				     "error allocating device\n");
>> +	p1->rtc = rtc;
>> +
>> +	rtc->ops = &p1_rtc_class_ops;
>> +	rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
>> +	rtc->range_max = RTC_TIMESTAMP_END_2063;
>> +
>> +	clear_bit(RTC_FEATURE_ALARM, rtc->features);
>> +	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features);
>> +
>> +	return devm_rtc_register_device(rtc);
>> +}
>> +
>> +static struct platform_driver p1_rtc_driver = {
>> +	.probe = p1_rtc_probe,
>> +	.driver = {
>> +		.name = MOD_NAME,
>> +	},
>> +};
>> +
>> +module_platform_driver(p1_rtc_driver);
>> +
>> +MODULE_DESCRIPTION("SpacemiT P1 RTC driver");
>> +MODULE_LICENSE("GPL");
>> +MODULE_ALIAS("platform:" MOD_NAME);
>> -- 
>> 2.45.2
>>
> 


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

* Re: [PATCH v8 2/8] mfd: simple-mfd-i2c: specify max_register
  2025-07-23 12:42     ` Alex Elder
@ 2025-07-24 10:14       ` Lee Jones
  0 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2025-07-24 10:14 UTC (permalink / raw)
  To: Alex Elder
  Cc: lgirdwood, broonie, alexandre.belloni, robh, krzk+dt, conor+dt,
	mat.jonczyk, dlan, paul.walmsley, palmer, aou, alex,
	troymitchell988, guodong, linux-rtc, devicetree, linux-riscv,
	spacemit, linux-kernel

On Wed, 23 Jul 2025, Alex Elder wrote:

> On 7/23/25 4:51 AM, Lee Jones wrote:
> > On Thu, 10 Jul 2025, Alex Elder wrote:
> > 
> > > All devices supported by simple MFD use the same 8-bit register 8-bit
> > > value regmap configuration.  There is an option available for a device
> > > to specify a custom configuration, but no existing device uses it.
> > > 
> > > Rather than specify a "full" regmap configuration to change only
> > > the max_register value, Lee Jones suggested allowing max_register
> > > to be specified in the simple_mfd_data structure.  If regmap_config
> > > and max_register are both supplied, the max_register field is ignored.
> > > 
> > > Signed-off-by: Alex Elder <elder@riscstar.com>
> > > Suggested-by: Lee Jones <lee@kernel.org>
> > > ---
> > > v8: - Use regmap_config_8r_8v, modifying it if max_register supplied
> > > 
> > >   drivers/mfd/simple-mfd-i2c.c | 8 ++++++--
> > >   drivers/mfd/simple-mfd-i2c.h | 3 ++-
> > >   2 files changed, 8 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
> > > index 22159913bea03..5138aa72140b5 100644
> > > --- a/drivers/mfd/simple-mfd-i2c.c
> > > +++ b/drivers/mfd/simple-mfd-i2c.c
> > > @@ -24,15 +24,16 @@
> > >   #include "simple-mfd-i2c.h"
> > > -static const struct regmap_config regmap_config_8r_8v = {
> > > +static struct regmap_config regmap_config_8r_8v = {
> > >   	.reg_bits = 8,
> > >   	.val_bits = 8,
> > > +	/* .max_register can be specified in simple_mfd_data */
> > 
> > Drop this comment please.
> > 
> > >   };
> > >   static int simple_mfd_i2c_probe(struct i2c_client *i2c)
> > >   {
> > >   	const struct simple_mfd_data *simple_mfd_data;
> > > -	const struct regmap_config *regmap_config;
> > > +	struct regmap_config *regmap_config;
> > >   	struct regmap *regmap;
> > >   	int ret;
> > > @@ -43,8 +44,11 @@ static int simple_mfd_i2c_probe(struct i2c_client *i2c)
> > >   		regmap_config = &regmap_config_8r_8v;
> > >   	else
> > >   		regmap_config = simple_mfd_data->regmap_config;
> > > +	if (simple_mfd_data && !simple_mfd_data->regmap_config)
> > > +		regmap_config->max_register = simple_mfd_data->max_register;
> > 
> > If max_register is set in simple_mfd_data, it should take precedence.
> 
> I don't really agree with that.  If simple_mfd_data->regmap_config
> is provided, why not use the max_register field already available
> there?

Why would a user add a max_register override to simple_mfd_data if they
didn't want to use it?

> This is why I said above that I think this feature doesn't add
> much value.  It provides a second way to specify something, but
> in the end it complicates the code more than it's worth.
> 
> The only time this new simple_mfd_data->max_register field seems
> to make sense is if it were the only thing provided (without
> simple_mfd_data->regmap_config being supplied).  In that case,
> I see the benefit--a null simple_mfd_data->regmap_config means
> use regmap_config_8r_8v, and overlay it with the max_register
> value.  The new max_register field avoids defining another huge
> but mostly empty regmap_config structure.

This is your use-case, right?

> Anyway, back to your original point:  I said in v7 "If both
> are specified, the max_register value is ignored" and I think
> that's the simplest.  Specify one or the other--if you want
> to define things in regmap_config, then that's where you add
> your max_register.  If you like regmap_config_8r_8v but want
> to define a max_register value, just provide max_register.
> 
> If you insist, I'll do what you say but before I sent another
> version I wanted to explain my reasoning.

I hear you and I get what you're saying.

I see no use-case where a user would provide both regmap_config AND
max_register either.  However, I see max_register in simple_mfd_data as
an override, so I would like it to take precedence please.

> > if (simple_mfd_data && simple_mfd_data->max_register)
> > 	regmap_config->max_register = simple_mfd_data->max_register;
> > 
> > >   	regmap = devm_regmap_init_i2c(i2c, regmap_config);
> > > +	regmap_config->max_register = 0;
> > 
> > Does max_register definitely have persistence over subsequent calls?
> 
> It is a global variable.  Isn't that how they work?  When
> it was read-only there was no concern about that, nor about
> any possible concurrent access (though I don't think multiple
> probes can be using this code at once).
> 
> We could allocate a new one each time instead.
> 
> I think what I offered in v5 was acceptable.  If you're
> willing to accept that I will be happy to keep discussing
> (and implementing) the max_register feature.

Yes, I'm inclined to agree.

Make the call and I will respect your decision.

-- 
Lee Jones [李琼斯]

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

end of thread, other threads:[~2025-07-24 10:14 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-10 17:50 [PATCH v8 0/8] spacemit: introduce P1 PMIC support Alex Elder
2025-07-10 17:50 ` [PATCH v8 1/8] dt-bindings: mfd: add support the SpacemiT P1 PMIC Alex Elder
2025-07-10 17:51 ` [PATCH v8 2/8] mfd: simple-mfd-i2c: specify max_register Alex Elder
2025-07-23  9:51   ` Lee Jones
2025-07-23 12:42     ` Alex Elder
2025-07-24 10:14       ` Lee Jones
2025-07-10 17:51 ` [PATCH v8 3/8] mfd: simple-mfd-i2c: add SpacemiT P1 support Alex Elder
2025-07-10 17:51 ` [PATCH v8 4/8] regulator: spacemit: support SpacemiT P1 regulators Alex Elder
2025-07-10 17:51 ` [PATCH v8 5/8] rtc: spacemit: support the SpacemiT P1 RTC Alex Elder
2025-07-23 21:39   ` Alexandre Belloni
2025-07-23 23:37     ` Alex Elder
2025-07-10 17:51 ` [PATCH v8 6/8] riscv: dts: spacemit: enable the i2c8 adapter Alex Elder
2025-07-10 17:51 ` [PATCH v8 7/8] riscv: dts: spacemit: define fixed regulators Alex Elder
2025-07-10 17:51 ` [PATCH v8 8/8] riscv: dts: spacemit: define regulator constraints Alex Elder

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