summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/regulator/dlg,da9121.yaml49
-rw-r--r--drivers/regulator/da9121-regulator.c43
2 files changed, 85 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml b/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml
index 13b3f75f8e5e..ce76eb5b85bd 100644
--- a/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml
+++ b/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml
@@ -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:
@@ -169,6 +188,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>
#include <dt-bindings/regulator/dlg,da9121-regulator.h>
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 = &regmap_config_1ch;
break;
case DA9121_SUBTYPE_DA9217:
chip->variant_id = DA9121_TYPE_DA9217;
- regmap = &da9121_1ch_regmap_config;
+ regmap = &regmap_config_1ch;
break;
case DA9121_SUBTYPE_DA9122:
case DA9121_SUBTYPE_DA9131:
chip->variant_id = DA9121_TYPE_DA9122_DA9131;
- regmap = &da9121_2ch_regmap_config;
+ regmap = &regmap_config_2ch;
break;
case DA9121_SUBTYPE_DA9220:
case DA9121_SUBTYPE_DA9132:
chip->variant_id = DA9121_TYPE_DA9220_DA9132;
- regmap = &da9121_2ch_regmap_config;
+ regmap = &regmap_config_2ch;
break;
case DA9121_SUBTYPE_DA9141:
chip->variant_id = DA9121_TYPE_DA9141;
- regmap = &da9121_1ch_regmap_config;
+ regmap = &regmap_config_1ch;
break;
case DA9121_SUBTYPE_DA9142:
chip->variant_id = DA9121_TYPE_DA9142;
- regmap = &da9121_2ch_regmap_config;
+ regmap = &regmap_config_2ch;
break;
default:
return -EINVAL;