blob: f593fb6447b3f28b9a2af9d81bff172000002505 [file] [log] [blame]
Luca Ellero841ebfb82023-07-05 14:56:16 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2023 ASEM Srl
4 * Author: Luca Ellero <l.ellero@asem.it>
5 *
6 * Originally based on NXP linux-imx kernel v5.15 drivers/iio/adc/imx93_adc.c
7 */
8
Luca Ellero841ebfb82023-07-05 14:56:16 +02009#include <errno.h>
10#include <dm.h>
11#include <linux/bitfield.h>
12#include <linux/iopoll.h>
13#include <clk.h>
14#include <adc.h>
15
16#define IMX93_ADC_MCR 0x00
17#define IMX93_ADC_MSR 0x04
18#define IMX93_ADC_ISR 0x10
19#define IMX93_ADC_IMR 0x20
20#define IMX93_ADC_CIMR0 0x24
21#define IMX93_ADC_CTR0 0x94
22#define IMX93_ADC_NCMR0 0xA4
23#define IMX93_ADC_PCDR0 0x100
24#define IMX93_ADC_PCDR1 0x104
25#define IMX93_ADC_PCDR2 0x108
26#define IMX93_ADC_PCDR3 0x10c
27#define IMX93_ADC_PCDR4 0x110
28#define IMX93_ADC_PCDR5 0x114
29#define IMX93_ADC_PCDR6 0x118
30#define IMX93_ADC_PCDR7 0x11c
31#define IMX93_ADC_CALSTAT 0x39C
32
33#define IMX93_ADC_MCR_MODE_MASK BIT(29)
34#define IMX93_ADC_MCR_NSTART_MASK BIT(24)
35#define IMX93_ADC_MCR_CALSTART_MASK BIT(14)
36#define IMX93_ADC_MCR_ADCLKSE_MASK BIT(8)
37#define IMX93_ADC_MCR_PWDN_MASK BIT(0)
38
39#define IMX93_ADC_MSR_CALFAIL_MASK BIT(30)
40#define IMX93_ADC_MSR_CALBUSY_MASK BIT(29)
41#define IMX93_ADC_MSR_ADCSTATUS_MASK GENMASK(2, 0)
42
43#define IMX93_ADC_ISR_EOC_MASK BIT(1)
44
45#define IMX93_ADC_IMR_EOC_MASK BIT(1)
46#define IMX93_ADC_IMR_ECH_MASK BIT(0)
47
48#define IMX93_ADC_PCDR_CDATA_MASK GENMASK(11, 0)
49
50#define IDLE 0
51#define POWER_DOWN 1
52#define WAIT_STATE 2
53#define BUSY_IN_CALIBRATION 3
54#define SAMPLE 4
55#define CONVERSION 6
56
57#define IMX93_ADC_MAX_CHANNEL 3
58#define IMX93_ADC_DAT_MASK 0xfff
59#define IMX93_ADC_TIMEOUT 100000
60
61struct imx93_adc_priv {
62 int active_channel;
63 void __iomem *regs;
64 struct clk ipg_clk;
65};
66
67static void imx93_adc_power_down(struct imx93_adc_priv *adc)
68{
69 u32 mcr, msr;
70 int ret;
71
72 mcr = readl(adc->regs + IMX93_ADC_MCR);
73 mcr |= FIELD_PREP(IMX93_ADC_MCR_PWDN_MASK, 1);
74 writel(mcr, adc->regs + IMX93_ADC_MCR);
75
76 ret = readl_poll_timeout(adc->regs + IMX93_ADC_MSR, msr,
77 ((msr & IMX93_ADC_MSR_ADCSTATUS_MASK) == POWER_DOWN), 50);
78 if (ret == -ETIMEDOUT)
79 pr_warn("ADC not in power down mode, current MSR: %x\n", msr);
80}
81
82static void imx93_adc_power_up(struct imx93_adc_priv *adc)
83{
84 u32 mcr;
85
86 /* bring ADC out of power down state, in idle state */
87 mcr = readl(adc->regs + IMX93_ADC_MCR);
88 mcr &= ~FIELD_PREP(IMX93_ADC_MCR_PWDN_MASK, 1);
89 writel(mcr, adc->regs + IMX93_ADC_MCR);
90}
91
92static void imx93_adc_config_ad_clk(struct imx93_adc_priv *adc)
93{
94 u32 mcr;
95
96 /* put adc in power down mode */
97 imx93_adc_power_down(adc);
98
99 /* config the AD_CLK equal to bus clock */
100 mcr = readl(adc->regs + IMX93_ADC_MCR);
101 mcr |= FIELD_PREP(IMX93_ADC_MCR_ADCLKSE_MASK, 1);
102 writel(mcr, adc->regs + IMX93_ADC_MCR);
103
104 /* bring ADC out of power down state, in idle state */
105 imx93_adc_power_up(adc);
106}
107
108static int imx93_adc_calibration(struct imx93_adc_priv *adc)
109{
110 u32 mcr, msr;
111 int ret;
112
113 /* make sure ADC is in power down mode */
114 imx93_adc_power_down(adc);
115
116 /* config SAR controller operating clock */
117 mcr = readl(adc->regs + IMX93_ADC_MCR);
118 mcr &= ~FIELD_PREP(IMX93_ADC_MCR_ADCLKSE_MASK, 1);
119 writel(mcr, adc->regs + IMX93_ADC_MCR);
120
121 /* bring ADC out of power down state */
122 imx93_adc_power_up(adc);
123
124 /*
125 * we use the default TSAMP/NRSMPL/AVGEN in MCR,
126 * can add the setting of these bit if need
127 */
128
129 /* run calibration */
130 mcr = readl(adc->regs + IMX93_ADC_MCR);
131 mcr |= FIELD_PREP(IMX93_ADC_MCR_CALSTART_MASK, 1);
132 writel(mcr, adc->regs + IMX93_ADC_MCR);
133
134 /* wait calibration to be finished */
135 ret = readl_poll_timeout(adc->regs + IMX93_ADC_MSR, msr,
136 !(msr & IMX93_ADC_MSR_CALBUSY_MASK), 2000000);
137 if (ret == -ETIMEDOUT) {
138 pr_warn("ADC calibration timeout\n");
139 return ret;
140 }
141
142 /* check whether calbration is successful or not */
143 msr = readl(adc->regs + IMX93_ADC_MSR);
144 if (msr & IMX93_ADC_MSR_CALFAIL_MASK) {
145 pr_warn("ADC calibration failed!\n");
146 return -EAGAIN;
147 }
148
149 return 0;
150}
151
152static int imx93_adc_channel_data(struct udevice *dev, int channel,
153 unsigned int *data)
154{
155 struct imx93_adc_priv *adc = dev_get_priv(dev);
156 u32 isr, pcda;
157 int ret;
158
159 if (channel != adc->active_channel) {
160 pr_err("Requested channel is not active!\n");
161 return -EINVAL;
162 }
163
164 ret = readl_poll_timeout(adc->regs + IMX93_ADC_ISR, isr,
165 (isr & IMX93_ADC_ISR_EOC_MASK), IMX93_ADC_TIMEOUT);
166
167 /* clear interrupts */
168 writel(isr, adc->regs + IMX93_ADC_ISR);
169
170 if (ret == -ETIMEDOUT) {
171 pr_warn("ADC conversion timeout!\n");
172 return ret;
173 }
174
175 pcda = readl(adc->regs + IMX93_ADC_PCDR0 + channel * 4);
176
177 *data = FIELD_GET(IMX93_ADC_PCDR_CDATA_MASK, pcda);
178
179 return 0;
180}
181
182static int imx93_adc_start_channel(struct udevice *dev, int channel)
183{
184 struct imx93_adc_priv *adc = dev_get_priv(dev);
185 u32 imr, mcr;
186
187 /* config channel mask register */
188 writel(1 << channel, adc->regs + IMX93_ADC_NCMR0);
189
190 /* config interrupt mask */
191 imr = FIELD_PREP(IMX93_ADC_IMR_EOC_MASK, 1);
192 writel(imr, adc->regs + IMX93_ADC_IMR);
193 writel(1 << channel, adc->regs + IMX93_ADC_CIMR0);
194
195 /* config one-shot mode */
196 mcr = readl(adc->regs + IMX93_ADC_MCR);
197 mcr &= ~FIELD_PREP(IMX93_ADC_MCR_MODE_MASK, 1);
198 writel(mcr, adc->regs + IMX93_ADC_MCR);
199
200 /* start normal conversion */
201 mcr = readl(adc->regs + IMX93_ADC_MCR);
202 mcr |= FIELD_PREP(IMX93_ADC_MCR_NSTART_MASK, 1);
203 writel(mcr, adc->regs + IMX93_ADC_MCR);
204
205 adc->active_channel = channel;
206
207 return 0;
208}
209
210static int imx93_adc_stop(struct udevice *dev)
211{
212 struct imx93_adc_priv *adc = dev_get_priv(dev);
213
214 imx93_adc_power_down(adc);
215
216 adc->active_channel = -1;
217
218 return 0;
219}
220
221static int imx93_adc_probe(struct udevice *dev)
222{
223 struct imx93_adc_priv *adc = dev_get_priv(dev);
224 unsigned int ret;
225
226 ret = imx93_adc_calibration(adc);
227 if (ret < 0)
228 return ret;
229
230 imx93_adc_config_ad_clk(adc);
231
232 adc->active_channel = -1;
233
234 return 0;
235}
236
237static int imx93_adc_of_to_plat(struct udevice *dev)
238{
239 struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
240 struct imx93_adc_priv *adc = dev_get_priv(dev);
241 unsigned int ret;
242
243 adc->regs = dev_read_addr_ptr(dev);
244 if (adc->regs == (struct imx93_adc *)FDT_ADDR_T_NONE) {
245 pr_err("Dev: %s - can't get address!", dev->name);
246 return -ENODATA;
247 }
248
249 ret = clk_get_by_name(dev, "ipg", &adc->ipg_clk);
250 if (ret < 0) {
251 pr_err("Can't get ADC ipg clk: %d\n", ret);
252 return ret;
253 }
254 ret = clk_enable(&adc->ipg_clk);
255 if(ret) {
256 pr_err("Can't enable ADC ipg clk: %d\n", ret);
257 return ret;
258 }
259
260 uc_pdata->data_mask = IMX93_ADC_DAT_MASK;
261 uc_pdata->data_format = ADC_DATA_FORMAT_BIN;
262 uc_pdata->data_timeout_us = IMX93_ADC_TIMEOUT;
263
264 /* Mask available channel bits: [0:3] */
265 uc_pdata->channel_mask = (2 << IMX93_ADC_MAX_CHANNEL) - 1;
266
267 return 0;
268}
269
270static const struct adc_ops imx93_adc_ops = {
271 .start_channel = imx93_adc_start_channel,
272 .channel_data = imx93_adc_channel_data,
273 .stop = imx93_adc_stop,
274};
275
276static const struct udevice_id imx93_adc_ids[] = {
277 { .compatible = "nxp,imx93-adc" },
278 { }
279};
280
281U_BOOT_DRIVER(imx93_adc) = {
282 .name = "imx93-adc",
283 .id = UCLASS_ADC,
284 .of_match = imx93_adc_ids,
285 .ops = &imx93_adc_ops,
286 .probe = imx93_adc_probe,
287 .of_to_plat = imx93_adc_of_to_plat,
288 .priv_auto = sizeof(struct imx93_adc_priv),
289};