diff options
| author | Mark Brown <broonie@kernel.org> | 2026-03-24 22:37:47 +0300 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-03-24 22:37:47 +0300 |
| commit | 3dacdda5e643303a3e56ad303312dfcf72b6fafe (patch) | |
| tree | 18400e613d1502d7b3c11ad80537b6832aa796f9 /drivers | |
| parent | 57fca3a8ed8e8e42b456bef93055e8b73b1e358f (diff) | |
| parent | 6c2505e185b09e506542956f473631cc09afc403 (diff) | |
| download | linux-3dacdda5e643303a3e56ad303312dfcf72b6fafe.tar.xz | |
regulator: da91xx: Allow caching of buck registers when no GPIO input control is configured
André Svensson <andre.svensson@axis.com> says:
This series introduces a boolean DT property, dlg,no-gpio-control, for
the DA91xx regulators. Use this property to indicate that GPIO control
is not configured with the functions DVC/RELOAD/EN, allowing buck
registers to be cached.
The DA9121 driver checks dlg,no-gpio-control and updates regmap_config's
volatile_table if the property is present. Buck registers are removed
from the volatile_table if the property is present, enabling caching of
the registers, which removes I2C reads when performing an I2C write to
the buck registers.
Link: https://patch.msgid.link/20260320-no-gpio-control-v2-0-dbc938e462cb@axis.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/regulator/da9121-regulator.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c index ef161eb0ca27..2b150bb4d471 100644 --- a/drivers/regulator/da9121-regulator.c +++ b/drivers/regulator/da9121-regulator.c @@ -400,8 +400,14 @@ static int da9121_of_parse_cb(struct device_node *np, GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE, "da9121-enable"); - if (!IS_ERR(ena_gpiod)) + if (!IS_ERR(ena_gpiod)) { + if (of_property_read_bool(chip->dev->of_node, "dlg,no-gpio-control")) { + gpiod_put(ena_gpiod); + dev_err(chip->dev, "dlg,no-gpio-control conflicts with enable-gpios\n"); + return -EINVAL; + } config->ena_gpiod = ena_gpiod; + } if (variant_parameters[chip->variant_id].num_bucks == 2) { uint32_t ripple_cancel; @@ -864,6 +870,21 @@ static const struct regmap_access_table da9121_volatile_table = { .n_yes_ranges = ARRAY_SIZE(da9121_volatile_ranges), }; +/* + * When GPIO functions DVC/RELOAD/EN are not used, the registers in the range + * DA9121_REG_BUCK_BUCK1_0 to DA9121_REG_BUCK_BUCK1_6 need not be volatile + * because register writes to these registers can only be performed via I2C. + */ +static const struct regmap_range da9121_volatile_ranges_no_gpio_ctrl[] = { + regmap_reg_range(DA9121_REG_SYS_STATUS_0, DA9121_REG_SYS_EVENT_2), + regmap_reg_range(DA9121_REG_SYS_GPIO0_0, DA9121_REG_SYS_GPIO2_1), +}; + +static const struct regmap_access_table da9121_volatile_table_no_gpio_ctrl = { + .yes_ranges = da9121_volatile_ranges_no_gpio_ctrl, + .n_yes_ranges = ARRAY_SIZE(da9121_volatile_ranges_no_gpio_ctrl), +}; + /* DA9121 regmap config for 1 channel variants */ static const struct regmap_config da9121_1ch_regmap_config = { .reg_bits = 8, @@ -994,10 +1015,18 @@ static int da9121_assign_chip_model(struct i2c_client *i2c, struct da9121 *chip) { const struct regmap_config *regmap; + struct regmap_config regmap_config_1ch = da9121_1ch_regmap_config; + struct regmap_config regmap_config_2ch = da9121_2ch_regmap_config; + int ret = 0; chip->dev = &i2c->dev; + if (of_property_read_bool(i2c->dev.of_node, "dlg,no-gpio-control")) { + regmap_config_1ch.volatile_table = &da9121_volatile_table_no_gpio_ctrl; + regmap_config_2ch.volatile_table = &da9121_volatile_table_no_gpio_ctrl; + } + /* Use configured subtype to select the regulator descriptor index and * register map, common to both consumer and automotive grade variants */ @@ -1005,29 +1034,29 @@ static int da9121_assign_chip_model(struct i2c_client *i2c, case DA9121_SUBTYPE_DA9121: case DA9121_SUBTYPE_DA9130: chip->variant_id = DA9121_TYPE_DA9121_DA9130; - regmap = &da9121_1ch_regmap_config; + regmap = ®map_config_1ch; break; case DA9121_SUBTYPE_DA9217: chip->variant_id = DA9121_TYPE_DA9217; - regmap = &da9121_1ch_regmap_config; + regmap = ®map_config_1ch; break; case DA9121_SUBTYPE_DA9122: case DA9121_SUBTYPE_DA9131: chip->variant_id = DA9121_TYPE_DA9122_DA9131; - regmap = &da9121_2ch_regmap_config; + regmap = ®map_config_2ch; break; case DA9121_SUBTYPE_DA9220: case DA9121_SUBTYPE_DA9132: chip->variant_id = DA9121_TYPE_DA9220_DA9132; - regmap = &da9121_2ch_regmap_config; + regmap = ®map_config_2ch; break; case DA9121_SUBTYPE_DA9141: chip->variant_id = DA9121_TYPE_DA9141; - regmap = &da9121_1ch_regmap_config; + regmap = ®map_config_1ch; break; case DA9121_SUBTYPE_DA9142: chip->variant_id = DA9121_TYPE_DA9142; - regmap = &da9121_2ch_regmap_config; + regmap = ®map_config_2ch; break; default: return -EINVAL; |
