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