1 // SPDX-License-Identifier: GPL-2.0
3 * This file is part of STM32 DAC driver
5 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
6 * Author: Fabrice Gasnier <fabrice.gasnier@st.com>.
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>
21 #include "stm32-dac-core.h"
24 * struct stm32_dac_priv - stm32 DAC core private data
25 * @pclk: peripheral clock common for all DACs
26 * @vref: regulator reference
27 * @common: Common data for all DAC instances
29 struct stm32_dac_priv
{
31 struct regulator
*vref
;
32 struct stm32_dac_common common
;
36 * struct stm32_dac_cfg - DAC configuration
37 * @has_hfsel: DAC has high frequency control
39 struct stm32_dac_cfg
{
43 static struct stm32_dac_priv
*to_stm32_dac_priv(struct stm32_dac_common
*com
)
45 return container_of(com
, struct stm32_dac_priv
, common
);
48 static const struct regmap_config stm32_dac_regmap_cfg
= {
51 .reg_stride
= sizeof(u32
),
52 .max_register
= 0x3fc,
55 static int stm32_dac_core_hw_start(struct device
*dev
)
57 struct stm32_dac_common
*common
= dev_get_drvdata(dev
);
58 struct stm32_dac_priv
*priv
= to_stm32_dac_priv(common
);
61 ret
= regulator_enable(priv
->vref
);
63 dev_err(dev
, "vref enable failed: %d\n", ret
);
67 ret
= clk_prepare_enable(priv
->pclk
);
69 dev_err(dev
, "pclk enable failed: %d\n", ret
);
70 goto err_regulator_disable
;
75 err_regulator_disable
:
76 regulator_disable(priv
->vref
);
81 static void stm32_dac_core_hw_stop(struct device
*dev
)
83 struct stm32_dac_common
*common
= dev_get_drvdata(dev
);
84 struct stm32_dac_priv
*priv
= to_stm32_dac_priv(common
);
86 clk_disable_unprepare(priv
->pclk
);
87 regulator_disable(priv
->vref
);
90 static int stm32_dac_probe(struct platform_device
*pdev
)
92 struct device
*dev
= &pdev
->dev
;
93 const struct stm32_dac_cfg
*cfg
;
94 struct stm32_dac_priv
*priv
;
95 struct regmap
*regmap
;
97 struct reset_control
*rst
;
100 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
103 platform_set_drvdata(pdev
, &priv
->common
);
105 cfg
= device_get_match_data(dev
);
107 mmio
= devm_platform_ioremap_resource(pdev
, 0);
109 return PTR_ERR(mmio
);
111 regmap
= devm_regmap_init_mmio_clk(dev
, "pclk", mmio
,
112 &stm32_dac_regmap_cfg
);
114 return PTR_ERR(regmap
);
115 priv
->common
.regmap
= regmap
;
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");
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");
125 pm_runtime_get_noresume(dev
);
126 pm_runtime_set_active(dev
);
127 pm_runtime_enable(dev
);
129 ret
= stm32_dac_core_hw_start(dev
);
133 ret
= regulator_get_voltage(priv
->vref
);
135 dev_err(dev
, "vref get voltage failed, %d\n", ret
);
138 priv
->common
.vref_mv
= ret
/ 1000;
139 dev_dbg(dev
, "vref+=%dmV\n", priv
->common
.vref_mv
);
141 rst
= devm_reset_control_get_optional_exclusive(dev
, NULL
);
144 ret
= dev_err_probe(dev
, PTR_ERR(rst
), "reset get failed\n");
148 reset_control_assert(rst
);
150 reset_control_deassert(rst
);
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
,
159 STM32H7_DAC_CR_HFSEL
: 0);
165 ret
= of_platform_populate(pdev
->dev
.of_node
, NULL
, NULL
, dev
);
167 dev_err(dev
, "failed to populate DT children\n");
176 stm32_dac_core_hw_stop(dev
);
178 pm_runtime_disable(dev
);
179 pm_runtime_set_suspended(dev
);
180 pm_runtime_put_noidle(dev
);
185 static void stm32_dac_remove(struct platform_device
*pdev
)
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
);
195 static int stm32_dac_core_resume(struct device
*dev
)
197 struct stm32_dac_common
*common
= dev_get_drvdata(dev
);
198 struct stm32_dac_priv
*priv
= to_stm32_dac_priv(common
);
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
);
209 return pm_runtime_force_resume(dev
);
212 static int stm32_dac_core_runtime_suspend(struct device
*dev
)
214 stm32_dac_core_hw_stop(dev
);
219 static int stm32_dac_core_runtime_resume(struct device
*dev
)
221 return stm32_dac_core_hw_start(dev
);
224 static 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
,
231 static const struct stm32_dac_cfg stm32h7_dac_cfg
= {
235 static const struct of_device_id stm32_dac_of_match
[] = {
237 .compatible
= "st,stm32f4-dac-core",
239 .compatible
= "st,stm32h7-dac-core",
240 .data
= (void *)&stm32h7_dac_cfg
,
244 MODULE_DEVICE_TABLE(of
, stm32_dac_of_match
);
246 static struct platform_driver stm32_dac_driver
= {
247 .probe
= stm32_dac_probe
,
248 .remove_new
= stm32_dac_remove
,
250 .name
= "stm32-dac-core",
251 .of_match_table
= stm32_dac_of_match
,
252 .pm
= pm_ptr(&stm32_dac_core_pm_ops
),
255 module_platform_driver(stm32_dac_driver
);
257 MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
258 MODULE_DESCRIPTION("STMicroelectronics STM32 DAC core driver");
259 MODULE_LICENSE("GPL v2");
260 MODULE_ALIAS("platform:stm32-dac-core");