1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * This file is part of STM32 DAC driver 4 * 5 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved 6 * Author: Fabrice Gasnier <fabrice.gasnier@st.com>. 7 * 8 */ 9 10 #include <linux/clk.h> 11 #include <linux/delay.h> 12 #include <linux/module.h> 13 #include <linux/of_platform.h> 14 #include <linux/regulator/consumer.h> 15 #include <linux/reset.h> 16 17 #include "stm32-dac-core.h" 18 19 /** 20 * struct stm32_dac_priv - stm32 DAC core private data 21 * @pclk: peripheral clock common for all DACs 22 * @rst: peripheral reset control 23 * @vref: regulator reference 24 * @common: Common data for all DAC instances 25 */ 26 struct stm32_dac_priv { 27 struct clk *pclk; 28 struct reset_control *rst; 29 struct regulator *vref; 30 struct stm32_dac_common common; 31 }; 32 33 /** 34 * struct stm32_dac_cfg - DAC configuration 35 * @has_hfsel: DAC has high frequency control 36 */ 37 struct stm32_dac_cfg { 38 bool has_hfsel; 39 }; 40 41 static struct stm32_dac_priv *to_stm32_dac_priv(struct stm32_dac_common *com) 42 { 43 return container_of(com, struct stm32_dac_priv, common); 44 } 45 46 static const struct regmap_config stm32_dac_regmap_cfg = { 47 .reg_bits = 32, 48 .val_bits = 32, 49 .reg_stride = sizeof(u32), 50 .max_register = 0x3fc, 51 }; 52 53 static int stm32_dac_probe(struct platform_device *pdev) 54 { 55 struct device *dev = &pdev->dev; 56 const struct stm32_dac_cfg *cfg; 57 struct stm32_dac_priv *priv; 58 struct regmap *regmap; 59 struct resource *res; 60 void __iomem *mmio; 61 int ret; 62 63 if (!dev->of_node) 64 return -ENODEV; 65 66 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 67 if (!priv) 68 return -ENOMEM; 69 cfg = (const struct stm32_dac_cfg *) 70 of_match_device(dev->driver->of_match_table, dev)->data; 71 72 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 73 mmio = devm_ioremap_resource(dev, res); 74 if (IS_ERR(mmio)) 75 return PTR_ERR(mmio); 76 77 regmap = devm_regmap_init_mmio(dev, mmio, &stm32_dac_regmap_cfg); 78 if (IS_ERR(regmap)) 79 return PTR_ERR(regmap); 80 priv->common.regmap = regmap; 81 82 priv->vref = devm_regulator_get(dev, "vref"); 83 if (IS_ERR(priv->vref)) { 84 ret = PTR_ERR(priv->vref); 85 dev_err(dev, "vref get failed, %d\n", ret); 86 return ret; 87 } 88 89 ret = regulator_enable(priv->vref); 90 if (ret < 0) { 91 dev_err(dev, "vref enable failed\n"); 92 return ret; 93 } 94 95 ret = regulator_get_voltage(priv->vref); 96 if (ret < 0) { 97 dev_err(dev, "vref get voltage failed, %d\n", ret); 98 goto err_vref; 99 } 100 priv->common.vref_mv = ret / 1000; 101 dev_dbg(dev, "vref+=%dmV\n", priv->common.vref_mv); 102 103 priv->pclk = devm_clk_get(dev, "pclk"); 104 if (IS_ERR(priv->pclk)) { 105 ret = PTR_ERR(priv->pclk); 106 dev_err(dev, "pclk get failed\n"); 107 goto err_vref; 108 } 109 110 ret = clk_prepare_enable(priv->pclk); 111 if (ret < 0) { 112 dev_err(dev, "pclk enable failed\n"); 113 goto err_vref; 114 } 115 116 priv->rst = devm_reset_control_get_exclusive(dev, NULL); 117 if (!IS_ERR(priv->rst)) { 118 reset_control_assert(priv->rst); 119 udelay(2); 120 reset_control_deassert(priv->rst); 121 } 122 123 if (cfg && cfg->has_hfsel) { 124 /* When clock speed is higher than 80MHz, set HFSEL */ 125 priv->common.hfsel = (clk_get_rate(priv->pclk) > 80000000UL); 126 ret = regmap_update_bits(regmap, STM32_DAC_CR, 127 STM32H7_DAC_CR_HFSEL, 128 priv->common.hfsel ? 129 STM32H7_DAC_CR_HFSEL : 0); 130 if (ret) 131 goto err_pclk; 132 } 133 134 platform_set_drvdata(pdev, &priv->common); 135 136 ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, dev); 137 if (ret < 0) { 138 dev_err(dev, "failed to populate DT children\n"); 139 goto err_pclk; 140 } 141 142 return 0; 143 144 err_pclk: 145 clk_disable_unprepare(priv->pclk); 146 err_vref: 147 regulator_disable(priv->vref); 148 149 return ret; 150 } 151 152 static int stm32_dac_remove(struct platform_device *pdev) 153 { 154 struct stm32_dac_common *common = platform_get_drvdata(pdev); 155 struct stm32_dac_priv *priv = to_stm32_dac_priv(common); 156 157 of_platform_depopulate(&pdev->dev); 158 clk_disable_unprepare(priv->pclk); 159 regulator_disable(priv->vref); 160 161 return 0; 162 } 163 164 static const struct stm32_dac_cfg stm32h7_dac_cfg = { 165 .has_hfsel = true, 166 }; 167 168 static const struct of_device_id stm32_dac_of_match[] = { 169 { 170 .compatible = "st,stm32f4-dac-core", 171 }, { 172 .compatible = "st,stm32h7-dac-core", 173 .data = (void *)&stm32h7_dac_cfg, 174 }, 175 {}, 176 }; 177 MODULE_DEVICE_TABLE(of, stm32_dac_of_match); 178 179 static struct platform_driver stm32_dac_driver = { 180 .probe = stm32_dac_probe, 181 .remove = stm32_dac_remove, 182 .driver = { 183 .name = "stm32-dac-core", 184 .of_match_table = stm32_dac_of_match, 185 }, 186 }; 187 module_platform_driver(stm32_dac_driver); 188 189 MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>"); 190 MODULE_DESCRIPTION("STMicroelectronics STM32 DAC core driver"); 191 MODULE_LICENSE("GPL v2"); 192 MODULE_ALIAS("platform:stm32-dac-core"); 193