1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
4 * Author: Fabrice Gasnier <fabrice.gasnier@st.com>
6 * Originally based on the Linux kernel v4.18 drivers/iio/adc/stm32-adc.c.
12 #include <dm/device_compat.h>
13 #include <linux/iopoll.h>
14 #include "stm32-adc-core.h"
16 /* STM32H7 - Registers for each ADC instance */
17 #define STM32H7_ADC_ISR 0x00
18 #define STM32H7_ADC_CR 0x08
19 #define STM32H7_ADC_CFGR 0x0C
20 #define STM32H7_ADC_SMPR1 0x14
21 #define STM32H7_ADC_SMPR2 0x18
22 #define STM32H7_ADC_PCSEL 0x1C
23 #define STM32H7_ADC_SQR1 0x30
24 #define STM32H7_ADC_DR 0x40
25 #define STM32H7_ADC_DIFSEL 0xC0
27 /* STM32H7_ADC_ISR - bit fields */
28 #define STM32MP1_VREGREADY BIT(12)
29 #define STM32H7_EOC BIT(2)
30 #define STM32H7_ADRDY BIT(0)
32 /* STM32H7_ADC_CR - bit fields */
33 #define STM32H7_DEEPPWD BIT(29)
34 #define STM32H7_ADVREGEN BIT(28)
35 #define STM32H7_BOOST BIT(8)
36 #define STM32H7_ADSTART BIT(2)
37 #define STM32H7_ADDIS BIT(1)
38 #define STM32H7_ADEN BIT(0)
40 /* STM32H7_ADC_CFGR bit fields */
41 #define STM32H7_EXTEN GENMASK(11, 10)
42 #define STM32H7_DMNGT GENMASK(1, 0)
44 /* STM32H7_ADC_SQR1 - bit fields */
45 #define STM32H7_SQ1_SHIFT 6
47 /* BOOST bit must be set on STM32H7 when ADC clock is above 20MHz */
48 #define STM32H7_BOOST_CLKRATE 20000000UL
50 #define STM32_ADC_CH_MAX 20 /* max number of channels */
51 #define STM32_ADC_TIMEOUT_US 100000
53 struct stm32_adc_cfg
{
54 unsigned int max_channels
;
55 unsigned int num_bits
;
62 const struct stm32_adc_cfg
*cfg
;
65 static int stm32_adc_stop(struct udevice
*dev
)
67 struct stm32_adc
*adc
= dev_get_priv(dev
);
69 setbits_le32(adc
->regs
+ STM32H7_ADC_CR
, STM32H7_ADDIS
);
70 clrbits_le32(adc
->regs
+ STM32H7_ADC_CR
, STM32H7_BOOST
);
71 /* Setting DEEPPWD disables ADC vreg and clears ADVREGEN */
72 setbits_le32(adc
->regs
+ STM32H7_ADC_CR
, STM32H7_DEEPPWD
);
73 adc
->active_channel
= -1;
78 static int stm32_adc_start_channel(struct udevice
*dev
, int channel
)
80 struct adc_uclass_platdata
*uc_pdata
= dev_get_uclass_platdata(dev
);
81 struct stm32_adc_common
*common
= dev_get_priv(dev_get_parent(dev
));
82 struct stm32_adc
*adc
= dev_get_priv(dev
);
86 /* Exit deep power down, then enable ADC voltage regulator */
87 clrbits_le32(adc
->regs
+ STM32H7_ADC_CR
, STM32H7_DEEPPWD
);
88 setbits_le32(adc
->regs
+ STM32H7_ADC_CR
, STM32H7_ADVREGEN
);
89 if (common
->rate
> STM32H7_BOOST_CLKRATE
)
90 setbits_le32(adc
->regs
+ STM32H7_ADC_CR
, STM32H7_BOOST
);
92 /* Wait for startup time */
93 if (!adc
->cfg
->has_vregready
) {
96 ret
= readl_poll_timeout(adc
->regs
+ STM32H7_ADC_ISR
, val
,
97 val
& STM32MP1_VREGREADY
,
98 STM32_ADC_TIMEOUT_US
);
101 dev_err(dev
, "Failed to enable vreg: %d\n", ret
);
106 /* Only use single ended channels */
107 writel(0, adc
->regs
+ STM32H7_ADC_DIFSEL
);
109 /* Enable ADC, Poll for ADRDY to be set (after adc startup time) */
110 setbits_le32(adc
->regs
+ STM32H7_ADC_CR
, STM32H7_ADEN
);
111 ret
= readl_poll_timeout(adc
->regs
+ STM32H7_ADC_ISR
, val
,
112 val
& STM32H7_ADRDY
, STM32_ADC_TIMEOUT_US
);
115 dev_err(dev
, "Failed to enable ADC: %d\n", ret
);
119 /* Preselect channels */
120 writel(uc_pdata
->channel_mask
, adc
->regs
+ STM32H7_ADC_PCSEL
);
122 /* Set sampling time to max value by default */
123 writel(0xffffffff, adc
->regs
+ STM32H7_ADC_SMPR1
);
124 writel(0xffffffff, adc
->regs
+ STM32H7_ADC_SMPR2
);
126 /* Program regular sequence: chan in SQ1 & len = 0 for one channel */
127 writel(channel
<< STM32H7_SQ1_SHIFT
, adc
->regs
+ STM32H7_ADC_SQR1
);
129 /* Trigger detection disabled (conversion can be launched in SW) */
130 clrbits_le32(adc
->regs
+ STM32H7_ADC_CFGR
, STM32H7_EXTEN
|
132 adc
->active_channel
= channel
;
137 static int stm32_adc_channel_data(struct udevice
*dev
, int channel
,
140 struct stm32_adc
*adc
= dev_get_priv(dev
);
144 if (channel
!= adc
->active_channel
) {
145 dev_err(dev
, "Requested channel is not active!\n");
149 setbits_le32(adc
->regs
+ STM32H7_ADC_CR
, STM32H7_ADSTART
);
150 ret
= readl_poll_timeout(adc
->regs
+ STM32H7_ADC_ISR
, val
,
151 val
& STM32H7_EOC
, STM32_ADC_TIMEOUT_US
);
153 dev_err(dev
, "conversion timed out: %d\n", ret
);
157 *data
= readl(adc
->regs
+ STM32H7_ADC_DR
);
162 static int stm32_adc_chan_of_init(struct udevice
*dev
)
164 struct adc_uclass_platdata
*uc_pdata
= dev_get_uclass_platdata(dev
);
165 struct stm32_adc
*adc
= dev_get_priv(dev
);
166 u32 chans
[STM32_ADC_CH_MAX
];
167 unsigned int i
, num_channels
;
170 /* Retrieve single ended channels listed in device tree */
171 ret
= dev_read_size(dev
, "st,adc-channels");
173 dev_err(dev
, "can't get st,adc-channels: %d\n", ret
);
176 num_channels
= ret
/ sizeof(u32
);
178 if (num_channels
> adc
->cfg
->max_channels
) {
179 dev_err(dev
, "too many st,adc-channels: %d\n", num_channels
);
183 ret
= dev_read_u32_array(dev
, "st,adc-channels", chans
, num_channels
);
185 dev_err(dev
, "can't read st,adc-channels: %d\n", ret
);
189 for (i
= 0; i
< num_channels
; i
++) {
190 if (chans
[i
] >= adc
->cfg
->max_channels
) {
191 dev_err(dev
, "bad channel %u\n", chans
[i
]);
194 uc_pdata
->channel_mask
|= 1 << chans
[i
];
197 uc_pdata
->data_mask
= (1 << adc
->cfg
->num_bits
) - 1;
198 uc_pdata
->data_format
= ADC_DATA_FORMAT_BIN
;
199 uc_pdata
->data_timeout_us
= 100000;
204 static int stm32_adc_probe(struct udevice
*dev
)
206 struct adc_uclass_platdata
*uc_pdata
= dev_get_uclass_platdata(dev
);
207 struct stm32_adc_common
*common
= dev_get_priv(dev_get_parent(dev
));
208 struct stm32_adc
*adc
= dev_get_priv(dev
);
211 offset
= dev_read_u32_default(dev
, "reg", -ENODATA
);
213 dev_err(dev
, "Can't read reg property\n");
216 adc
->regs
= common
->base
+ offset
;
217 adc
->cfg
= (const struct stm32_adc_cfg
*)dev_get_driver_data(dev
);
219 /* VDD supplied by common vref pin */
220 uc_pdata
->vdd_supply
= common
->vref
;
221 uc_pdata
->vdd_microvolts
= common
->vref_uv
;
222 uc_pdata
->vss_microvolts
= 0;
224 return stm32_adc_chan_of_init(dev
);
227 static const struct adc_ops stm32_adc_ops
= {
228 .start_channel
= stm32_adc_start_channel
,
229 .channel_data
= stm32_adc_channel_data
,
230 .stop
= stm32_adc_stop
,
233 static const struct stm32_adc_cfg stm32h7_adc_cfg
= {
235 .max_channels
= STM32_ADC_CH_MAX
,
238 static const struct stm32_adc_cfg stm32mp1_adc_cfg
= {
240 .max_channels
= STM32_ADC_CH_MAX
,
241 .has_vregready
= true,
244 static const struct udevice_id stm32_adc_ids
[] = {
245 { .compatible
= "st,stm32h7-adc",
246 .data
= (ulong
)&stm32h7_adc_cfg
},
247 { .compatible
= "st,stm32mp1-adc",
248 .data
= (ulong
)&stm32mp1_adc_cfg
},
252 U_BOOT_DRIVER(stm32_adc
) = {
255 .of_match
= stm32_adc_ids
,
256 .probe
= stm32_adc_probe
,
257 .ops
= &stm32_adc_ops
,
258 .priv_auto_alloc_size
= sizeof(struct stm32_adc
),