Each regulator can be enabeld/disabled by the internal pmic state
machine or by a gpio input signal. Typically the OTP configures the
regulators to be enabled/disabled on a specific sequence number which is
most the time fine. Sometimes we need to reconfigure that due to a PCB
bug. This patch adds the support to disable/enable the regulator based
on a gpio input signal.

Signed-off-by: Marco Felsch <m.fel...@pengutronix.de>
---
 drivers/regulator/da9062-regulator.c | 84 +++++++++++++++++++++++++++-
 1 file changed, 82 insertions(+), 2 deletions(-)

diff --git a/drivers/regulator/da9062-regulator.c 
b/drivers/regulator/da9062-regulator.c
index 9d6eb7625948..1fd15c6c654f 100644
--- a/drivers/regulator/da9062-regulator.c
+++ b/drivers/regulator/da9062-regulator.c
@@ -53,6 +53,7 @@ struct da9062_regulator_info {
        struct reg_field suspend_sleep;
        unsigned int suspend_vsel_reg;
        struct reg_field vsel_gpi;
+       struct reg_field ena_gpi;
        /* Event detection bit */
        struct reg_field oc_event;
 };
@@ -69,6 +70,7 @@ struct da9062_regulator {
        struct regmap_field                     *sleep;
        struct regmap_field                     *suspend_sleep;
        struct regmap_field                     *vsel_gpi;
+       struct regmap_field                     *ena_gpi;
 };
 
 /* Encapsulates all information for the regulators driver */
@@ -398,7 +400,10 @@ static int da9062_config_gpi(struct device_node *np,
                goto free;
        }
 
-       ret = regmap_field_write(regl->vsel_gpi, nr);
+       if (!strncmp(gpi_id, "ena", 3))
+               ret = regmap_field_write(regl->ena_gpi, nr);
+       else
+               ret = regmap_field_write(regl->vsel_gpi, nr);
 
 free:
        kfree(prop);
@@ -411,7 +416,13 @@ static int da9062_parse_dt(struct device_node *np,
                           const struct regulator_desc *desc,
                           struct regulator_config *cfg)
 {
-       return da9062_config_gpi(np, desc, cfg, "vsel");
+       int error;
+
+       error = da9062_config_gpi(np, desc, cfg, "vsel");
+       if (error)
+               return error;
+
+       return da9062_config_gpi(np, desc, cfg, "ena");
 }
 
 /* DA9061 Regulator information */
@@ -456,6 +467,10 @@ static const struct da9062_regulator_info 
local_da9061_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VBUCK1_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VBUCK1_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_BUCK1_CONT,
+                       __builtin_ffs((int)DA9062AA_BUCK1_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_BUCK1_GPI_MASK) - 1),
        },
        {
                .desc.id = DA9061_ID_BUCK2,
@@ -497,6 +512,10 @@ static const struct da9062_regulator_info 
local_da9061_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VBUCK3_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VBUCK3_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_BUCK3_CONT,
+                       __builtin_ffs((int)DA9062AA_BUCK3_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_BUCK3_GPI_MASK) - 1),
        },
        {
                .desc.id = DA9061_ID_BUCK3,
@@ -538,6 +557,10 @@ static const struct da9062_regulator_info 
local_da9061_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VBUCK4_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VBUCK4_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_BUCK4_CONT,
+                       __builtin_ffs((int)DA9062AA_BUCK4_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_BUCK4_GPI_MASK) - 1),
        },
        {
                .desc.id = DA9061_ID_LDO1,
@@ -572,6 +595,10 @@ static const struct da9062_regulator_info 
local_da9061_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VLDO1_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VLDO1_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_LDO1_CONT,
+                       __builtin_ffs((int)DA9062AA_LDO1_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_LDO1_GPI_MASK) - 1),
                .oc_event = REG_FIELD(DA9062AA_STATUS_D,
                        __builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
                        sizeof(unsigned int) * 8 -
@@ -610,6 +637,10 @@ static const struct da9062_regulator_info 
local_da9061_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VLDO2_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VLDO2_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_LDO2_CONT,
+                       __builtin_ffs((int)DA9062AA_LDO2_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_LDO2_GPI_MASK) - 1),
                .oc_event = REG_FIELD(DA9062AA_STATUS_D,
                        __builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
                        sizeof(unsigned int) * 8 -
@@ -648,6 +679,10 @@ static const struct da9062_regulator_info 
local_da9061_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VLDO3_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VLDO3_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_LDO3_CONT,
+                       __builtin_ffs((int)DA9062AA_LDO3_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_LDO3_GPI_MASK) - 1),
                .oc_event = REG_FIELD(DA9062AA_STATUS_D,
                        __builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
                        sizeof(unsigned int) * 8 -
@@ -686,6 +721,10 @@ static const struct da9062_regulator_info 
local_da9061_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VLDO4_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VLDO4_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_LDO4_CONT,
+                       __builtin_ffs((int)DA9062AA_LDO4_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_LDO4_GPI_MASK) - 1),
                .oc_event = REG_FIELD(DA9062AA_STATUS_D,
                        __builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
                        sizeof(unsigned int) * 8 -
@@ -735,6 +774,10 @@ static const struct da9062_regulator_info 
local_da9062_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VBUCK1_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VBUCK1_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_BUCK1_CONT,
+                       __builtin_ffs((int)DA9062AA_BUCK1_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_BUCK1_GPI_MASK) - 1),
        },
        {
                .desc.id = DA9062_ID_BUCK2,
@@ -776,6 +819,10 @@ static const struct da9062_regulator_info 
local_da9062_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VBUCK2_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VBUCK2_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_BUCK2_CONT,
+                       __builtin_ffs((int)DA9062AA_BUCK2_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_BUCK2_GPI_MASK) - 1),
        },
        {
                .desc.id = DA9062_ID_BUCK3,
@@ -817,6 +864,10 @@ static const struct da9062_regulator_info 
local_da9062_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VBUCK3_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VBUCK3_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_BUCK3_CONT,
+                       __builtin_ffs((int)DA9062AA_BUCK3_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_BUCK3_GPI_MASK) - 1),
        },
        {
                .desc.id = DA9062_ID_BUCK4,
@@ -858,6 +909,10 @@ static const struct da9062_regulator_info 
local_da9062_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VBUCK4_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VBUCK4_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_BUCK4_CONT,
+                       __builtin_ffs((int)DA9062AA_BUCK4_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_BUCK4_GPI_MASK) - 1),
        },
        {
                .desc.id = DA9062_ID_LDO1,
@@ -892,6 +947,10 @@ static const struct da9062_regulator_info 
local_da9062_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VLDO1_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VLDO1_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_LDO1_CONT,
+                       __builtin_ffs((int)DA9062AA_LDO1_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_LDO1_GPI_MASK) - 1),
                .oc_event = REG_FIELD(DA9062AA_STATUS_D,
                        __builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
                        sizeof(unsigned int) * 8 -
@@ -930,6 +989,10 @@ static const struct da9062_regulator_info 
local_da9062_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VLDO2_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VLDO2_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_LDO2_CONT,
+                       __builtin_ffs((int)DA9062AA_LDO2_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_LDO2_GPI_MASK) - 1),
                .oc_event = REG_FIELD(DA9062AA_STATUS_D,
                        __builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
                        sizeof(unsigned int) * 8 -
@@ -968,6 +1031,10 @@ static const struct da9062_regulator_info 
local_da9062_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VLDO3_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VLDO3_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_LDO3_CONT,
+                       __builtin_ffs((int)DA9062AA_LDO3_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_LDO3_GPI_MASK) - 1),
                .oc_event = REG_FIELD(DA9062AA_STATUS_D,
                        __builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
                        sizeof(unsigned int) * 8 -
@@ -1006,6 +1073,10 @@ static const struct da9062_regulator_info 
local_da9062_regulator_info[] = {
                        __builtin_ffs((int)DA9062AA_VLDO4_GPI_MASK) - 1,
                        sizeof(unsigned int) * 8 -
                        __builtin_clz(DA9062AA_VLDO4_GPI_MASK) - 1),
+               .ena_gpi = REG_FIELD(DA9062AA_LDO4_CONT,
+                       __builtin_ffs((int)DA9062AA_LDO4_GPI_MASK) - 1,
+                       sizeof(unsigned int) * 8 -
+                       __builtin_clz(DA9062AA_LDO4_GPI_MASK) - 1),
                .oc_event = REG_FIELD(DA9062AA_STATUS_D,
                        __builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
                        sizeof(unsigned int) * 8 -
@@ -1135,6 +1206,15 @@ static int da9062_regulator_probe(struct platform_device 
*pdev)
                                return PTR_ERR(regl->vsel_gpi);
                }
 
+               if (regl->info->ena_gpi.reg) {
+                       regl->ena_gpi = devm_regmap_field_alloc(
+                                       &pdev->dev,
+                                       chip->regmap,
+                                       regl->info->ena_gpi);
+                       if (IS_ERR(regl->ena_gpi))
+                               return PTR_ERR(regl->ena_gpi);
+               }
+
                /* Register regulator */
                memset(&config, 0, sizeof(config));
                config.dev = chip->dev;
-- 
2.20.1

Reply via email to