]> Git Repo - u-boot.git/blob - drivers/adc/imx93-adc.c
Merge tag 'v2023.10-rc4' into next
[u-boot.git] / drivers / adc / imx93-adc.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2023 ASEM Srl
4  * Author: Luca Ellero <[email protected]>
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
62 struct imx93_adc_priv {
63         int active_channel;
64         void __iomem *regs;
65         struct clk ipg_clk;
66 };
67
68 static 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
83 static 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
93 static 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
109 static 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
153 static 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
183 static 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
211 static 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
222 static 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
238 static 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
271 static 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
277 static const struct udevice_id imx93_adc_ids[] = {
278         { .compatible = "nxp,imx93-adc" },
279         { }
280 };
281
282 U_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 };
This page took 0.04289 seconds and 4 git commands to generate.