Skip to content

Commit

Permalink
regulator: add support for the stm32-booster
Browse files Browse the repository at this point in the history
Add support for the 3.3V booster regulator embedded in stm32h7 and stm32mp1
devices, that can be used to supply ADC analog input switches.

This regulator is supplied by vdda. It's controlled by using SYSCFG:
- STM32H7 has a unique register to set/clear the booster enable bit
- STM32MP1 has separate set and clear registers to configure it.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Fabrice Gasnier authored and Mark Brown committed Jul 2, 2019
1 parent 025bf37 commit 4e210fb
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 0 deletions.
11 changes: 11 additions & 0 deletions drivers/regulator/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,17 @@ config REGULATOR_SLG51000
The SLG51000 is seven compact and customizable low dropout
regulators.

config REGULATOR_STM32_BOOSTER
tristate "STMicroelectronics STM32 BOOSTER"
depends on ARCH_STM32 || COMPILE_TEST
help
This driver supports internal booster (3V3) embedded in some
STMicroelectronics STM32 chips. It can be used to supply ADC analog
input switches when vdda supply is below 2.7V.

This driver can also be built as a module. If so, the module
will be called stm32-booster.

config REGULATOR_STM32_VREFBUF
tristate "STMicroelectronics STM32 VREFBUF"
depends on ARCH_STM32 || COMPILE_TEST
Expand Down
1 change: 1 addition & 0 deletions drivers/regulator/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o
obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
obj-$(CONFIG_REGULATOR_SLG51000) += slg51000-regulator.o
obj-$(CONFIG_REGULATOR_STM32_BOOSTER) += stm32-booster.o
obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o
obj-$(CONFIG_REGULATOR_STPMIC1) += stpmic1_regulator.o
Expand Down
132 changes: 132 additions & 0 deletions drivers/regulator/stm32-booster.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) STMicroelectronics 2019
// Author(s): Fabrice Gasnier <fabrice.gasnier@st.com>.

#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>

/* STM32H7 SYSCFG register */
#define STM32H7_SYSCFG_PMCR 0x04
#define STM32H7_SYSCFG_BOOSTE_MASK BIT(8)

/* STM32MP1 SYSCFG has set and clear registers */
#define STM32MP1_SYSCFG_PMCSETR 0x04
#define STM32MP1_SYSCFG_PMCCLRR 0x44
#define STM32MP1_SYSCFG_EN_BOOSTER_MASK BIT(8)

static const struct regulator_ops stm32h7_booster_ops = {
.list_voltage = regulator_list_voltage_linear,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};

static const struct regulator_desc stm32h7_booster_desc = {
.name = "booster",
.supply_name = "vdda",
.n_voltages = 1,
.type = REGULATOR_VOLTAGE,
.min_uV = 3300000,
.fixed_uV = 3300000,
.ramp_delay = 66000, /* up to 50us to stabilize */
.ops = &stm32h7_booster_ops,
.enable_reg = STM32H7_SYSCFG_PMCR,
.enable_mask = STM32H7_SYSCFG_BOOSTE_MASK,
.owner = THIS_MODULE,
};

static int stm32mp1_booster_enable(struct regulator_dev *rdev)
{
return regmap_write(rdev->regmap, STM32MP1_SYSCFG_PMCSETR,
STM32MP1_SYSCFG_EN_BOOSTER_MASK);
}

static int stm32mp1_booster_disable(struct regulator_dev *rdev)
{
return regmap_write(rdev->regmap, STM32MP1_SYSCFG_PMCCLRR,
STM32MP1_SYSCFG_EN_BOOSTER_MASK);
}

static const struct regulator_ops stm32mp1_booster_ops = {
.list_voltage = regulator_list_voltage_linear,
.enable = stm32mp1_booster_enable,
.disable = stm32mp1_booster_disable,
.is_enabled = regulator_is_enabled_regmap,
};

static const struct regulator_desc stm32mp1_booster_desc = {
.name = "booster",
.supply_name = "vdda",
.n_voltages = 1,
.type = REGULATOR_VOLTAGE,
.min_uV = 3300000,
.fixed_uV = 3300000,
.ramp_delay = 66000,
.ops = &stm32mp1_booster_ops,
.enable_reg = STM32MP1_SYSCFG_PMCSETR,
.enable_mask = STM32MP1_SYSCFG_EN_BOOSTER_MASK,
.owner = THIS_MODULE,
};

static int stm32_booster_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = pdev->dev.of_node;
struct regulator_config config = { };
const struct regulator_desc *desc;
struct regulator_dev *rdev;
struct regmap *regmap;
int ret;

regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
if (IS_ERR(regmap))
return PTR_ERR(regmap);

desc = (const struct regulator_desc *)
of_match_device(dev->driver->of_match_table, dev)->data;

config.regmap = regmap;
config.dev = dev;
config.of_node = np;
config.init_data = of_get_regulator_init_data(dev, np, desc);

rdev = devm_regulator_register(dev, desc, &config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(dev, "register failed with error %d\n", ret);
return ret;
}

return 0;
}

static const struct of_device_id stm32_booster_of_match[] = {
{
.compatible = "st,stm32h7-booster",
.data = (void *)&stm32h7_booster_desc
}, {
.compatible = "st,stm32mp1-booster",
.data = (void *)&stm32mp1_booster_desc
}, {
},
};
MODULE_DEVICE_TABLE(of, stm32_booster_of_match);

static struct platform_driver stm32_booster_driver = {
.probe = stm32_booster_probe,
.driver = {
.name = "stm32-booster",
.of_match_table = of_match_ptr(stm32_booster_of_match),
},
};
module_platform_driver(stm32_booster_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
MODULE_DESCRIPTION("STMicroelectronics STM32 booster regulator driver");
MODULE_ALIAS("platform:stm32-booster");

0 comments on commit 4e210fb

Please sign in to comment.