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