Merge tag 'sound-5.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[sfrench/cifs-2.6.git] / drivers / regulator / stm32-booster.c
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");