From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marco Felsch Subject: [PATCH 5/5] regulator: da9062: add gpio based regulator dis-/enable support Date: Tue, 17 Sep 2019 14:42:46 +0200 Message-ID: <20190917124246.11732-6-m.felsch@pengutronix.de> References: <20190917124246.11732-1-m.felsch@pengutronix.de> Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Return-path: In-Reply-To: <20190917124246.11732-1-m.felsch@pengutronix.de> Sender: linux-kernel-owner@vger.kernel.org To: support.opensource@diasemi.com, lee.jones@linaro.org, robh+dt@kernel.org, lgirdwood@gmail.com, broonie@kernel.org, stwiss.opensource@diasemi.com Cc: kernel@pengutronix.de, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org List-Id: devicetree@vger.kernel.org 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 --- 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