0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/bitfield.h>
0009 #include <linux/clk.h>
0010 #include <linux/io.h>
0011 #include <linux/iopoll.h>
0012 #include <linux/module.h>
0013 #include <linux/of_device.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/regulator/driver.h>
0016 #include <linux/regulator/of_regulator.h>
0017 #include <linux/pm_runtime.h>
0018
0019
0020 #define STM32_VREFBUF_CSR 0x00
0021
0022
0023 #define STM32_VRS GENMASK(6, 4)
0024 #define STM32_VRR BIT(3)
0025 #define STM32_HIZ BIT(1)
0026 #define STM32_ENVR BIT(0)
0027
0028 #define STM32_VREFBUF_AUTO_SUSPEND_DELAY_MS 10
0029
0030 struct stm32_vrefbuf {
0031 void __iomem *base;
0032 struct clk *clk;
0033 struct device *dev;
0034 };
0035
0036 static const unsigned int stm32_vrefbuf_voltages[] = {
0037
0038 2500000, 2048000, 1800000, 1500000,
0039 };
0040
0041 static int stm32_vrefbuf_enable(struct regulator_dev *rdev)
0042 {
0043 struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
0044 u32 val;
0045 int ret;
0046
0047 ret = pm_runtime_resume_and_get(priv->dev);
0048 if (ret < 0)
0049 return ret;
0050
0051 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
0052 val = (val & ~STM32_HIZ) | STM32_ENVR;
0053 writel_relaxed(val, priv->base + STM32_VREFBUF_CSR);
0054
0055
0056
0057
0058
0059
0060
0061 ret = readl_poll_timeout(priv->base + STM32_VREFBUF_CSR, val,
0062 val & STM32_VRR, 650, 10000);
0063 if (ret) {
0064 dev_err(&rdev->dev, "stm32 vrefbuf timed out!\n");
0065 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
0066 val = (val & ~STM32_ENVR) | STM32_HIZ;
0067 writel_relaxed(val, priv->base + STM32_VREFBUF_CSR);
0068 }
0069
0070 pm_runtime_mark_last_busy(priv->dev);
0071 pm_runtime_put_autosuspend(priv->dev);
0072
0073 return ret;
0074 }
0075
0076 static int stm32_vrefbuf_disable(struct regulator_dev *rdev)
0077 {
0078 struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
0079 u32 val;
0080 int ret;
0081
0082 ret = pm_runtime_resume_and_get(priv->dev);
0083 if (ret < 0)
0084 return ret;
0085
0086 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
0087 val &= ~STM32_ENVR;
0088 writel_relaxed(val, priv->base + STM32_VREFBUF_CSR);
0089
0090 pm_runtime_mark_last_busy(priv->dev);
0091 pm_runtime_put_autosuspend(priv->dev);
0092
0093 return 0;
0094 }
0095
0096 static int stm32_vrefbuf_is_enabled(struct regulator_dev *rdev)
0097 {
0098 struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
0099 int ret;
0100
0101 ret = pm_runtime_resume_and_get(priv->dev);
0102 if (ret < 0)
0103 return ret;
0104
0105 ret = readl_relaxed(priv->base + STM32_VREFBUF_CSR) & STM32_ENVR;
0106
0107 pm_runtime_mark_last_busy(priv->dev);
0108 pm_runtime_put_autosuspend(priv->dev);
0109
0110 return ret;
0111 }
0112
0113 static int stm32_vrefbuf_set_voltage_sel(struct regulator_dev *rdev,
0114 unsigned sel)
0115 {
0116 struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
0117 u32 val;
0118 int ret;
0119
0120 ret = pm_runtime_resume_and_get(priv->dev);
0121 if (ret < 0)
0122 return ret;
0123
0124 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
0125 val = (val & ~STM32_VRS) | FIELD_PREP(STM32_VRS, sel);
0126 writel_relaxed(val, priv->base + STM32_VREFBUF_CSR);
0127
0128 pm_runtime_mark_last_busy(priv->dev);
0129 pm_runtime_put_autosuspend(priv->dev);
0130
0131 return 0;
0132 }
0133
0134 static int stm32_vrefbuf_get_voltage_sel(struct regulator_dev *rdev)
0135 {
0136 struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
0137 u32 val;
0138 int ret;
0139
0140 ret = pm_runtime_resume_and_get(priv->dev);
0141 if (ret < 0)
0142 return ret;
0143
0144 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
0145 ret = FIELD_GET(STM32_VRS, val);
0146
0147 pm_runtime_mark_last_busy(priv->dev);
0148 pm_runtime_put_autosuspend(priv->dev);
0149
0150 return ret;
0151 }
0152
0153 static const struct regulator_ops stm32_vrefbuf_volt_ops = {
0154 .enable = stm32_vrefbuf_enable,
0155 .disable = stm32_vrefbuf_disable,
0156 .is_enabled = stm32_vrefbuf_is_enabled,
0157 .get_voltage_sel = stm32_vrefbuf_get_voltage_sel,
0158 .set_voltage_sel = stm32_vrefbuf_set_voltage_sel,
0159 .list_voltage = regulator_list_voltage_table,
0160 };
0161
0162 static const struct regulator_desc stm32_vrefbuf_regu = {
0163 .name = "vref",
0164 .supply_name = "vdda",
0165 .volt_table = stm32_vrefbuf_voltages,
0166 .n_voltages = ARRAY_SIZE(stm32_vrefbuf_voltages),
0167 .ops = &stm32_vrefbuf_volt_ops,
0168 .off_on_delay = 1000,
0169 .type = REGULATOR_VOLTAGE,
0170 .owner = THIS_MODULE,
0171 };
0172
0173 static int stm32_vrefbuf_probe(struct platform_device *pdev)
0174 {
0175 struct stm32_vrefbuf *priv;
0176 struct regulator_config config = { };
0177 struct regulator_dev *rdev;
0178 int ret;
0179
0180 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
0181 if (!priv)
0182 return -ENOMEM;
0183 priv->dev = &pdev->dev;
0184
0185 priv->base = devm_platform_ioremap_resource(pdev, 0);
0186 if (IS_ERR(priv->base))
0187 return PTR_ERR(priv->base);
0188
0189 priv->clk = devm_clk_get(&pdev->dev, NULL);
0190 if (IS_ERR(priv->clk))
0191 return PTR_ERR(priv->clk);
0192
0193 pm_runtime_get_noresume(&pdev->dev);
0194 pm_runtime_set_active(&pdev->dev);
0195 pm_runtime_set_autosuspend_delay(&pdev->dev,
0196 STM32_VREFBUF_AUTO_SUSPEND_DELAY_MS);
0197 pm_runtime_use_autosuspend(&pdev->dev);
0198 pm_runtime_enable(&pdev->dev);
0199
0200 ret = clk_prepare_enable(priv->clk);
0201 if (ret) {
0202 dev_err(&pdev->dev, "clk prepare failed with error %d\n", ret);
0203 goto err_pm_stop;
0204 }
0205
0206 config.dev = &pdev->dev;
0207 config.driver_data = priv;
0208 config.of_node = pdev->dev.of_node;
0209 config.init_data = of_get_regulator_init_data(&pdev->dev,
0210 pdev->dev.of_node,
0211 &stm32_vrefbuf_regu);
0212
0213 rdev = regulator_register(&stm32_vrefbuf_regu, &config);
0214 if (IS_ERR(rdev)) {
0215 ret = PTR_ERR(rdev);
0216 dev_err(&pdev->dev, "register failed with error %d\n", ret);
0217 goto err_clk_dis;
0218 }
0219 platform_set_drvdata(pdev, rdev);
0220
0221 pm_runtime_mark_last_busy(&pdev->dev);
0222 pm_runtime_put_autosuspend(&pdev->dev);
0223
0224 return 0;
0225
0226 err_clk_dis:
0227 clk_disable_unprepare(priv->clk);
0228 err_pm_stop:
0229 pm_runtime_disable(&pdev->dev);
0230 pm_runtime_set_suspended(&pdev->dev);
0231 pm_runtime_put_noidle(&pdev->dev);
0232
0233 return ret;
0234 }
0235
0236 static int stm32_vrefbuf_remove(struct platform_device *pdev)
0237 {
0238 struct regulator_dev *rdev = platform_get_drvdata(pdev);
0239 struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
0240
0241 pm_runtime_get_sync(&pdev->dev);
0242 regulator_unregister(rdev);
0243 clk_disable_unprepare(priv->clk);
0244 pm_runtime_disable(&pdev->dev);
0245 pm_runtime_set_suspended(&pdev->dev);
0246 pm_runtime_put_noidle(&pdev->dev);
0247
0248 return 0;
0249 };
0250
0251 static int __maybe_unused stm32_vrefbuf_runtime_suspend(struct device *dev)
0252 {
0253 struct regulator_dev *rdev = dev_get_drvdata(dev);
0254 struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
0255
0256 clk_disable_unprepare(priv->clk);
0257
0258 return 0;
0259 }
0260
0261 static int __maybe_unused stm32_vrefbuf_runtime_resume(struct device *dev)
0262 {
0263 struct regulator_dev *rdev = dev_get_drvdata(dev);
0264 struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
0265
0266 return clk_prepare_enable(priv->clk);
0267 }
0268
0269 static const struct dev_pm_ops stm32_vrefbuf_pm_ops = {
0270 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
0271 pm_runtime_force_resume)
0272 SET_RUNTIME_PM_OPS(stm32_vrefbuf_runtime_suspend,
0273 stm32_vrefbuf_runtime_resume,
0274 NULL)
0275 };
0276
0277 static const struct of_device_id __maybe_unused stm32_vrefbuf_of_match[] = {
0278 { .compatible = "st,stm32-vrefbuf", },
0279 {},
0280 };
0281 MODULE_DEVICE_TABLE(of, stm32_vrefbuf_of_match);
0282
0283 static struct platform_driver stm32_vrefbuf_driver = {
0284 .probe = stm32_vrefbuf_probe,
0285 .remove = stm32_vrefbuf_remove,
0286 .driver = {
0287 .name = "stm32-vrefbuf",
0288 .of_match_table = of_match_ptr(stm32_vrefbuf_of_match),
0289 .pm = &stm32_vrefbuf_pm_ops,
0290 },
0291 };
0292 module_platform_driver(stm32_vrefbuf_driver);
0293
0294 MODULE_LICENSE("GPL v2");
0295 MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
0296 MODULE_DESCRIPTION("STMicroelectronics STM32 VREFBUF driver");
0297 MODULE_ALIAS("platform:stm32-vrefbuf");