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>,
Stephen Boyd <sboyd@kernel.org>,
Brian Masney <bmasney+clk@redhat.com>,
Jerome Brunet <jbrunet+clk@baylibre.com>,
Linus Walleij <linusw@kernel.org>,
Bartosz Golaszewski <brgl@kernel.org>,
Alexandre Belloni <alexandre.belloni@bootlin.com>,
Michael Walle <mwalle@kernel.org>,
mfd@lists.linux.dev, 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 v3 07/10] regulator: bd71828: Support ROHM BD73800
Date: Wed, 2 Sep 2026 14:05:36 +0300 [thread overview]
Message-ID: <ce7152cd65276d2e855f7b605918f2f74f69c324.1788346553.git.mazziesaccount@gmail.com> (raw)
In-Reply-To: <cover.1788346553.git.mazziesaccount@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 23969 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>
Acked-by: Mark Brown <broonie@kernel.org>
---
Revision history:
v3:
- No changes
v1 => v2:
- Simplified DT parsing as was suggested by Mark
- Fix buck5 vsel_mask
---
drivers/regulator/Kconfig | 4 +-
drivers/regulator/bd71828-regulator.c | 558 +++++++++++++++++++++++++-
2 files changed, 559 insertions(+), 3 deletions(-)
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 89789ac7a786..13928af8cad4 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 2ced81df0c02..dea551cf658a 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/of.h>
#include <linux/platform_device.h>
@@ -31,6 +31,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.
@@ -172,6 +179,55 @@ 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),
+};
+
+/*
+ * BUCK5 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 };
/*
@@ -225,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,
@@ -1565,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_BUCK5_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,
@@ -1619,6 +2111,52 @@ static int bd72720_dt_parse(struct device *dev,
return bd72720_buck10_ldon_head_mode(dev, nproot, regmap, buck10_desc);
}
+static bool bd73800_use_ldo_high_range(struct device_node *nproot,
+ const char *ldo_node)
+{
+ struct device_node *np __free(device_node) =
+ of_get_child_by_name(nproot, ldo_node);
+
+ if (!np)
+ return false;
+
+ return of_property_read_bool(np, "rohm,ldo-range-high");
+}
+
+static int bd73800_check_ldo_otp_options(struct device *dev,
+ struct bd71828_regulator_data *d,
+ unsigned int num_reg_data)
+{
+ struct device_node *nproot __free(device_node) =
+ of_get_child_by_name(dev->parent->of_node, "regulators");
+
+ /*
+ * 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);
+
+ if (!nproot) {
+ dev_err(dev, "failed to find regulators node\n");
+ return -ENODEV;
+ }
+
+ if (bd73800_use_ldo_high_range(nproot, LDO1_NODE_NAME)) {
+ d[BD73800_LDO1].desc.linear_ranges = bd73800_ldo13_high_volts;
+ d[BD73800_LDO1].desc.n_linear_ranges =
+ ARRAY_SIZE(bd73800_ldo13_high_volts);
+ }
+
+ if (bd73800_use_ldo_high_range(nproot, LDO3_NODE_NAME)) {
+ 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;
@@ -1656,6 +2194,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");
@@ -1692,6 +2247,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.55.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
next prev parent reply other threads:[~2026-09-02 11:05 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 11:03 [PATCH v3 00/10] Support ROHM BD73800 Matti Vaittinen
2026-09-02 11:03 ` [PATCH v3 01/10] dt-bindings: mfd: common ROHM PMIC properties Matti Vaittinen
2026-09-02 11:04 ` [PATCH v3 02/10] dt-bindings: rohm,bd*: Ref common ROHM bindings Matti Vaittinen
2026-09-02 11:04 ` [PATCH v3 03/10] dt-bindings: regulator: ROHM BD73800 regulators Matti Vaittinen
2026-09-02 11:04 ` [PATCH v3 04/10] dt-bindings: mfd: ROHM BD73800 PMIC Matti Vaittinen
2026-09-02 11:04 ` [PATCH v3 05/10] mfd: Support for ROHM BD73800 PMIC core Matti Vaittinen
2026-09-02 13:24 ` Bartosz Golaszewski
2026-09-02 11:05 ` [PATCH v3 06/10] rtc: bd70528: Support RTC on ROHM BD73800 Matti Vaittinen
2026-09-02 11:05 ` Matti Vaittinen [this message]
2026-09-02 11:05 ` [PATCH v3 08/10] clk: bd718x7: Support " Matti Vaittinen
2026-09-04 8:24 ` Jerome Brunet
2026-09-02 11:07 ` [PATCH v3 09/10] gpio: bd73800: Support ROHM BD73800 PMIC GPIOs Matti Vaittinen
2026-09-02 12:39 ` Linus Walleij
2026-09-03 5:02 ` Matti Vaittinen
2026-09-02 12:58 ` Bartosz Golaszewski
2026-09-03 5:00 ` Matti Vaittinen
2026-09-03 7:53 ` Bartosz Golaszewski
2026-09-02 11:07 ` [PATCH v3 10/10] 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=ce7152cd65276d2e855f7b605918f2f74f69c324.1788346553.git.mazziesaccount@gmail.com \
--to=matti.vaittinen@linux.dev \
--cc=alexandre.belloni@bootlin.com \
--cc=bmasney+clk@redhat.com \
--cc=brgl@kernel.org \
--cc=broonie@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=jbrunet+clk@baylibre.com \
--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=mfd@lists.linux.dev \
--cc=mwalle@kernel.org \
--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