mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 11:21:26 -04:00
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>
This commit is contained in:
@@ -81,6 +81,14 @@ properties:
|
||||
Specify the polling period, measured in milliseconds, between interrupt status
|
||||
update checks. Range 1000-10000 ms.
|
||||
|
||||
dlg,no-gpio-control:
|
||||
type: boolean
|
||||
description: |
|
||||
Available GPIO input pins of the regulator are strapped to fixed levels, therefore
|
||||
GPIO configurable input functions, DVC/RELOAD/EN, cannot dynamically update BUCK
|
||||
registers. GPIO pins connected as output pins are not required to be strapped to a
|
||||
fixed level. Not allowed together with enable-gpios.
|
||||
|
||||
regulators:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
@@ -134,6 +142,17 @@ allOf:
|
||||
properties:
|
||||
buck2: false
|
||||
|
||||
- if:
|
||||
required:
|
||||
- dlg,no-gpio-control
|
||||
then:
|
||||
properties:
|
||||
regulators:
|
||||
patternProperties:
|
||||
"^buck([1-2])$":
|
||||
properties:
|
||||
enable-gpios: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
@@ -168,6 +187,36 @@ examples:
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/regulator/dlg,da9121-regulator.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pmic@68 {
|
||||
compatible = "dlg,da9121";
|
||||
reg = <0x68>;
|
||||
|
||||
interrupt-parent = <&gpio6>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
dlg,irq-polling-delay-passive-ms = <2000>;
|
||||
dlg,no-gpio-control;
|
||||
|
||||
regulators {
|
||||
DA9121_BUCK: buck1 {
|
||||
regulator-name = "BUCK1";
|
||||
regulator-min-microvolt = <300000>;
|
||||
regulator-max-microvolt = <1900000>;
|
||||
regulator-min-microamp = <7000000>;
|
||||
regulator-max-microamp = <20000000>;
|
||||
regulator-boot-on;
|
||||
regulator-initial-mode = <DA9121_BUCK_MODE_AUTO>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user