2 * This file is part of STM32 DAC driver
4 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
5 * Author: Fabrice Gasnier <fabrice.gasnier@st.com>.
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.
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.
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/>.
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>
29 #include "stm32-dac-core.h"
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
38 struct stm32_dac_priv
{
40 struct reset_control
*rst
;
41 struct regulator
*vref
;
42 struct stm32_dac_common common
;
46 * struct stm32_dac_cfg - DAC configuration
47 * @has_hfsel: DAC has high frequency control
49 struct stm32_dac_cfg
{
53 static struct stm32_dac_priv
*to_stm32_dac_priv(struct stm32_dac_common
*com
)
55 return container_of(com
, struct stm32_dac_priv
, common
);
58 static const struct regmap_config stm32_dac_regmap_cfg
= {
61 .reg_stride
= sizeof(u32
),
62 .max_register
= 0x3fc,
65 static int stm32_dac_probe(struct platform_device
*pdev
)
67 struct device
*dev
= &pdev
->dev
;
68 const struct stm32_dac_cfg
*cfg
;
69 struct stm32_dac_priv
*priv
;
70 struct regmap
*regmap
;
78 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
81 cfg
= (const struct stm32_dac_cfg
*)
82 of_match_device(dev
->driver
->of_match_table
, dev
)->data
;
84 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
85 mmio
= devm_ioremap_resource(dev
, res
);
89 regmap
= devm_regmap_init_mmio(dev
, mmio
, &stm32_dac_regmap_cfg
);
91 return PTR_ERR(regmap
);
92 priv
->common
.regmap
= regmap
;
94 priv
->vref
= devm_regulator_get(dev
, "vref");
95 if (IS_ERR(priv
->vref
)) {
96 ret
= PTR_ERR(priv
->vref
);
97 dev_err(dev
, "vref get failed, %d\n", ret
);
101 ret
= regulator_enable(priv
->vref
);
103 dev_err(dev
, "vref enable failed\n");
107 ret
= regulator_get_voltage(priv
->vref
);
109 dev_err(dev
, "vref get voltage failed, %d\n", ret
);
112 priv
->common
.vref_mv
= ret
/ 1000;
113 dev_dbg(dev
, "vref+=%dmV\n", priv
->common
.vref_mv
);
115 priv
->pclk
= devm_clk_get(dev
, "pclk");
116 if (IS_ERR(priv
->pclk
)) {
117 ret
= PTR_ERR(priv
->pclk
);
118 dev_err(dev
, "pclk get failed\n");
122 ret
= clk_prepare_enable(priv
->pclk
);
124 dev_err(dev
, "pclk enable failed\n");
128 priv
->rst
= devm_reset_control_get_exclusive(dev
, NULL
);
129 if (!IS_ERR(priv
->rst
)) {
130 reset_control_assert(priv
->rst
);
132 reset_control_deassert(priv
->rst
);
135 if (cfg
&& cfg
->has_hfsel
) {
136 /* When clock speed is higher than 80MHz, set HFSEL */
137 priv
->common
.hfsel
= (clk_get_rate(priv
->pclk
) > 80000000UL);
138 ret
= regmap_update_bits(regmap
, STM32_DAC_CR
,
139 STM32H7_DAC_CR_HFSEL
,
141 STM32H7_DAC_CR_HFSEL
: 0);
146 platform_set_drvdata(pdev
, &priv
->common
);
148 ret
= of_platform_populate(pdev
->dev
.of_node
, NULL
, NULL
, dev
);
150 dev_err(dev
, "failed to populate DT children\n");
157 clk_disable_unprepare(priv
->pclk
);
159 regulator_disable(priv
->vref
);
164 static int stm32_dac_remove(struct platform_device
*pdev
)
166 struct stm32_dac_common
*common
= platform_get_drvdata(pdev
);
167 struct stm32_dac_priv
*priv
= to_stm32_dac_priv(common
);
169 of_platform_depopulate(&pdev
->dev
);
170 clk_disable_unprepare(priv
->pclk
);
171 regulator_disable(priv
->vref
);
176 static const struct stm32_dac_cfg stm32h7_dac_cfg
= {
180 static const struct of_device_id stm32_dac_of_match
[] = {
182 .compatible
= "st,stm32f4-dac-core",
184 .compatible
= "st,stm32h7-dac-core",
185 .data
= (void *)&stm32h7_dac_cfg
,
189 MODULE_DEVICE_TABLE(of
, stm32_dac_of_match
);
191 static struct platform_driver stm32_dac_driver
= {
192 .probe
= stm32_dac_probe
,
193 .remove
= stm32_dac_remove
,
195 .name
= "stm32-dac-core",
196 .of_match_table
= stm32_dac_of_match
,
199 module_platform_driver(stm32_dac_driver
);
201 MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
202 MODULE_DESCRIPTION("STMicroelectronics STM32 DAC core driver");
203 MODULE_LICENSE("GPL v2");
204 MODULE_ALIAS("platform:stm32-dac-core");