From: Matti Vaittinen <matti.vaittinen@linux.dev>
To: Matti Vaittinen <mazziesaccount@gmail.com>,
Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>,
Matti Vaittinen <matti.vaittinen@linux.dev>
Cc: Lee Jones <lee@kernel.org>, Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Liam Girdwood <lgirdwood@gmail.com>,
Mark Brown <broonie@kernel.org>,
Matti Vaittinen <mazziesaccount@gmail.com>,
Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@kernel.org>,
Brian Masney <bmasney@redhat.com>,
Linus Walleij <linusw@kernel.org>,
Bartosz Golaszewski <brgl@kernel.org>,
Alexandre Belloni <alexandre.belloni@bootlin.com>,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org,
linux-rtc@vger.kernel.org
Subject: [PATCH 5/8] regulator: bd71828: Support ROHM BD73800
Date: Wed, 1 Jul 2026 15:42:35 +0300 [thread overview]
Message-ID: <1d00359236272fd1fab0dfbcb9119d2f91aa0d23.1782909323.git.mazziesaccount@gmail.com> (raw)
In-Reply-To: <cover.1782909323.git.mazziesaccount@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 23837 bytes --]
From: Matti Vaittinen <mazziesaccount@gmail.com>
The ROHM BD73800 is a power management IC which integrates 8 BUCKs and 4
LDOs. The PMIC has internal state-machine and it can support transitions
to RUN, SUSPEND and IDLE states. The LDOs 1 and 3 have two different
voltage range configurations that can be set at the manufacturing phase
by OTP. By default driver assumes low voltage ranges to be used because
the data-sheet indicates the higher voltage ranges to be an 'OTP option'.
The high voltage range can be indicated via device-tree property.
Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
---
drivers/regulator/Kconfig | 4 +-
drivers/regulator/bd71828-regulator.c | 555 +++++++++++++++++++++++++-
2 files changed, 556 insertions(+), 3 deletions(-)
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index a54a549196fe..0e5a3994f49d 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -241,12 +241,12 @@ config REGULATOR_BD71815
will be called bd71815-regulator.
config REGULATOR_BD71828
- tristate "ROHM BD71828, BD72720 and BD73900 Power Regulators"
+ tristate "ROHM BD71828, BD72720 and BD73[8/9]00 Power Regulators"
depends on MFD_ROHM_BD71828
select REGULATOR_ROHM
help
This driver supports voltage regulators on ROHM BD71828,
- BD71879, BD72720 and BD73900 PMICs. This will enable
+ BD71879, BD72720 and BD73[8/9]00 PMICs. This will enable
support for the software controllable buck and LDO regulators.
This driver can also be built as a module. If so, the module
diff --git a/drivers/regulator/bd71828-regulator.c b/drivers/regulator/bd71828-regulator.c
index bd61caa8284a..89738953f8b5 100644
--- a/drivers/regulator/bd71828-regulator.c
+++ b/drivers/regulator/bd71828-regulator.c
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
// Copyright (C) 2019 ROHM Semiconductors
// bd71828-regulator.c ROHM BD71828GW-DS1 regulator driver
-//
#include <linux/cleanup.h>
#include <linux/delay.h>
@@ -10,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/mfd/rohm-bd71828.h>
#include <linux/mfd/rohm-bd72720.h>
+#include <linux/mfd/rohm-bd73800.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h>
@@ -32,6 +32,13 @@ struct bd71828_regulator_data {
int reg_init_amnt;
};
+/*
+ * LDO1 and LDO3 node names are used also in the driver to find OTP setting for
+ * the used voltage range.
+ */
+#define LDO1_NODE_NAME "ldo1"
+#define LDO3_NODE_NAME "ldo3"
+
static const struct reg_init bd71828_buck1_inits[] = {
/*
* DVS Buck voltages can be changed by register values or via GPIO.
@@ -173,6 +180,54 @@ static const struct linear_range bd72720_ldo6_volts[] = {
REGULATOR_LINEAR_RANGE(1800000, 0x79, 0x7f, 0),
};
+static const struct linear_range bd73800_buck12348_volts[] = {
+ REGULATOR_LINEAR_RANGE(500000, 0x00, 0x50, 10000),
+ REGULATOR_LINEAR_RANGE(1300000, 0x51, 0xff, 0),
+};
+
+static const unsigned int bd73800_buck5_volt_range_sel[] = {
+ 0x0, 0x0, 0x1, 0x1,
+};
+
+static const struct linear_range bd73800_buck5_volts[] = {
+ /* range selector 0 */
+ REGULATOR_LINEAR_RANGE(500000, 0x00, 0x50, 10000),
+ REGULATOR_LINEAR_RANGE(1300000, 0x51, 0x7f, 0),
+ /* range selector 1 */
+ REGULATOR_LINEAR_RANGE(300000, 0x00, 0x46, 10000),
+ REGULATOR_LINEAR_RANGE(1000000, 0x47, 0x7f, 0),
+};
+/*
+ * iBUCK5 has two different pickable ranges, each having voltages matching
+ * selectors 0x0 to 0x7f. This gives 0x7f + 1 different voltages for each of
+ * the ranges.
+ */
+#define BD73800_NUM_BUCK5_VOLTS ((0x7f + 1) * 2)
+
+static const struct linear_range bd73800_buck67_volts[] = {
+ REGULATOR_LINEAR_RANGE(1500000, 0x00, 0xc8, 10000),
+ REGULATOR_LINEAR_RANGE(3500000, 0xc9, 0xff, 0),
+};
+
+/*
+ * On the BD73800 the LDO1 and LDO3 support two different voltage areas.
+ * Whether to use 'high' or 'low' ranges is configured by OTP. There seems
+ * to be no register to read the configured area so it must be given via
+ * device-tree properties.
+ */
+static const struct linear_range bd73800_ldo13_low_volts[] = {
+ REGULATOR_LINEAR_RANGE(600000, 0x00, 0x78, 10000),
+ REGULATOR_LINEAR_RANGE(1800000, 0x79, 0xff, 0),
+};
+
+static const struct linear_range bd73800_ldo13_high_volts[] = {
+ REGULATOR_LINEAR_RANGE(750000, 0x00, 0xff, 10000),
+};
+
+static const struct linear_range bd73800_ldo24_volts[] = {
+ REGULATOR_LINEAR_RANGE(750000, 0x00, 0xff, 10000),
+};
+
static const unsigned int bd71828_ramp_delay[] = { 2500, 5000, 10000, 20000 };
/*
@@ -226,6 +281,36 @@ static int bd71828_ldo6_parse_dt(struct device_node *np,
return 0;
}
+/* Operations for all other BUCKs but BUCK 5 */
+static const struct regulator_ops bd73800_buck_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_ramp_delay = regulator_set_ramp_delay_regmap,
+};
+
+static const struct regulator_ops bd73800_buck5_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_pickable_linear_range,
+ .set_voltage_sel = regulator_set_voltage_sel_pickable_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
+ .set_ramp_delay = regulator_set_ramp_delay_regmap,
+};
+
+static const struct regulator_ops bd73800_ldo_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+};
+
static const struct regulator_ops bd71828_buck_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -1566,6 +1651,412 @@ static const struct bd71828_regulator_data bd72720_rdata[] = {
},
};
+static const struct bd71828_regulator_data bd73800_rdata[] = {
+ {
+ .desc = {
+ .name = "buck1",
+ .of_match = of_match_ptr("buck1"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD73800_BUCK1,
+ .ops = &bd73800_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd73800_buck12348_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd73800_buck12348_volts),
+ .n_voltages = BD73800_NUM_VOLTS,
+ .enable_reg = BD73800_REG_BUCK1_ON,
+ .enable_mask = BD73800_MASK_RUN_EN,
+ .vsel_reg = BD73800_REG_BUCK1_VOLT_RUN,
+ .vsel_mask = BD73800_MASK_VOLT,
+ .ramp_delay_table = bd71828_ramp_delay,
+ .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),
+ .ramp_reg = BD73800_REG_BUCK1_MODE,
+ .ramp_mask = BD73800_MASK_RAMP_DELAY,
+ .owner = THIS_MODULE,
+ .of_parse_cb = buck_set_hw_dvs_levels,
+ },
+ .dvs = {
+ .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+ ROHM_DVS_LEVEL_SUSPEND,
+ .run_reg = BD73800_REG_BUCK1_VOLT_RUN,
+ .run_mask = BD73800_MASK_VOLT,
+ .idle_reg = BD73800_REG_BUCK1_VOLT_IDLE,
+ .idle_mask = BD73800_MASK_VOLT,
+ .idle_on_mask = BD73800_MASK_IDLE_EN,
+ .suspend_reg = BD73800_REG_BUCK1_VOLT_SUSP,
+ .suspend_mask = BD73800_MASK_VOLT,
+ .suspend_on_mask = BD73800_MASK_SUSP_EN,
+ },
+ }, {
+ .desc = {
+ .name = "buck2",
+ .of_match = of_match_ptr("buck2"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD73800_BUCK2,
+ .ops = &bd73800_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd73800_buck12348_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd73800_buck12348_volts),
+ .n_voltages = BD73800_NUM_VOLTS,
+ .enable_reg = BD73800_REG_BUCK2_ON,
+ .enable_mask = BD73800_MASK_RUN_EN,
+ .vsel_reg = BD73800_REG_BUCK2_VOLT_RUN,
+ .vsel_mask = BD73800_MASK_VOLT,
+ .ramp_delay_table = bd71828_ramp_delay,
+ .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),
+ .ramp_reg = BD73800_REG_BUCK2_MODE,
+ .ramp_mask = BD73800_MASK_RAMP_DELAY,
+ .owner = THIS_MODULE,
+ .of_parse_cb = buck_set_hw_dvs_levels,
+ },
+ .dvs = {
+ .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+ ROHM_DVS_LEVEL_SUSPEND,
+ .run_reg = BD73800_REG_BUCK2_VOLT_RUN,
+ .run_mask = BD73800_MASK_VOLT,
+ .idle_reg = BD73800_REG_BUCK2_VOLT_IDLE,
+ .idle_mask = BD73800_MASK_VOLT,
+ .idle_on_mask = BD73800_MASK_IDLE_EN,
+ .suspend_reg = BD73800_REG_BUCK2_VOLT_SUSP,
+ .suspend_mask = BD73800_MASK_VOLT,
+ .suspend_on_mask = BD73800_MASK_SUSP_EN,
+ },
+ }, {
+ .desc = {
+ .name = "buck3",
+ .of_match = of_match_ptr("buck3"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD73800_BUCK3,
+ .ops = &bd73800_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd73800_buck12348_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd73800_buck12348_volts),
+ .n_voltages = BD73800_NUM_VOLTS,
+ .enable_reg = BD73800_REG_BUCK3_ON,
+ .enable_mask = BD73800_MASK_RUN_EN,
+ .vsel_reg = BD73800_REG_BUCK3_VOLT_RUN,
+ .vsel_mask = BD73800_MASK_VOLT,
+ .ramp_delay_table = bd71828_ramp_delay,
+ .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),
+ .ramp_reg = BD73800_REG_BUCK3_MODE,
+ .ramp_mask = BD73800_MASK_RAMP_DELAY,
+ .owner = THIS_MODULE,
+ .of_parse_cb = buck_set_hw_dvs_levels,
+ },
+ .dvs = {
+ .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+ ROHM_DVS_LEVEL_SUSPEND,
+ .run_reg = BD73800_REG_BUCK3_VOLT_RUN,
+ .run_mask = BD73800_MASK_VOLT,
+ .idle_reg = BD73800_REG_BUCK3_VOLT_IDLE,
+ .idle_mask = BD73800_MASK_VOLT,
+ .idle_on_mask = BD73800_MASK_IDLE_EN,
+ .suspend_reg = BD73800_REG_BUCK3_VOLT_SUSP,
+ .suspend_mask = BD73800_MASK_VOLT,
+ .suspend_on_mask = BD73800_MASK_SUSP_EN,
+ },
+
+ }, {
+ .desc = {
+ .name = "buck4",
+ .of_match = of_match_ptr("buck4"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD73800_BUCK4,
+ .ops = &bd73800_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd73800_buck12348_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd73800_buck12348_volts),
+ .n_voltages = BD73800_NUM_VOLTS,
+ .enable_reg = BD73800_REG_BUCK4_ON,
+ .enable_mask = BD73800_MASK_RUN_EN,
+ .vsel_reg = BD73800_REG_BUCK4_VOLT_RUN,
+ .vsel_mask = BD73800_MASK_VOLT,
+ .ramp_delay_table = bd71828_ramp_delay,
+ .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),
+ .ramp_reg = BD73800_REG_BUCK4_MODE,
+ .ramp_mask = BD73800_MASK_RAMP_DELAY,
+ .owner = THIS_MODULE,
+ .of_parse_cb = buck_set_hw_dvs_levels,
+ },
+ .dvs = {
+ .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+ ROHM_DVS_LEVEL_SUSPEND,
+ .run_reg = BD73800_REG_BUCK4_VOLT_RUN,
+ .run_mask = BD73800_MASK_VOLT,
+ .idle_reg = BD73800_REG_BUCK4_VOLT_IDLE,
+ .idle_mask = BD73800_MASK_VOLT,
+ .idle_on_mask = BD73800_MASK_IDLE_EN,
+ .suspend_reg = BD73800_REG_BUCK4_VOLT_SUSP,
+ .suspend_mask = BD73800_MASK_VOLT,
+ .suspend_on_mask = BD73800_MASK_SUSP_EN,
+ },
+ }, {
+ .desc = {
+ .name = "buck5",
+ .of_match = of_match_ptr("buck5"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD73800_BUCK5,
+ .ops = &bd73800_buck5_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd73800_buck5_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd73800_buck5_volts),
+ .linear_range_selectors_bitfield =
+ bd73800_buck5_volt_range_sel,
+ .n_voltages = BD73800_NUM_BUCK5_VOLTS,
+ .enable_reg = BD73800_REG_BUCK5_ON,
+ .enable_mask = BD73800_MASK_RUN_EN,
+ .vsel_reg = BD73800_REG_BUCK5_VOLT_RUN,
+ .vsel_mask = BD73800_MASK_VOLT,
+ .vsel_range_reg = BD73800_REG_BUCK5_MODE,
+ .vsel_range_mask = BD73800_BUCK5_RANGE_MASK,
+ .range_applied_by_vsel = true,
+ .ramp_delay_table = bd71828_ramp_delay,
+ .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),
+ .ramp_reg = BD73800_REG_BUCK5_MODE,
+ .ramp_mask = BD73800_MASK_RAMP_DELAY,
+ .owner = THIS_MODULE,
+ },
+ .dvs = {
+ /*
+ * We don't support setting the IDLE / SUSPEND voltages
+ * for the BUCK 5 for now. Reason is that the pickable
+ * range selector bit is common for all states (RUN,
+ * SUSPEND and IDLE), and toggling it for one impacts
+ * also others.
+ * Furthermore, writing the BD73800 range selector does
+ * not impact the RUN voltage until a new voltage value
+ * is also written to the vsel register. Hence the
+ * voltage change can be done without any 'intermediate
+ * voltages', even when the range is changed when the
+ * BUCK is enabled.
+ * It, however, is not documented how the IDLE / SUSPEND
+ * states work in this regard. I expect the full
+ * combination of the range selector and vsel is taken
+ * into account at the state change, no matter when they
+ * have been written to.
+ */
+ .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+ ROHM_DVS_LEVEL_SUSPEND,
+ .run_reg = BD73800_REG_BUCK5_VOLT_RUN,
+ .run_mask = BD73800_MASK_VOLT,
+ .idle_on_mask = BD73800_MASK_IDLE_EN,
+ .suspend_on_mask = BD73800_MASK_SUSP_EN,
+ },
+
+ }, {
+ .desc = {
+ .name = "buck6",
+ .of_match = of_match_ptr("buck6"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD73800_BUCK6,
+ .ops = &bd73800_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd73800_buck67_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd73800_buck67_volts),
+ .n_voltages = BD73800_NUM_VOLTS,
+ .enable_reg = BD73800_REG_BUCK6_ON,
+ .enable_mask = BD73800_MASK_RUN_EN,
+ .vsel_reg = BD73800_REG_BUCK6_VOLT_RUN,
+ .vsel_mask = BD73800_MASK_VOLT,
+ .ramp_delay_table = bd71828_ramp_delay,
+ .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),
+ .ramp_reg = BD73800_REG_BUCK6_MODE,
+ .ramp_mask = BD73800_MASK_RAMP_DELAY,
+ .owner = THIS_MODULE,
+ .of_parse_cb = buck_set_hw_dvs_levels,
+ },
+ .dvs = {
+ .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+ ROHM_DVS_LEVEL_SUSPEND,
+ .run_reg = BD73800_REG_BUCK6_VOLT_RUN,
+ .run_mask = BD73800_MASK_VOLT,
+ .idle_reg = BD73800_REG_BUCK6_VOLT_IDLE,
+ .idle_mask = BD73800_MASK_VOLT,
+ .idle_on_mask = BD73800_MASK_IDLE_EN,
+ .suspend_reg = BD73800_REG_BUCK6_VOLT_SUSP,
+ .suspend_mask = BD73800_MASK_VOLT,
+ .suspend_on_mask = BD73800_MASK_SUSP_EN,
+ },
+ }, {
+ .desc = {
+ .name = "buck7",
+ .of_match = of_match_ptr("buck7"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD73800_BUCK7,
+ .ops = &bd73800_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd73800_buck67_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd73800_buck67_volts),
+ .n_voltages = BD73800_NUM_VOLTS,
+ .enable_reg = BD73800_REG_BUCK7_ON,
+ .enable_mask = BD73800_MASK_RUN_EN,
+ .vsel_reg = BD73800_REG_BUCK7_VOLT_RUN,
+ .vsel_mask = BD73800_MASK_VOLT,
+ .ramp_delay_table = bd71828_ramp_delay,
+ .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),
+ .ramp_reg = BD73800_REG_BUCK7_MODE,
+ .ramp_mask = BD73800_MASK_RAMP_DELAY,
+ .owner = THIS_MODULE,
+ .of_parse_cb = buck_set_hw_dvs_levels,
+ },
+ .dvs = {
+ .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+ ROHM_DVS_LEVEL_SUSPEND,
+ .run_reg = BD73800_REG_BUCK7_VOLT_RUN,
+ .run_mask = BD73800_MASK_VOLT,
+ .idle_reg = BD73800_REG_BUCK7_VOLT_IDLE,
+ .idle_mask = BD73800_MASK_VOLT,
+ .idle_on_mask = BD73800_MASK_IDLE_EN,
+ .suspend_reg = BD73800_REG_BUCK7_VOLT_SUSP,
+ .suspend_mask = BD73800_MASK_VOLT,
+ .suspend_on_mask = BD73800_MASK_SUSP_EN,
+ },
+ }, {
+ .desc = {
+ .name = "buck8",
+ .of_match = of_match_ptr("buck8"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD73800_BUCK8,
+ .ops = &bd73800_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd73800_buck12348_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd73800_buck12348_volts),
+ .n_voltages = BD73800_NUM_VOLTS,
+ .enable_reg = BD73800_REG_BUCK8_ON,
+ .enable_mask = BD73800_MASK_RUN_EN,
+ .vsel_reg = BD73800_REG_BUCK8_VOLT_RUN,
+ .vsel_mask = BD73800_MASK_VOLT,
+ .ramp_delay_table = bd71828_ramp_delay,
+ .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),
+ .ramp_reg = BD73800_REG_BUCK8_MODE,
+ .ramp_mask = BD73800_MASK_RAMP_DELAY,
+ .owner = THIS_MODULE,
+ .of_parse_cb = buck_set_hw_dvs_levels,
+ },
+ .dvs = {
+ .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+ ROHM_DVS_LEVEL_SUSPEND,
+ .run_reg = BD73800_REG_BUCK8_VOLT_RUN,
+ .run_mask = BD73800_MASK_VOLT,
+ .idle_reg = BD73800_REG_BUCK8_VOLT_IDLE,
+ .idle_mask = BD73800_MASK_VOLT,
+ .idle_on_mask = BD73800_MASK_IDLE_EN,
+ .suspend_reg = BD73800_REG_BUCK8_VOLT_SUSP,
+ .suspend_mask = BD73800_MASK_VOLT,
+ .suspend_on_mask = BD73800_MASK_SUSP_EN,
+ },
+ }, {
+ .desc = {
+ .name = "ldo1",
+ .of_match = of_match_ptr(LDO1_NODE_NAME),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD73800_LDO1,
+ .ops = &bd73800_ldo_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd73800_ldo13_low_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd73800_ldo13_low_volts),
+ .n_voltages = BD73800_NUM_VOLTS,
+ .enable_reg = BD73800_REG_LDO1_ON,
+ .enable_mask = BD73800_MASK_RUN_EN,
+ .vsel_reg = BD73800_REG_LDO1_VOLT,
+ .vsel_mask = BD73800_MASK_VOLT,
+ .owner = THIS_MODULE,
+ .of_parse_cb = buck_set_hw_dvs_levels,
+ },
+ .dvs = {
+ /*
+ * LDOs support only single voltage for all states.
+ * Voltage can be individually enabled for each state
+ * though. Allow setting enable/disable config by
+ * setting the <state>_on_mask for all supported states.
+ */
+ .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+ ROHM_DVS_LEVEL_SUSPEND,
+ .run_reg = BD73800_REG_LDO1_VOLT,
+ .run_mask = BD73800_MASK_VOLT,
+ .idle_on_mask = BD73800_MASK_IDLE_EN,
+ .suspend_on_mask = BD73800_MASK_SUSP_EN,
+ },
+ }, {
+ .desc = {
+ .name = "ldo2",
+ .of_match = of_match_ptr("ldo2"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD73800_LDO2,
+ .ops = &bd73800_ldo_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd73800_ldo24_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd73800_ldo24_volts),
+ .n_voltages = BD73800_NUM_VOLTS,
+ .enable_reg = BD73800_REG_LDO2_ON,
+ .enable_mask = BD73800_MASK_RUN_EN,
+ .vsel_reg = BD73800_REG_LDO2_VOLT,
+ .vsel_mask = BD73800_MASK_VOLT,
+ .owner = THIS_MODULE,
+ .of_parse_cb = buck_set_hw_dvs_levels,
+ },
+ .dvs = {
+ .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+ ROHM_DVS_LEVEL_SUSPEND,
+ .run_reg = BD73800_REG_LDO2_VOLT,
+ .run_mask = BD73800_MASK_VOLT,
+ .idle_on_mask = BD73800_MASK_IDLE_EN,
+ .suspend_on_mask = BD73800_MASK_SUSP_EN,
+ },
+ }, {
+ .desc = {
+ .name = "ldo3",
+ .of_match = of_match_ptr(LDO3_NODE_NAME),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD73800_LDO3,
+ .ops = &bd73800_ldo_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd73800_ldo13_low_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd73800_ldo13_low_volts),
+ .n_voltages = BD73800_NUM_VOLTS,
+ .enable_reg = BD73800_REG_LDO3_ON,
+ .enable_mask = BD73800_MASK_RUN_EN,
+ .vsel_reg = BD73800_REG_LDO3_VOLT,
+ .vsel_mask = BD73800_MASK_VOLT,
+ .owner = THIS_MODULE,
+ .of_parse_cb = buck_set_hw_dvs_levels,
+ },
+ .dvs = {
+ .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+ ROHM_DVS_LEVEL_SUSPEND,
+ .run_reg = BD73800_REG_LDO3_VOLT,
+ .run_mask = BD73800_MASK_VOLT,
+ .idle_on_mask = BD73800_MASK_IDLE_EN,
+ .suspend_on_mask = BD73800_MASK_SUSP_EN,
+ },
+ }, {
+ .desc = {
+ .name = "ldo4",
+ .of_match = of_match_ptr("ldo4"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = BD73800_LDO4,
+ .ops = &bd73800_ldo_ops,
+ .type = REGULATOR_VOLTAGE,
+ .linear_ranges = bd73800_ldo24_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd73800_ldo24_volts),
+ .n_voltages = BD73800_NUM_VOLTS,
+ .enable_reg = BD73800_REG_LDO4_ON,
+ .enable_mask = BD73800_MASK_RUN_EN,
+ .vsel_reg = BD73800_REG_LDO4_VOLT,
+ .vsel_mask = BD73800_MASK_VOLT,
+ .owner = THIS_MODULE,
+ .of_parse_cb = buck_set_hw_dvs_levels,
+ },
+ .dvs = {
+ .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+ ROHM_DVS_LEVEL_SUSPEND,
+ .run_reg = BD73800_REG_LDO4_VOLT,
+ .run_mask = BD73800_MASK_VOLT,
+ .idle_on_mask = BD73800_MASK_IDLE_EN,
+ .suspend_on_mask = BD73800_MASK_SUSP_EN,
+ },
+ },
+};
+
static int bd72720_buck10_ldon_head_mode(struct device *dev,
struct device_node *npreg,
struct regmap *regmap,
@@ -1620,6 +2111,50 @@ static int bd72720_dt_parse(struct device *dev,
return bd72720_buck10_ldon_head_mode(dev, nproot, regmap, buck10_desc);
}
+static int bd73800_check_ldo_otp_options(struct device *dev,
+ struct bd71828_regulator_data *d,
+ unsigned int num_reg_data)
+{
+ bool ldo1_use_high_range = false, ldo3_use_high_range = false;
+ struct device_node *nproot = dev->parent->of_node;
+ struct device_node *np;
+
+ /*
+ * The code assumes regulator IDs to start from 0 and to match the
+ * indexing of regulator data arrays. WARN if someone changes this.
+ */
+ WARN_ON(d[BD73800_LDO1].desc.id != BD73800_LDO1);
+ WARN_ON(d[BD73800_LDO3].desc.id != BD73800_LDO3);
+
+ nproot = of_get_child_by_name(nproot, "regulators");
+ if (!nproot) {
+ dev_err(dev, "failed to find regulators node\n");
+ return -ENODEV;
+ }
+ for_each_child_of_node(nproot, np) {
+ if (of_node_name_eq(np, LDO1_NODE_NAME))
+ ldo1_use_high_range = of_property_read_bool(np,
+ "rohm,ldo-range-high");
+ if (of_node_name_eq(np, LDO3_NODE_NAME))
+ ldo3_use_high_range = of_property_read_bool(np,
+ "rohm,ldo-range-high");
+ }
+ of_node_put(nproot);
+
+ if (ldo1_use_high_range) {
+ d[BD73800_LDO1].desc.linear_ranges = bd73800_ldo13_high_volts;
+ d[BD73800_LDO1].desc.n_linear_ranges =
+ ARRAY_SIZE(bd73800_ldo13_high_volts);
+ }
+ if (ldo3_use_high_range) {
+ d[BD73800_LDO3].desc.linear_ranges = bd73800_ldo13_high_volts;
+ d[BD73800_LDO3].desc.n_linear_ranges =
+ ARRAY_SIZE(bd73800_ldo13_high_volts);
+ }
+
+ return 0;
+}
+
static int bd71828_probe(struct platform_device *pdev)
{
int i, j, ret, num_regulators;
@@ -1657,6 +2192,23 @@ static int bd71828_probe(struct platform_device *pdev)
num_regulators = ARRAY_SIZE(bd71828_rdata);
break;
+
+ case ROHM_CHIP_TYPE_BD73800:
+ {
+ rdata = devm_kmemdup(&pdev->dev, bd73800_rdata, sizeof(bd73800_rdata),
+ GFP_KERNEL);
+ if (!rdata)
+ return -ENOMEM;
+
+ num_regulators = ARRAY_SIZE(bd73800_rdata);
+
+ ret = bd73800_check_ldo_otp_options(&pdev->dev, rdata,
+ num_regulators);
+ if (ret)
+ return ret;
+
+ break;
+ }
default:
return dev_err_probe(&pdev->dev, -EINVAL,
"Unsupported device\n");
@@ -1693,6 +2245,7 @@ static int bd71828_probe(struct platform_device *pdev)
static const struct platform_device_id bd71828_pmic_id[] = {
{ .name = "bd71828-pmic", .driver_data = ROHM_CHIP_TYPE_BD71828 },
{ .name = "bd72720-pmic", .driver_data = ROHM_CHIP_TYPE_BD72720 },
+ { .name = "bd73800-pmic", .driver_data = ROHM_CHIP_TYPE_BD73800 },
{ }
};
MODULE_DEVICE_TABLE(platform, bd71828_pmic_id);
--
2.54.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
next prev parent reply other threads:[~2026-07-01 12:43 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-01 12:40 [PATCH 0/8] " Matti Vaittinen
2026-07-01 12:41 ` [PATCH 1/8] dt-bindings: regulator: ROHM BD73800 regulators Matti Vaittinen
2026-07-01 15:39 ` Rob Herring (Arm)
2026-07-01 19:25 ` Rob Herring
2026-07-02 4:45 ` Matti Vaittinen
2026-07-01 12:41 ` [PATCH 2/8] dt-bindings: mfd: ROHM BD73800 PMIC Matti Vaittinen
2026-07-02 8:05 ` Krzysztof Kozlowski
2026-07-02 8:25 ` Matti Vaittinen
2026-07-03 20:46 ` Linus Walleij
2026-07-12 16:03 ` Matti Vaittinen
2026-07-01 12:41 ` [PATCH 3/8] mfd: Support for ROHM BD73800 PMIC core Matti Vaittinen
2026-07-09 10:48 ` Lee Jones
2026-07-12 17:54 ` Matti Vaittinen
2026-07-01 12:42 ` [PATCH 4/8] rtc: bd70528: Support RTC on ROHM BD73800 Matti Vaittinen
2026-07-01 12:55 ` Alexandre Belloni
2026-07-01 12:42 ` Matti Vaittinen [this message]
2026-07-01 13:01 ` [PATCH 5/8] regulator: bd71828: Support " Mark Brown
2026-07-02 4:55 ` Matti Vaittinen
2026-07-01 12:43 ` [PATCH 6/8] clk: bd718x7: " Matti Vaittinen
2026-07-01 12:43 ` [PATCH 7/8] gpio: bd73800: Support ROHM BD73800 PMIC GPIOs Matti Vaittinen
2026-07-03 13:11 ` Bartosz Golaszewski
2026-07-12 15:42 ` Matti Vaittinen
2026-07-13 8:16 ` Bartosz Golaszewski
2026-07-14 14:14 ` Matti Vaittinen
2026-07-01 12:43 ` [PATCH 8/8] MAINTAINERS: Add ROHM BD73800 PMIC files Matti Vaittinen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1d00359236272fd1fab0dfbcb9119d2f91aa0d23.1782909323.git.mazziesaccount@gmail.com \
--to=matti.vaittinen@linux.dev \
--cc=alexandre.belloni@bootlin.com \
--cc=bmasney@redhat.com \
--cc=brgl@kernel.org \
--cc=broonie@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=krzk+dt@kernel.org \
--cc=lee@kernel.org \
--cc=lgirdwood@gmail.com \
--cc=linusw@kernel.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rtc@vger.kernel.org \
--cc=matti.vaittinen@fi.rohmeurope.com \
--cc=mazziesaccount@gmail.com \
--cc=mturquette@baylibre.com \
--cc=robh@kernel.org \
--cc=sboyd@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox