1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (C) STMicroelectronics 2019 3 // Author(s): Fabrice Gasnier <fabrice.gasnier@st.com>. 4 5 #include <linux/mfd/syscon.h> 6 #include <linux/module.h> 7 #include <linux/of_device.h> 8 #include <linux/platform_device.h> 9 #include <linux/regmap.h> 10 #include <linux/regulator/driver.h> 11 #include <linux/regulator/of_regulator.h> 12 13 /* STM32H7 SYSCFG register */ 14 #define STM32H7_SYSCFG_PMCR 0x04 15 #define STM32H7_SYSCFG_BOOSTE_MASK BIT(8) 16 17 /* STM32MP1 SYSCFG has set and clear registers */ 18 #define STM32MP1_SYSCFG_PMCSETR 0x04 19 #define STM32MP1_SYSCFG_PMCCLRR 0x44 20 #define STM32MP1_SYSCFG_EN_BOOSTER_MASK BIT(8) 21 22 static const struct regulator_ops stm32h7_booster_ops = { 23 .list_voltage = regulator_list_voltage_linear, 24 .enable = regulator_enable_regmap, 25 .disable = regulator_disable_regmap, 26 .is_enabled = regulator_is_enabled_regmap, 27 }; 28 29 static const struct regulator_desc stm32h7_booster_desc = { 30 .name = "booster", 31 .supply_name = "vdda", 32 .n_voltages = 1, 33 .type = REGULATOR_VOLTAGE, 34 .min_uV = 3300000, 35 .fixed_uV = 3300000, 36 .ramp_delay = 66000, /* up to 50us to stabilize */ 37 .ops = &stm32h7_booster_ops, 38 .enable_reg = STM32H7_SYSCFG_PMCR, 39 .enable_mask = STM32H7_SYSCFG_BOOSTE_MASK, 40 .owner = THIS_MODULE, 41 }; 42 43 static int stm32mp1_booster_enable(struct regulator_dev *rdev) 44 { 45 return regmap_write(rdev->regmap, STM32MP1_SYSCFG_PMCSETR, 46 STM32MP1_SYSCFG_EN_BOOSTER_MASK); 47 } 48 49 static int stm32mp1_booster_disable(struct regulator_dev *rdev) 50 { 51 return regmap_write(rdev->regmap, STM32MP1_SYSCFG_PMCCLRR, 52 STM32MP1_SYSCFG_EN_BOOSTER_MASK); 53 } 54 55 static const struct regulator_ops stm32mp1_booster_ops = { 56 .list_voltage = regulator_list_voltage_linear, 57 .enable = stm32mp1_booster_enable, 58 .disable = stm32mp1_booster_disable, 59 .is_enabled = regulator_is_enabled_regmap, 60 }; 61 62 static const struct regulator_desc stm32mp1_booster_desc = { 63 .name = "booster", 64 .supply_name = "vdda", 65 .n_voltages = 1, 66 .type = REGULATOR_VOLTAGE, 67 .min_uV = 3300000, 68 .fixed_uV = 3300000, 69 .ramp_delay = 66000, 70 .ops = &stm32mp1_booster_ops, 71 .enable_reg = STM32MP1_SYSCFG_PMCSETR, 72 .enable_mask = STM32MP1_SYSCFG_EN_BOOSTER_MASK, 73 .owner = THIS_MODULE, 74 }; 75 76 static int stm32_booster_probe(struct platform_device *pdev) 77 { 78 struct device *dev = &pdev->dev; 79 struct device_node *np = pdev->dev.of_node; 80 struct regulator_config config = { }; 81 const struct regulator_desc *desc; 82 struct regulator_dev *rdev; 83 struct regmap *regmap; 84 int ret; 85 86 regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); 87 if (IS_ERR(regmap)) 88 return PTR_ERR(regmap); 89 90 desc = (const struct regulator_desc *) 91 of_match_device(dev->driver->of_match_table, dev)->data; 92 93 config.regmap = regmap; 94 config.dev = dev; 95 config.of_node = np; 96 config.init_data = of_get_regulator_init_data(dev, np, desc); 97 98 rdev = devm_regulator_register(dev, desc, &config); 99 if (IS_ERR(rdev)) { 100 ret = PTR_ERR(rdev); 101 dev_err(dev, "register failed with error %d\n", ret); 102 return ret; 103 } 104 105 return 0; 106 } 107 108 static const struct of_device_id stm32_booster_of_match[] = { 109 { 110 .compatible = "st,stm32h7-booster", 111 .data = (void *)&stm32h7_booster_desc 112 }, { 113 .compatible = "st,stm32mp1-booster", 114 .data = (void *)&stm32mp1_booster_desc 115 }, { 116 }, 117 }; 118 MODULE_DEVICE_TABLE(of, stm32_booster_of_match); 119 120 static struct platform_driver stm32_booster_driver = { 121 .probe = stm32_booster_probe, 122 .driver = { 123 .name = "stm32-booster", 124 .of_match_table = of_match_ptr(stm32_booster_of_match), 125 }, 126 }; 127 module_platform_driver(stm32_booster_driver); 128 129 MODULE_LICENSE("GPL v2"); 130 MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>"); 131 MODULE_DESCRIPTION("STMicroelectronics STM32 booster regulator driver"); 132 MODULE_ALIAS("platform:stm32-booster"); 133