From 69eb0980ab4ced06f7c2b4774575337ce32912fb Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Thu, 23 Apr 2015 16:10:24 +0530 Subject: [PATCH] regulator: max8973: add mechanism to enable/disable through GPIO MAX8973 supports the voltage output enable/disable through its EN pin. This EN pin can be connected through GPIO from host processor. Add support to provide GPIO number from platform/DT and if it is valid GPIO then enable external control default. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- .../bindings/regulator/max8973-regulator.txt | 2 ++ drivers/regulator/max8973-regulator.c | 29 +++++++++++++++---- include/linux/regulator/max8973-regulator.h | 4 +++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/max8973-regulator.txt b/Documentation/devicetree/bindings/regulator/max8973-regulator.txt index f63de7d8dc23..201a26337387 100644 --- a/Documentation/devicetree/bindings/regulator/max8973-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/max8973-regulator.txt @@ -12,6 +12,8 @@ Optional properties: -maxim,externally-enable: boolean, externally control the regulator output enable/disable. +-maxim,enable-gpio: GPIO for enable control. If the valid GPIO is provided + then externally enable control will be considered. -maxim,dvs-gpio: GPIO which is connected to DVS pin of device. -maxim,dvs-default-state: Default state of GPIO during initialisation. 1 for HIGH and 0 for LOW. diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c index 1442f920c80e..00cf91cc4c85 100644 --- a/drivers/regulator/max8973-regulator.c +++ b/drivers/regulator/max8973-regulator.c @@ -96,6 +96,7 @@ struct max8973_chip { struct regulator_desc desc; struct regmap *regmap; bool enable_external_control; + int enable_gpio; int dvs_gpio; int lru_index[MAX8973_MAX_VOUT_REG]; int curr_vout_val[MAX8973_MAX_VOUT_REG]; @@ -379,6 +380,7 @@ static struct max8973_regulator_platform_data *max8973_parse_dt( pdata->enable_ext_control = of_property_read_bool(np, "maxim,externally-enable"); + pdata->enable_gpio = of_get_named_gpio(np, "maxim,enable-gpio", 0); pdata->dvs_gpio = of_get_named_gpio(np, "maxim,dvs-gpio", 0); ret = of_property_read_u32(np, "maxim,dvs-default-state", &pval); @@ -409,6 +411,7 @@ static int max8973_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct max8973_regulator_platform_data *pdata; + struct regulator_init_data *ridata; struct regulator_config config = { }; struct regulator_dev *rdev; struct max8973_chip *max; @@ -427,7 +430,8 @@ static int max8973_probe(struct i2c_client *client, return -EIO; } - if (pdata->dvs_gpio == -EPROBE_DEFER) + if ((pdata->dvs_gpio == -EPROBE_DEFER) || + (pdata->enable_gpio == -EPROBE_DEFER)) return -EPROBE_DEFER; max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL); @@ -453,6 +457,15 @@ static int max8973_probe(struct i2c_client *client, max->desc.uV_step = MAX8973_VOLATGE_STEP; max->desc.n_voltages = MAX8973_BUCK_N_VOLTAGE; + max->dvs_gpio = (pdata->dvs_gpio) ? pdata->dvs_gpio : -EINVAL; + max->enable_gpio = (pdata->enable_gpio) ? pdata->enable_gpio : -EINVAL; + max->enable_external_control = pdata->enable_ext_control; + max->curr_gpio_val = pdata->dvs_def_state; + max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state; + + if (gpio_is_valid(max->enable_gpio)) + max->enable_external_control = true; + if (!pdata->enable_ext_control) { max->desc.enable_reg = MAX8973_VOUT; max->desc.enable_mask = MAX8973_VOUT_ENABLE; @@ -461,11 +474,6 @@ static int max8973_probe(struct i2c_client *client, max->ops.is_enabled = regulator_is_enabled_regmap; } - max->dvs_gpio = (pdata->dvs_gpio) ? pdata->dvs_gpio : -EINVAL; - max->enable_external_control = pdata->enable_ext_control; - max->curr_gpio_val = pdata->dvs_def_state; - max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state; - max->lru_index[0] = max->curr_vout_reg; if (gpio_is_valid(max->dvs_gpio)) { @@ -509,6 +517,15 @@ static int max8973_probe(struct i2c_client *client, config.of_node = client->dev.of_node; config.regmap = max->regmap; + if (gpio_is_valid(max->enable_gpio)) { + ridata = pdata->reg_init_data; + config.ena_gpio_flags = GPIOF_OUT_INIT_LOW; + if (ridata && (ridata->constraints.always_on || + ridata->constraints.boot_on)) + config.ena_gpio_flags = GPIOF_OUT_INIT_HIGH; + config.ena_gpio = max->enable_gpio; + } + /* Register the regulators */ rdev = devm_regulator_register(&client->dev, &max->desc, &config); if (IS_ERR(rdev)) { diff --git a/include/linux/regulator/max8973-regulator.h b/include/linux/regulator/max8973-regulator.h index f8acc052e353..f6a8a16a0d4d 100644 --- a/include/linux/regulator/max8973-regulator.h +++ b/include/linux/regulator/max8973-regulator.h @@ -58,6 +58,9 @@ * control signal from EN input pin. If it is false then * voltage output will be enabled/disabled through EN bit of * device register. + * @enable_gpio: Enable GPIO. If EN pin is controlled through GPIO from host + * then GPIO number can be provided. If no GPIO controlled then + * it should be -1. * @dvs_gpio: GPIO for dvs. It should be -1 if this is tied with fixed logic. * @dvs_def_state: Default state of dvs. 1 if it is high else 0. */ @@ -65,6 +68,7 @@ struct max8973_regulator_platform_data { struct regulator_init_data *reg_init_data; unsigned long control_flags; bool enable_ext_control; + int enable_gpio; int dvs_gpio; unsigned dvs_def_state:1; }; -- 2.39.2