Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (C) STMicroelectronics 2019
0003 // Author(s): Fabrice Gasnier <fabrice.gasnier@st.com>.
0004 
0005 #include <linux/mfd/syscon.h>
0006 #include <linux/module.h>
0007 #include <linux/of_device.h>
0008 #include <linux/platform_device.h>
0009 #include <linux/regmap.h>
0010 #include <linux/regulator/driver.h>
0011 #include <linux/regulator/of_regulator.h>
0012 
0013 /* STM32H7 SYSCFG register */
0014 #define STM32H7_SYSCFG_PMCR     0x04
0015 #define STM32H7_SYSCFG_BOOSTE_MASK  BIT(8)
0016 
0017 /* STM32MP1 SYSCFG has set and clear registers */
0018 #define STM32MP1_SYSCFG_PMCSETR     0x04
0019 #define STM32MP1_SYSCFG_PMCCLRR     0x44
0020 #define STM32MP1_SYSCFG_EN_BOOSTER_MASK BIT(8)
0021 
0022 static const struct regulator_ops stm32h7_booster_ops = {
0023     .enable     = regulator_enable_regmap,
0024     .disable    = regulator_disable_regmap,
0025     .is_enabled = regulator_is_enabled_regmap,
0026 };
0027 
0028 static const struct regulator_desc stm32h7_booster_desc = {
0029     .name = "booster",
0030     .supply_name = "vdda",
0031     .n_voltages = 1,
0032     .type = REGULATOR_VOLTAGE,
0033     .fixed_uV = 3300000,
0034     .ramp_delay = 66000, /* up to 50us to stabilize */
0035     .ops = &stm32h7_booster_ops,
0036     .enable_reg = STM32H7_SYSCFG_PMCR,
0037     .enable_mask = STM32H7_SYSCFG_BOOSTE_MASK,
0038     .owner = THIS_MODULE,
0039 };
0040 
0041 static int stm32mp1_booster_enable(struct regulator_dev *rdev)
0042 {
0043     return regmap_write(rdev->regmap, STM32MP1_SYSCFG_PMCSETR,
0044                 STM32MP1_SYSCFG_EN_BOOSTER_MASK);
0045 }
0046 
0047 static int stm32mp1_booster_disable(struct regulator_dev *rdev)
0048 {
0049     return regmap_write(rdev->regmap, STM32MP1_SYSCFG_PMCCLRR,
0050                 STM32MP1_SYSCFG_EN_BOOSTER_MASK);
0051 }
0052 
0053 static const struct regulator_ops stm32mp1_booster_ops = {
0054     .enable     = stm32mp1_booster_enable,
0055     .disable    = stm32mp1_booster_disable,
0056     .is_enabled = regulator_is_enabled_regmap,
0057 };
0058 
0059 static const struct regulator_desc stm32mp1_booster_desc = {
0060     .name = "booster",
0061     .supply_name = "vdda",
0062     .n_voltages = 1,
0063     .type = REGULATOR_VOLTAGE,
0064     .fixed_uV = 3300000,
0065     .ramp_delay = 66000,
0066     .ops = &stm32mp1_booster_ops,
0067     .enable_reg = STM32MP1_SYSCFG_PMCSETR,
0068     .enable_mask = STM32MP1_SYSCFG_EN_BOOSTER_MASK,
0069     .owner = THIS_MODULE,
0070 };
0071 
0072 static int stm32_booster_probe(struct platform_device *pdev)
0073 {
0074     struct device *dev = &pdev->dev;
0075     struct device_node *np = pdev->dev.of_node;
0076     struct regulator_config config = { };
0077     const struct regulator_desc *desc;
0078     struct regulator_dev *rdev;
0079     struct regmap *regmap;
0080     int ret;
0081 
0082     regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
0083     if (IS_ERR(regmap))
0084         return PTR_ERR(regmap);
0085 
0086     desc = (const struct regulator_desc *)
0087         of_match_device(dev->driver->of_match_table, dev)->data;
0088 
0089     config.regmap = regmap;
0090     config.dev = dev;
0091     config.of_node = np;
0092     config.init_data = of_get_regulator_init_data(dev, np, desc);
0093 
0094     rdev = devm_regulator_register(dev, desc, &config);
0095     if (IS_ERR(rdev)) {
0096         ret = PTR_ERR(rdev);
0097         dev_err(dev, "register failed with error %d\n", ret);
0098         return ret;
0099     }
0100 
0101     return 0;
0102 }
0103 
0104 static const struct of_device_id __maybe_unused stm32_booster_of_match[] = {
0105     {
0106         .compatible = "st,stm32h7-booster",
0107         .data = (void *)&stm32h7_booster_desc
0108     }, {
0109         .compatible = "st,stm32mp1-booster",
0110         .data = (void *)&stm32mp1_booster_desc
0111     }, {
0112     },
0113 };
0114 MODULE_DEVICE_TABLE(of, stm32_booster_of_match);
0115 
0116 static struct platform_driver stm32_booster_driver = {
0117     .probe = stm32_booster_probe,
0118     .driver = {
0119         .name  = "stm32-booster",
0120         .of_match_table = of_match_ptr(stm32_booster_of_match),
0121     },
0122 };
0123 module_platform_driver(stm32_booster_driver);
0124 
0125 MODULE_LICENSE("GPL v2");
0126 MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
0127 MODULE_DESCRIPTION("STMicroelectronics STM32 booster regulator driver");
0128 MODULE_ALIAS("platform:stm32-booster");