261 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * This file is part of STM32 DAC driver4 *5 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved6 * Author: Fabrice Gasnier <fabrice.gasnier@st.com>.7 *8 */9 10#include <linux/clk.h>11#include <linux/delay.h>12#include <linux/mod_devicetable.h>13#include <linux/module.h>14#include <linux/of_platform.h>15#include <linux/platform_device.h>16#include <linux/pm_runtime.h>17#include <linux/property.h>18#include <linux/regulator/consumer.h>19#include <linux/reset.h>20 21#include "stm32-dac-core.h"22 23/**24 * struct stm32_dac_priv - stm32 DAC core private data25 * @pclk: peripheral clock common for all DACs26 * @vref: regulator reference27 * @common: Common data for all DAC instances28 */29struct stm32_dac_priv {30 struct clk *pclk;31 struct regulator *vref;32 struct stm32_dac_common common;33};34 35/**36 * struct stm32_dac_cfg - DAC configuration37 * @has_hfsel: DAC has high frequency control38 */39struct stm32_dac_cfg {40 bool has_hfsel;41};42 43static struct stm32_dac_priv *to_stm32_dac_priv(struct stm32_dac_common *com)44{45 return container_of(com, struct stm32_dac_priv, common);46}47 48static const struct regmap_config stm32_dac_regmap_cfg = {49 .reg_bits = 32,50 .val_bits = 32,51 .reg_stride = sizeof(u32),52 .max_register = 0x3fc,53};54 55static int stm32_dac_core_hw_start(struct device *dev)56{57 struct stm32_dac_common *common = dev_get_drvdata(dev);58 struct stm32_dac_priv *priv = to_stm32_dac_priv(common);59 int ret;60 61 ret = regulator_enable(priv->vref);62 if (ret < 0) {63 dev_err(dev, "vref enable failed: %d\n", ret);64 return ret;65 }66 67 ret = clk_prepare_enable(priv->pclk);68 if (ret < 0) {69 dev_err(dev, "pclk enable failed: %d\n", ret);70 goto err_regulator_disable;71 }72 73 return 0;74 75err_regulator_disable:76 regulator_disable(priv->vref);77 78 return ret;79}80 81static void stm32_dac_core_hw_stop(struct device *dev)82{83 struct stm32_dac_common *common = dev_get_drvdata(dev);84 struct stm32_dac_priv *priv = to_stm32_dac_priv(common);85 86 clk_disable_unprepare(priv->pclk);87 regulator_disable(priv->vref);88}89 90static int stm32_dac_probe(struct platform_device *pdev)91{92 struct device *dev = &pdev->dev;93 const struct stm32_dac_cfg *cfg;94 struct stm32_dac_priv *priv;95 struct regmap *regmap;96 void __iomem *mmio;97 struct reset_control *rst;98 int ret;99 100 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);101 if (!priv)102 return -ENOMEM;103 platform_set_drvdata(pdev, &priv->common);104 105 cfg = device_get_match_data(dev);106 107 mmio = devm_platform_ioremap_resource(pdev, 0);108 if (IS_ERR(mmio))109 return PTR_ERR(mmio);110 111 regmap = devm_regmap_init_mmio_clk(dev, "pclk", mmio,112 &stm32_dac_regmap_cfg);113 if (IS_ERR(regmap))114 return PTR_ERR(regmap);115 priv->common.regmap = regmap;116 117 priv->pclk = devm_clk_get(dev, "pclk");118 if (IS_ERR(priv->pclk))119 return dev_err_probe(dev, PTR_ERR(priv->pclk), "pclk get failed\n");120 121 priv->vref = devm_regulator_get(dev, "vref");122 if (IS_ERR(priv->vref))123 return dev_err_probe(dev, PTR_ERR(priv->vref), "vref get failed\n");124 125 pm_runtime_get_noresume(dev);126 pm_runtime_set_active(dev);127 pm_runtime_enable(dev);128 129 ret = stm32_dac_core_hw_start(dev);130 if (ret)131 goto err_pm_stop;132 133 ret = regulator_get_voltage(priv->vref);134 if (ret < 0) {135 dev_err(dev, "vref get voltage failed, %d\n", ret);136 goto err_hw_stop;137 }138 priv->common.vref_mv = ret / 1000;139 dev_dbg(dev, "vref+=%dmV\n", priv->common.vref_mv);140 141 rst = devm_reset_control_get_optional_exclusive(dev, NULL);142 if (rst) {143 if (IS_ERR(rst)) {144 ret = dev_err_probe(dev, PTR_ERR(rst), "reset get failed\n");145 goto err_hw_stop;146 }147 148 reset_control_assert(rst);149 udelay(2);150 reset_control_deassert(rst);151 }152 153 if (cfg && cfg->has_hfsel) {154 /* When clock speed is higher than 80MHz, set HFSEL */155 priv->common.hfsel = (clk_get_rate(priv->pclk) > 80000000UL);156 ret = regmap_update_bits(regmap, STM32_DAC_CR,157 STM32H7_DAC_CR_HFSEL,158 priv->common.hfsel ?159 STM32H7_DAC_CR_HFSEL : 0);160 if (ret)161 goto err_hw_stop;162 }163 164 165 ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, dev);166 if (ret < 0) {167 dev_err(dev, "failed to populate DT children\n");168 goto err_hw_stop;169 }170 171 pm_runtime_put(dev);172 173 return 0;174 175err_hw_stop:176 stm32_dac_core_hw_stop(dev);177err_pm_stop:178 pm_runtime_disable(dev);179 pm_runtime_set_suspended(dev);180 pm_runtime_put_noidle(dev);181 182 return ret;183}184 185static void stm32_dac_remove(struct platform_device *pdev)186{187 pm_runtime_get_sync(&pdev->dev);188 of_platform_depopulate(&pdev->dev);189 stm32_dac_core_hw_stop(&pdev->dev);190 pm_runtime_disable(&pdev->dev);191 pm_runtime_set_suspended(&pdev->dev);192 pm_runtime_put_noidle(&pdev->dev);193}194 195static int stm32_dac_core_resume(struct device *dev)196{197 struct stm32_dac_common *common = dev_get_drvdata(dev);198 struct stm32_dac_priv *priv = to_stm32_dac_priv(common);199 int ret;200 201 if (priv->common.hfsel) {202 /* restore hfsel (maybe lost under low power state) */203 ret = regmap_set_bits(priv->common.regmap, STM32_DAC_CR,204 STM32H7_DAC_CR_HFSEL);205 if (ret)206 return ret;207 }208 209 return pm_runtime_force_resume(dev);210}211 212static int stm32_dac_core_runtime_suspend(struct device *dev)213{214 stm32_dac_core_hw_stop(dev);215 216 return 0;217}218 219static int stm32_dac_core_runtime_resume(struct device *dev)220{221 return stm32_dac_core_hw_start(dev);222}223 224static const struct dev_pm_ops stm32_dac_core_pm_ops = {225 SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, stm32_dac_core_resume)226 RUNTIME_PM_OPS(stm32_dac_core_runtime_suspend,227 stm32_dac_core_runtime_resume,228 NULL)229};230 231static const struct stm32_dac_cfg stm32h7_dac_cfg = {232 .has_hfsel = true,233};234 235static const struct of_device_id stm32_dac_of_match[] = {236 {237 .compatible = "st,stm32f4-dac-core",238 }, {239 .compatible = "st,stm32h7-dac-core",240 .data = (void *)&stm32h7_dac_cfg,241 },242 {},243};244MODULE_DEVICE_TABLE(of, stm32_dac_of_match);245 246static struct platform_driver stm32_dac_driver = {247 .probe = stm32_dac_probe,248 .remove_new = stm32_dac_remove,249 .driver = {250 .name = "stm32-dac-core",251 .of_match_table = stm32_dac_of_match,252 .pm = pm_ptr(&stm32_dac_core_pm_ops),253 },254};255module_platform_driver(stm32_dac_driver);256 257MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");258MODULE_DESCRIPTION("STMicroelectronics STM32 DAC core driver");259MODULE_LICENSE("GPL v2");260MODULE_ALIAS("platform:stm32-dac-core");261