1 /* 2 * This file is part of STM32 DAC driver 3 * 4 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved 5 * Author: Fabrice Gasnier <fabrice.gasnier@st.com>. 6 * 7 * License type: GPLv2 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License version 2 as published by 11 * the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 * or FITNESS FOR A PARTICULAR PURPOSE. 16 * See the GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along with 19 * this program. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #include <linux/clk.h> 23 #include <linux/delay.h> 24 #include <linux/module.h> 25 #include <linux/of_platform.h> 26 #include <linux/regulator/consumer.h> 27 #include <linux/reset.h> 28 29 #include "stm32-dac-core.h" 30 31 /** 32 * struct stm32_dac_priv - stm32 DAC core private data 33 * @pclk: peripheral clock common for all DACs 34 * @rst: peripheral reset control 35 * @vref: regulator reference 36 * @common: Common data for all DAC instances 37 */ 38 struct stm32_dac_priv { 39 struct clk *pclk; 40 struct reset_control *rst; 41 struct regulator *vref; 42 struct stm32_dac_common common; 43 }; 44 45 static struct stm32_dac_priv *to_stm32_dac_priv(struct stm32_dac_common *com) 46 { 47 return container_of(com, struct stm32_dac_priv, common); 48 } 49 50 static const struct regmap_config stm32_dac_regmap_cfg = { 51 .reg_bits = 32, 52 .val_bits = 32, 53 .reg_stride = sizeof(u32), 54 .max_register = 0x3fc, 55 }; 56 57 static int stm32_dac_probe(struct platform_device *pdev) 58 { 59 struct device *dev = &pdev->dev; 60 struct stm32_dac_priv *priv; 61 struct regmap *regmap; 62 struct resource *res; 63 void __iomem *mmio; 64 int ret; 65 66 if (!dev->of_node) 67 return -ENODEV; 68 69 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 70 if (!priv) 71 return -ENOMEM; 72 73 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 74 mmio = devm_ioremap_resource(dev, res); 75 if (IS_ERR(mmio)) 76 return PTR_ERR(mmio); 77 78 regmap = devm_regmap_init_mmio(dev, mmio, &stm32_dac_regmap_cfg); 79 if (IS_ERR(regmap)) 80 return PTR_ERR(regmap); 81 priv->common.regmap = regmap; 82 83 priv->vref = devm_regulator_get(dev, "vref"); 84 if (IS_ERR(priv->vref)) { 85 ret = PTR_ERR(priv->vref); 86 dev_err(dev, "vref get failed, %d\n", ret); 87 return ret; 88 } 89 90 ret = regulator_enable(priv->vref); 91 if (ret < 0) { 92 dev_err(dev, "vref enable failed\n"); 93 return ret; 94 } 95 96 ret = regulator_get_voltage(priv->vref); 97 if (ret < 0) { 98 dev_err(dev, "vref get voltage failed, %d\n", ret); 99 goto err_vref; 100 } 101 priv->common.vref_mv = ret / 1000; 102 dev_dbg(dev, "vref+=%dmV\n", priv->common.vref_mv); 103 104 priv->pclk = devm_clk_get(dev, "pclk"); 105 if (IS_ERR(priv->pclk)) { 106 ret = PTR_ERR(priv->pclk); 107 dev_err(dev, "pclk get failed\n"); 108 goto err_vref; 109 } 110 111 ret = clk_prepare_enable(priv->pclk); 112 if (ret < 0) { 113 dev_err(dev, "pclk enable failed\n"); 114 goto err_vref; 115 } 116 117 priv->rst = devm_reset_control_get(dev, NULL); 118 if (!IS_ERR(priv->rst)) { 119 reset_control_assert(priv->rst); 120 udelay(2); 121 reset_control_deassert(priv->rst); 122 } 123 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, STM32H7_DAC_CR_HFSEL, 127 priv->common.hfsel ? STM32H7_DAC_CR_HFSEL : 0); 128 if (ret) 129 goto err_pclk; 130 131 platform_set_drvdata(pdev, &priv->common); 132 133 ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, dev); 134 if (ret < 0) { 135 dev_err(dev, "failed to populate DT children\n"); 136 goto err_pclk; 137 } 138 139 return 0; 140 141 err_pclk: 142 clk_disable_unprepare(priv->pclk); 143 err_vref: 144 regulator_disable(priv->vref); 145 146 return ret; 147 } 148 149 static int stm32_dac_remove(struct platform_device *pdev) 150 { 151 struct stm32_dac_common *common = platform_get_drvdata(pdev); 152 struct stm32_dac_priv *priv = to_stm32_dac_priv(common); 153 154 of_platform_depopulate(&pdev->dev); 155 clk_disable_unprepare(priv->pclk); 156 regulator_disable(priv->vref); 157 158 return 0; 159 } 160 161 static const struct of_device_id stm32_dac_of_match[] = { 162 { .compatible = "st,stm32h7-dac-core", }, 163 {}, 164 }; 165 MODULE_DEVICE_TABLE(of, stm32_dac_of_match); 166 167 static struct platform_driver stm32_dac_driver = { 168 .probe = stm32_dac_probe, 169 .remove = stm32_dac_remove, 170 .driver = { 171 .name = "stm32-dac-core", 172 .of_match_table = stm32_dac_of_match, 173 }, 174 }; 175 module_platform_driver(stm32_dac_driver); 176 177 MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>"); 178 MODULE_DESCRIPTION("STMicroelectronics STM32 DAC core driver"); 179 MODULE_LICENSE("GPL v2"); 180 MODULE_ALIAS("platform:stm32-dac-core"); 181