xref: /openbmc/u-boot/drivers/adc/stm32-adc.c (revision a466ecec483a94ac5c66d3ce6793e1575f333d23)
1*a466ececSFabrice Gasnier // SPDX-License-Identifier: GPL-2.0
2*a466ececSFabrice Gasnier /*
3*a466ececSFabrice Gasnier  * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
4*a466ececSFabrice Gasnier  * Author: Fabrice Gasnier <fabrice.gasnier@st.com>
5*a466ececSFabrice Gasnier  *
6*a466ececSFabrice Gasnier  * Originally based on the Linux kernel v4.18 drivers/iio/adc/stm32-adc.c.
7*a466ececSFabrice Gasnier  */
8*a466ececSFabrice Gasnier 
9*a466ececSFabrice Gasnier #include <common.h>
10*a466ececSFabrice Gasnier #include <adc.h>
11*a466ececSFabrice Gasnier #include <asm/io.h>
12*a466ececSFabrice Gasnier #include <linux/iopoll.h>
13*a466ececSFabrice Gasnier #include "stm32-adc-core.h"
14*a466ececSFabrice Gasnier 
15*a466ececSFabrice Gasnier /* STM32H7 - Registers for each ADC instance */
16*a466ececSFabrice Gasnier #define STM32H7_ADC_ISR			0x00
17*a466ececSFabrice Gasnier #define STM32H7_ADC_CR			0x08
18*a466ececSFabrice Gasnier #define STM32H7_ADC_CFGR		0x0C
19*a466ececSFabrice Gasnier #define STM32H7_ADC_SMPR1		0x14
20*a466ececSFabrice Gasnier #define STM32H7_ADC_SMPR2		0x18
21*a466ececSFabrice Gasnier #define STM32H7_ADC_PCSEL		0x1C
22*a466ececSFabrice Gasnier #define STM32H7_ADC_SQR1		0x30
23*a466ececSFabrice Gasnier #define STM32H7_ADC_DR			0x40
24*a466ececSFabrice Gasnier #define STM32H7_ADC_DIFSEL		0xC0
25*a466ececSFabrice Gasnier 
26*a466ececSFabrice Gasnier /* STM32H7_ADC_ISR - bit fields */
27*a466ececSFabrice Gasnier #define STM32MP1_VREGREADY		BIT(12)
28*a466ececSFabrice Gasnier #define STM32H7_EOC			BIT(2)
29*a466ececSFabrice Gasnier #define STM32H7_ADRDY			BIT(0)
30*a466ececSFabrice Gasnier 
31*a466ececSFabrice Gasnier /* STM32H7_ADC_CR - bit fields */
32*a466ececSFabrice Gasnier #define STM32H7_DEEPPWD			BIT(29)
33*a466ececSFabrice Gasnier #define STM32H7_ADVREGEN		BIT(28)
34*a466ececSFabrice Gasnier #define STM32H7_BOOST			BIT(8)
35*a466ececSFabrice Gasnier #define STM32H7_ADSTART			BIT(2)
36*a466ececSFabrice Gasnier #define STM32H7_ADDIS			BIT(1)
37*a466ececSFabrice Gasnier #define STM32H7_ADEN			BIT(0)
38*a466ececSFabrice Gasnier 
39*a466ececSFabrice Gasnier /* STM32H7_ADC_CFGR bit fields */
40*a466ececSFabrice Gasnier #define STM32H7_EXTEN			GENMASK(11, 10)
41*a466ececSFabrice Gasnier #define STM32H7_DMNGT			GENMASK(1, 0)
42*a466ececSFabrice Gasnier 
43*a466ececSFabrice Gasnier /* STM32H7_ADC_SQR1 - bit fields */
44*a466ececSFabrice Gasnier #define STM32H7_SQ1_SHIFT		6
45*a466ececSFabrice Gasnier 
46*a466ececSFabrice Gasnier /* BOOST bit must be set on STM32H7 when ADC clock is above 20MHz */
47*a466ececSFabrice Gasnier #define STM32H7_BOOST_CLKRATE		20000000UL
48*a466ececSFabrice Gasnier 
49*a466ececSFabrice Gasnier #define STM32_ADC_CH_MAX		20	/* max number of channels */
50*a466ececSFabrice Gasnier #define STM32_ADC_TIMEOUT_US		100000
51*a466ececSFabrice Gasnier 
52*a466ececSFabrice Gasnier struct stm32_adc_cfg {
53*a466ececSFabrice Gasnier 	unsigned int max_channels;
54*a466ececSFabrice Gasnier 	unsigned int num_bits;
55*a466ececSFabrice Gasnier 	bool has_vregready;
56*a466ececSFabrice Gasnier };
57*a466ececSFabrice Gasnier 
58*a466ececSFabrice Gasnier struct stm32_adc {
59*a466ececSFabrice Gasnier 	void __iomem *regs;
60*a466ececSFabrice Gasnier 	int active_channel;
61*a466ececSFabrice Gasnier 	const struct stm32_adc_cfg *cfg;
62*a466ececSFabrice Gasnier };
63*a466ececSFabrice Gasnier 
stm32_adc_stop(struct udevice * dev)64*a466ececSFabrice Gasnier static int stm32_adc_stop(struct udevice *dev)
65*a466ececSFabrice Gasnier {
66*a466ececSFabrice Gasnier 	struct stm32_adc *adc = dev_get_priv(dev);
67*a466ececSFabrice Gasnier 
68*a466ececSFabrice Gasnier 	setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADDIS);
69*a466ececSFabrice Gasnier 	clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_BOOST);
70*a466ececSFabrice Gasnier 	/* Setting DEEPPWD disables ADC vreg and clears ADVREGEN */
71*a466ececSFabrice Gasnier 	setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_DEEPPWD);
72*a466ececSFabrice Gasnier 	adc->active_channel = -1;
73*a466ececSFabrice Gasnier 
74*a466ececSFabrice Gasnier 	return 0;
75*a466ececSFabrice Gasnier }
76*a466ececSFabrice Gasnier 
stm32_adc_start_channel(struct udevice * dev,int channel)77*a466ececSFabrice Gasnier static int stm32_adc_start_channel(struct udevice *dev, int channel)
78*a466ececSFabrice Gasnier {
79*a466ececSFabrice Gasnier 	struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
80*a466ececSFabrice Gasnier 	struct stm32_adc_common *common = dev_get_priv(dev_get_parent(dev));
81*a466ececSFabrice Gasnier 	struct stm32_adc *adc = dev_get_priv(dev);
82*a466ececSFabrice Gasnier 	int ret;
83*a466ececSFabrice Gasnier 	u32 val;
84*a466ececSFabrice Gasnier 
85*a466ececSFabrice Gasnier 	/* Exit deep power down, then enable ADC voltage regulator */
86*a466ececSFabrice Gasnier 	clrbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_DEEPPWD);
87*a466ececSFabrice Gasnier 	setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADVREGEN);
88*a466ececSFabrice Gasnier 	if (common->rate > STM32H7_BOOST_CLKRATE)
89*a466ececSFabrice Gasnier 		setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_BOOST);
90*a466ececSFabrice Gasnier 
91*a466ececSFabrice Gasnier 	/* Wait for startup time */
92*a466ececSFabrice Gasnier 	if (!adc->cfg->has_vregready) {
93*a466ececSFabrice Gasnier 		udelay(20);
94*a466ececSFabrice Gasnier 	} else {
95*a466ececSFabrice Gasnier 		ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val,
96*a466ececSFabrice Gasnier 					 val & STM32MP1_VREGREADY,
97*a466ececSFabrice Gasnier 					 STM32_ADC_TIMEOUT_US);
98*a466ececSFabrice Gasnier 		if (ret < 0) {
99*a466ececSFabrice Gasnier 			stm32_adc_stop(dev);
100*a466ececSFabrice Gasnier 			dev_err(dev, "Failed to enable vreg: %d\n", ret);
101*a466ececSFabrice Gasnier 			return ret;
102*a466ececSFabrice Gasnier 		}
103*a466ececSFabrice Gasnier 	}
104*a466ececSFabrice Gasnier 
105*a466ececSFabrice Gasnier 	/* Only use single ended channels */
106*a466ececSFabrice Gasnier 	writel(0, adc->regs + STM32H7_ADC_DIFSEL);
107*a466ececSFabrice Gasnier 
108*a466ececSFabrice Gasnier 	/* Enable ADC, Poll for ADRDY to be set (after adc startup time) */
109*a466ececSFabrice Gasnier 	setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADEN);
110*a466ececSFabrice Gasnier 	ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val,
111*a466ececSFabrice Gasnier 				 val & STM32H7_ADRDY, STM32_ADC_TIMEOUT_US);
112*a466ececSFabrice Gasnier 	if (ret < 0) {
113*a466ececSFabrice Gasnier 		stm32_adc_stop(dev);
114*a466ececSFabrice Gasnier 		dev_err(dev, "Failed to enable ADC: %d\n", ret);
115*a466ececSFabrice Gasnier 		return ret;
116*a466ececSFabrice Gasnier 	}
117*a466ececSFabrice Gasnier 
118*a466ececSFabrice Gasnier 	/* Preselect channels */
119*a466ececSFabrice Gasnier 	writel(uc_pdata->channel_mask, adc->regs + STM32H7_ADC_PCSEL);
120*a466ececSFabrice Gasnier 
121*a466ececSFabrice Gasnier 	/* Set sampling time to max value by default */
122*a466ececSFabrice Gasnier 	writel(0xffffffff, adc->regs + STM32H7_ADC_SMPR1);
123*a466ececSFabrice Gasnier 	writel(0xffffffff, adc->regs + STM32H7_ADC_SMPR2);
124*a466ececSFabrice Gasnier 
125*a466ececSFabrice Gasnier 	/* Program regular sequence: chan in SQ1 & len = 0 for one channel */
126*a466ececSFabrice Gasnier 	writel(channel << STM32H7_SQ1_SHIFT, adc->regs + STM32H7_ADC_SQR1);
127*a466ececSFabrice Gasnier 
128*a466ececSFabrice Gasnier 	/* Trigger detection disabled (conversion can be launched in SW) */
129*a466ececSFabrice Gasnier 	clrbits_le32(adc->regs + STM32H7_ADC_CFGR, STM32H7_EXTEN |
130*a466ececSFabrice Gasnier 		     STM32H7_DMNGT);
131*a466ececSFabrice Gasnier 	adc->active_channel = channel;
132*a466ececSFabrice Gasnier 
133*a466ececSFabrice Gasnier 	return 0;
134*a466ececSFabrice Gasnier }
135*a466ececSFabrice Gasnier 
stm32_adc_channel_data(struct udevice * dev,int channel,unsigned int * data)136*a466ececSFabrice Gasnier static int stm32_adc_channel_data(struct udevice *dev, int channel,
137*a466ececSFabrice Gasnier 				  unsigned int *data)
138*a466ececSFabrice Gasnier {
139*a466ececSFabrice Gasnier 	struct stm32_adc *adc = dev_get_priv(dev);
140*a466ececSFabrice Gasnier 	int ret;
141*a466ececSFabrice Gasnier 	u32 val;
142*a466ececSFabrice Gasnier 
143*a466ececSFabrice Gasnier 	if (channel != adc->active_channel) {
144*a466ececSFabrice Gasnier 		dev_err(dev, "Requested channel is not active!\n");
145*a466ececSFabrice Gasnier 		return -EINVAL;
146*a466ececSFabrice Gasnier 	}
147*a466ececSFabrice Gasnier 
148*a466ececSFabrice Gasnier 	setbits_le32(adc->regs + STM32H7_ADC_CR, STM32H7_ADSTART);
149*a466ececSFabrice Gasnier 	ret = readl_poll_timeout(adc->regs + STM32H7_ADC_ISR, val,
150*a466ececSFabrice Gasnier 				 val & STM32H7_EOC, STM32_ADC_TIMEOUT_US);
151*a466ececSFabrice Gasnier 	if (ret < 0) {
152*a466ececSFabrice Gasnier 		dev_err(dev, "conversion timed out: %d\n", ret);
153*a466ececSFabrice Gasnier 		return ret;
154*a466ececSFabrice Gasnier 	}
155*a466ececSFabrice Gasnier 
156*a466ececSFabrice Gasnier 	*data = readl(adc->regs + STM32H7_ADC_DR);
157*a466ececSFabrice Gasnier 
158*a466ececSFabrice Gasnier 	return 0;
159*a466ececSFabrice Gasnier }
160*a466ececSFabrice Gasnier 
stm32_adc_chan_of_init(struct udevice * dev)161*a466ececSFabrice Gasnier static int stm32_adc_chan_of_init(struct udevice *dev)
162*a466ececSFabrice Gasnier {
163*a466ececSFabrice Gasnier 	struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
164*a466ececSFabrice Gasnier 	struct stm32_adc *adc = dev_get_priv(dev);
165*a466ececSFabrice Gasnier 	u32 chans[STM32_ADC_CH_MAX];
166*a466ececSFabrice Gasnier 	int i, num_channels, ret;
167*a466ececSFabrice Gasnier 
168*a466ececSFabrice Gasnier 	/* Retrieve single ended channels listed in device tree */
169*a466ececSFabrice Gasnier 	num_channels = dev_read_size(dev, "st,adc-channels");
170*a466ececSFabrice Gasnier 	if (num_channels < 0) {
171*a466ececSFabrice Gasnier 		dev_err(dev, "can't get st,adc-channels: %d\n", num_channels);
172*a466ececSFabrice Gasnier 		return num_channels;
173*a466ececSFabrice Gasnier 	}
174*a466ececSFabrice Gasnier 	num_channels /= sizeof(u32);
175*a466ececSFabrice Gasnier 
176*a466ececSFabrice Gasnier 	if (num_channels > adc->cfg->max_channels) {
177*a466ececSFabrice Gasnier 		dev_err(dev, "too many st,adc-channels: %d\n", num_channels);
178*a466ececSFabrice Gasnier 		return -EINVAL;
179*a466ececSFabrice Gasnier 	}
180*a466ececSFabrice Gasnier 
181*a466ececSFabrice Gasnier 	ret = dev_read_u32_array(dev, "st,adc-channels", chans, num_channels);
182*a466ececSFabrice Gasnier 	if (ret < 0) {
183*a466ececSFabrice Gasnier 		dev_err(dev, "can't read st,adc-channels: %d\n", ret);
184*a466ececSFabrice Gasnier 		return ret;
185*a466ececSFabrice Gasnier 	}
186*a466ececSFabrice Gasnier 
187*a466ececSFabrice Gasnier 	for (i = 0; i < num_channels; i++) {
188*a466ececSFabrice Gasnier 		if (chans[i] >= adc->cfg->max_channels) {
189*a466ececSFabrice Gasnier 			dev_err(dev, "bad channel %u\n", chans[i]);
190*a466ececSFabrice Gasnier 			return -EINVAL;
191*a466ececSFabrice Gasnier 		}
192*a466ececSFabrice Gasnier 		uc_pdata->channel_mask |= 1 << chans[i];
193*a466ececSFabrice Gasnier 	}
194*a466ececSFabrice Gasnier 
195*a466ececSFabrice Gasnier 	uc_pdata->data_mask = (1 << adc->cfg->num_bits) - 1;
196*a466ececSFabrice Gasnier 	uc_pdata->data_format = ADC_DATA_FORMAT_BIN;
197*a466ececSFabrice Gasnier 	uc_pdata->data_timeout_us = 100000;
198*a466ececSFabrice Gasnier 
199*a466ececSFabrice Gasnier 	return 0;
200*a466ececSFabrice Gasnier }
201*a466ececSFabrice Gasnier 
stm32_adc_probe(struct udevice * dev)202*a466ececSFabrice Gasnier static int stm32_adc_probe(struct udevice *dev)
203*a466ececSFabrice Gasnier {
204*a466ececSFabrice Gasnier 	struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
205*a466ececSFabrice Gasnier 	struct stm32_adc_common *common = dev_get_priv(dev_get_parent(dev));
206*a466ececSFabrice Gasnier 	struct stm32_adc *adc = dev_get_priv(dev);
207*a466ececSFabrice Gasnier 	int offset;
208*a466ececSFabrice Gasnier 
209*a466ececSFabrice Gasnier 	offset = dev_read_u32_default(dev, "reg", -ENODATA);
210*a466ececSFabrice Gasnier 	if (offset < 0) {
211*a466ececSFabrice Gasnier 		dev_err(dev, "Can't read reg property\n");
212*a466ececSFabrice Gasnier 		return offset;
213*a466ececSFabrice Gasnier 	}
214*a466ececSFabrice Gasnier 	adc->regs = common->base + offset;
215*a466ececSFabrice Gasnier 	adc->cfg = (const struct stm32_adc_cfg *)dev_get_driver_data(dev);
216*a466ececSFabrice Gasnier 
217*a466ececSFabrice Gasnier 	/* VDD supplied by common vref pin */
218*a466ececSFabrice Gasnier 	uc_pdata->vdd_supply = common->vref;
219*a466ececSFabrice Gasnier 	uc_pdata->vdd_microvolts = common->vref_uv;
220*a466ececSFabrice Gasnier 	uc_pdata->vss_microvolts = 0;
221*a466ececSFabrice Gasnier 
222*a466ececSFabrice Gasnier 	return stm32_adc_chan_of_init(dev);
223*a466ececSFabrice Gasnier }
224*a466ececSFabrice Gasnier 
225*a466ececSFabrice Gasnier static const struct adc_ops stm32_adc_ops = {
226*a466ececSFabrice Gasnier 	.start_channel = stm32_adc_start_channel,
227*a466ececSFabrice Gasnier 	.channel_data = stm32_adc_channel_data,
228*a466ececSFabrice Gasnier 	.stop = stm32_adc_stop,
229*a466ececSFabrice Gasnier };
230*a466ececSFabrice Gasnier 
231*a466ececSFabrice Gasnier static const struct stm32_adc_cfg stm32h7_adc_cfg = {
232*a466ececSFabrice Gasnier 	.num_bits = 16,
233*a466ececSFabrice Gasnier 	.max_channels = STM32_ADC_CH_MAX,
234*a466ececSFabrice Gasnier };
235*a466ececSFabrice Gasnier 
236*a466ececSFabrice Gasnier static const struct stm32_adc_cfg stm32mp1_adc_cfg = {
237*a466ececSFabrice Gasnier 	.num_bits = 16,
238*a466ececSFabrice Gasnier 	.max_channels = STM32_ADC_CH_MAX,
239*a466ececSFabrice Gasnier 	.has_vregready = true,
240*a466ececSFabrice Gasnier };
241*a466ececSFabrice Gasnier 
242*a466ececSFabrice Gasnier static const struct udevice_id stm32_adc_ids[] = {
243*a466ececSFabrice Gasnier 	{ .compatible = "st,stm32h7-adc",
244*a466ececSFabrice Gasnier 	  .data = (ulong)&stm32h7_adc_cfg },
245*a466ececSFabrice Gasnier 	{ .compatible = "st,stm32mp1-adc",
246*a466ececSFabrice Gasnier 	  .data = (ulong)&stm32mp1_adc_cfg },
247*a466ececSFabrice Gasnier 	{}
248*a466ececSFabrice Gasnier };
249*a466ececSFabrice Gasnier 
250*a466ececSFabrice Gasnier U_BOOT_DRIVER(stm32_adc) = {
251*a466ececSFabrice Gasnier 	.name  = "stm32-adc",
252*a466ececSFabrice Gasnier 	.id = UCLASS_ADC,
253*a466ececSFabrice Gasnier 	.of_match = stm32_adc_ids,
254*a466ececSFabrice Gasnier 	.probe = stm32_adc_probe,
255*a466ececSFabrice Gasnier 	.ops = &stm32_adc_ops,
256*a466ececSFabrice Gasnier 	.priv_auto_alloc_size = sizeof(struct stm32_adc),
257*a466ececSFabrice Gasnier };
258