186 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (C) STMicroelectronics 20193// Authors: Gabriel Fernandez <gabriel.fernandez@st.com>4// Pascal Paillet <p.paillet@st.com>.5 6#include <linux/io.h>7#include <linux/iopoll.h>8#include <linux/module.h>9#include <linux/of.h>10#include <linux/platform_device.h>11#include <linux/regulator/driver.h>12#include <linux/regulator/of_regulator.h>13 14/*15 * Registers description16 */17#define REG_PWR_CR3 0x0C18 19#define USB_3_3_EN BIT(24)20#define USB_3_3_RDY BIT(26)21#define REG_1_8_EN BIT(28)22#define REG_1_8_RDY BIT(29)23#define REG_1_1_EN BIT(30)24#define REG_1_1_RDY BIT(31)25 26/* list of supported regulators */27enum {28 PWR_REG11,29 PWR_REG18,30 PWR_USB33,31 STM32PWR_REG_NUM_REGS32};33 34static u32 ready_mask_table[STM32PWR_REG_NUM_REGS] = {35 [PWR_REG11] = REG_1_1_RDY,36 [PWR_REG18] = REG_1_8_RDY,37 [PWR_USB33] = USB_3_3_RDY,38};39 40struct stm32_pwr_reg {41 void __iomem *base;42 u32 ready_mask;43};44 45static int stm32_pwr_reg_is_ready(struct regulator_dev *rdev)46{47 struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev);48 u32 val;49 50 val = readl_relaxed(priv->base + REG_PWR_CR3);51 52 return (val & priv->ready_mask);53}54 55static int stm32_pwr_reg_is_enabled(struct regulator_dev *rdev)56{57 struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev);58 u32 val;59 60 val = readl_relaxed(priv->base + REG_PWR_CR3);61 62 return (val & rdev->desc->enable_mask);63}64 65static int stm32_pwr_reg_enable(struct regulator_dev *rdev)66{67 struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev);68 int ret;69 u32 val;70 71 val = readl_relaxed(priv->base + REG_PWR_CR3);72 val |= rdev->desc->enable_mask;73 writel_relaxed(val, priv->base + REG_PWR_CR3);74 75 /* use an arbitrary timeout of 20ms */76 ret = readx_poll_timeout(stm32_pwr_reg_is_ready, rdev, val, val,77 100, 20 * 1000);78 if (ret)79 dev_err(&rdev->dev, "regulator enable timed out!\n");80 81 return ret;82}83 84static int stm32_pwr_reg_disable(struct regulator_dev *rdev)85{86 struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev);87 int ret;88 u32 val;89 90 val = readl_relaxed(priv->base + REG_PWR_CR3);91 val &= ~rdev->desc->enable_mask;92 writel_relaxed(val, priv->base + REG_PWR_CR3);93 94 /* use an arbitrary timeout of 20ms */95 ret = readx_poll_timeout(stm32_pwr_reg_is_enabled, rdev, val, !val,96 100, 20 * 1000);97 if (ret)98 dev_err(&rdev->dev, "regulator disable timed out!\n");99 100 return ret;101}102 103static const struct regulator_ops stm32_pwr_reg_ops = {104 .enable = stm32_pwr_reg_enable,105 .disable = stm32_pwr_reg_disable,106 .is_enabled = stm32_pwr_reg_is_enabled,107};108 109#define PWR_REG(_id, _name, _volt, _en, _supply) \110 [_id] = { \111 .id = _id, \112 .name = _name, \113 .of_match = of_match_ptr(_name), \114 .n_voltages = 1, \115 .type = REGULATOR_VOLTAGE, \116 .fixed_uV = _volt, \117 .ops = &stm32_pwr_reg_ops, \118 .enable_mask = _en, \119 .owner = THIS_MODULE, \120 .supply_name = _supply, \121 } \122 123static const struct regulator_desc stm32_pwr_desc[] = {124 PWR_REG(PWR_REG11, "reg11", 1100000, REG_1_1_EN, "vdd"),125 PWR_REG(PWR_REG18, "reg18", 1800000, REG_1_8_EN, "vdd"),126 PWR_REG(PWR_USB33, "usb33", 3300000, USB_3_3_EN, "vdd_3v3_usbfs"),127};128 129static int stm32_pwr_regulator_probe(struct platform_device *pdev)130{131 struct stm32_pwr_reg *priv;132 void __iomem *base;133 struct regulator_dev *rdev;134 struct regulator_config config = { };135 int i, ret = 0;136 137 base = devm_platform_ioremap_resource(pdev, 0);138 if (IS_ERR(base)) {139 dev_err(&pdev->dev, "Unable to map IO memory\n");140 return PTR_ERR(base);141 }142 143 config.dev = &pdev->dev;144 145 for (i = 0; i < STM32PWR_REG_NUM_REGS; i++) {146 priv = devm_kzalloc(&pdev->dev, sizeof(struct stm32_pwr_reg),147 GFP_KERNEL);148 if (!priv)149 return -ENOMEM;150 priv->base = base;151 priv->ready_mask = ready_mask_table[i];152 config.driver_data = priv;153 154 rdev = devm_regulator_register(&pdev->dev,155 &stm32_pwr_desc[i],156 &config);157 if (IS_ERR(rdev)) {158 ret = PTR_ERR(rdev);159 dev_err(&pdev->dev,160 "Failed to register regulator: %d\n", ret);161 break;162 }163 }164 return ret;165}166 167static const struct of_device_id __maybe_unused stm32_pwr_of_match[] = {168 { .compatible = "st,stm32mp1,pwr-reg", },169 { .compatible = "st,stm32mp13-pwr-reg", },170 {},171};172MODULE_DEVICE_TABLE(of, stm32_pwr_of_match);173 174static struct platform_driver stm32_pwr_driver = {175 .probe = stm32_pwr_regulator_probe,176 .driver = {177 .name = "stm32-pwr-regulator",178 .probe_type = PROBE_PREFER_ASYNCHRONOUS,179 .of_match_table = of_match_ptr(stm32_pwr_of_match),180 },181};182module_platform_driver(stm32_pwr_driver);183 184MODULE_DESCRIPTION("STM32MP1 PWR voltage regulator driver");185MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");186