]> Git Repo - J-u-boot.git/blob - drivers/adc/rockchip-saradc.c
Restore patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet"
[J-u-boot.git] / drivers / adc / rockchip-saradc.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2017, Fuzhou Rockchip Electronics Co., Ltd
4  *
5  * Rockchip SARADC driver for U-Boot
6  */
7
8 #include <adc.h>
9 #include <clk.h>
10 #include <dm.h>
11 #include <errno.h>
12 #include <reset.h>
13 #include <asm/arch-rockchip/hardware.h>
14 #include <linux/bitfield.h>
15 #include <linux/bitops.h>
16 #include <linux/delay.h>
17 #include <linux/err.h>
18 #include <linux/printk.h>
19 #include <power/regulator.h>
20
21 #define usleep_range(a, b) udelay((b))
22
23 #define SARADC_CTRL_CHN_MASK            GENMASK(2, 0)
24 #define SARADC_CTRL_POWER_CTRL          BIT(3)
25 #define SARADC_CTRL_IRQ_ENABLE          BIT(5)
26 #define SARADC_CTRL_IRQ_STATUS          BIT(6)
27
28 #define SARADC_TIMEOUT                  (100 * 1000)
29
30 struct rockchip_saradc_regs_v1 {
31         unsigned int data;
32         unsigned int stas;
33         unsigned int ctrl;
34         unsigned int dly_pu_soc;
35 };
36
37 struct rockchip_saradc_regs_v2 {
38         unsigned int conv_con;
39 #define SARADC2_SINGLE_MODE     BIT(5)
40 #define SARADC2_START           BIT(4)
41 #define SARADC2_CONV_CHANNELS   GENMASK(3, 0)
42         unsigned int t_pd_soc;
43         unsigned int t_as_soc;
44         unsigned int t_das_soc;
45         unsigned int t_sel_soc;
46         unsigned int high_comp[16];
47         unsigned int low_comp[16];
48         unsigned int debounce;
49         unsigned int ht_int_en;
50         unsigned int lt_int_en;
51         unsigned int reserved[24];
52         unsigned int mt_int_en;
53         unsigned int end_int_en;
54 #define SARADC2_EN_END_INT      BIT(0)
55         unsigned int st_con;
56         unsigned int status;
57         unsigned int end_int_st;
58         unsigned int ht_int_st;
59         unsigned int lt_int_st;
60         unsigned int mt_int_st;
61         unsigned int data[16];
62         unsigned int auto_ch_en;
63 };
64
65 union rockchip_saradc_regs {
66         struct rockchip_saradc_regs_v1  *v1;
67         struct rockchip_saradc_regs_v2  *v2;
68 };
69 struct rockchip_saradc_data {
70         int                             num_bits;
71         int                             num_channels;
72         unsigned long                   clk_rate;
73         int (*channel_data)(struct udevice *dev, int channel, unsigned int *data);
74         int (*start_channel)(struct udevice *dev, int channel);
75         int (*stop)(struct udevice *dev);
76 };
77
78 struct rockchip_saradc_priv {
79         union rockchip_saradc_regs              regs;
80         int                                     active_channel;
81         const struct rockchip_saradc_data       *data;
82         struct reset_ctl                        *reset;
83 };
84
85 int rockchip_saradc_channel_data_v1(struct udevice *dev, int channel,
86                                     unsigned int *data)
87 {
88         struct rockchip_saradc_priv *priv = dev_get_priv(dev);
89
90         if ((readl(&priv->regs.v1->ctrl) & SARADC_CTRL_IRQ_STATUS) !=
91             SARADC_CTRL_IRQ_STATUS)
92                 return -EBUSY;
93
94         /* Read value */
95         *data = readl(&priv->regs.v1->data);
96
97         /* Power down adc */
98         writel(0, &priv->regs.v1->ctrl);
99
100         return 0;
101 }
102
103 int rockchip_saradc_channel_data_v2(struct udevice *dev, int channel,
104                                     unsigned int *data)
105 {
106         struct rockchip_saradc_priv *priv = dev_get_priv(dev);
107
108         if (!(readl(&priv->regs.v2->end_int_st) & SARADC2_EN_END_INT))
109                 return -EBUSY;
110
111         /* Read value */
112         *data = readl(&priv->regs.v2->data[channel]);
113
114         /* Acknowledge the interrupt */
115         writel(SARADC2_EN_END_INT, &priv->regs.v2->end_int_st);
116
117         return 0;
118 }
119 int rockchip_saradc_channel_data(struct udevice *dev, int channel,
120                                  unsigned int *data)
121 {
122         struct rockchip_saradc_priv *priv = dev_get_priv(dev);
123         struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
124         int ret;
125
126         if (channel != priv->active_channel) {
127                 pr_err("Requested channel is not active!");
128                 return -EINVAL;
129         }
130
131         ret = priv->data->channel_data(dev, channel, data);
132         if (ret) {
133                 if (ret != -EBUSY)
134                         pr_err("Error reading channel data, %d!", ret);
135                 return ret;
136         }
137
138         *data &= uc_pdata->data_mask;
139
140         return 0;
141 }
142
143 int rockchip_saradc_start_channel_v1(struct udevice *dev, int channel)
144 {
145         struct rockchip_saradc_priv *priv = dev_get_priv(dev);
146
147         /* 8 clock periods as delay between power up and start cmd */
148         writel(8, &priv->regs.v1->dly_pu_soc);
149
150         /* Select the channel to be used and trigger conversion */
151         writel(SARADC_CTRL_POWER_CTRL | (channel & SARADC_CTRL_CHN_MASK) |
152                SARADC_CTRL_IRQ_ENABLE, &priv->regs.v1->ctrl);
153
154         return 0;
155 }
156
157 static void rockchip_saradc_reset_controller(struct reset_ctl *reset)
158 {
159         reset_assert(reset);
160         usleep_range(10, 20);
161         reset_deassert(reset);
162 }
163
164 int rockchip_saradc_start_channel_v2(struct udevice *dev, int channel)
165 {
166         struct rockchip_saradc_priv *priv = dev_get_priv(dev);
167
168         /*
169          * Downstream says
170          * """If read other chn at anytime, then chn1 will error, assert
171          * controller as a workaround."""
172          */
173         if (priv->reset)
174                 rockchip_saradc_reset_controller(priv->reset);
175
176         writel(0xc, &priv->regs.v2->t_das_soc);
177         writel(0x20, &priv->regs.v2->t_pd_soc);
178
179         /* Acknowledge any previous interrupt */
180         writel(SARADC2_EN_END_INT, &priv->regs.v2->end_int_st);
181
182         rk_clrsetreg(&priv->regs.v2->conv_con,
183                      SARADC2_CONV_CHANNELS | SARADC2_START | SARADC2_SINGLE_MODE,
184                      FIELD_PREP(SARADC2_CONV_CHANNELS, channel) |
185                      FIELD_PREP(SARADC2_START, 1) |
186                      FIELD_PREP(SARADC2_SINGLE_MODE, 1));
187
188         return 0;
189 }
190
191 int rockchip_saradc_start_channel(struct udevice *dev, int channel)
192 {
193         struct rockchip_saradc_priv *priv = dev_get_priv(dev);
194         int ret;
195
196         if (channel < 0 || channel >= priv->data->num_channels) {
197                 pr_err("Requested channel is invalid!");
198                 return -EINVAL;
199         }
200
201         ret = priv->data->start_channel(dev, channel);
202         if (ret) {
203                 pr_err("Error starting channel, %d!", ret);
204                 return ret;
205         }
206
207         priv->active_channel = channel;
208
209         return 0;
210 }
211
212 int rockchip_saradc_stop_v1(struct udevice *dev)
213 {
214         struct rockchip_saradc_priv *priv = dev_get_priv(dev);
215
216         /* Power down adc */
217         writel(0, &priv->regs.v1->ctrl);
218
219         return 0;
220 }
221
222 int rockchip_saradc_stop(struct udevice *dev)
223 {
224         struct rockchip_saradc_priv *priv = dev_get_priv(dev);
225
226         if (priv->data->stop) {
227                 int ret = priv->data->stop(dev);
228
229                 if (ret) {
230                         pr_err("Error stopping channel, %d!", ret);
231                         return ret;
232                 }
233         }
234
235         priv->active_channel = -1;
236
237         return 0;
238 }
239
240 int rockchip_saradc_probe(struct udevice *dev)
241 {
242         struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
243         struct rockchip_saradc_priv *priv = dev_get_priv(dev);
244         struct udevice *vref;
245         struct clk clk;
246         int vref_uv;
247         int ret;
248
249         priv->reset = devm_reset_control_get_optional(dev, "saradc-apb");
250
251         ret = clk_get_by_index(dev, 0, &clk);
252         if (ret)
253                 return ret;
254
255         ret = clk_set_rate(&clk, priv->data->clk_rate);
256         if (IS_ERR_VALUE(ret))
257                 return ret;
258
259         priv->active_channel = -1;
260
261         ret = device_get_supply_regulator(dev, "vref-supply", &vref);
262         if (ret) {
263                 printf("can't get vref-supply: %d\n", ret);
264                 return ret;
265         }
266
267         if (priv->reset)
268                 rockchip_saradc_reset_controller(priv->reset);
269
270         vref_uv = regulator_get_value(vref);
271         if (vref_uv < 0) {
272                 printf("can't get vref-supply value: %d\n", vref_uv);
273                 return vref_uv;
274         }
275
276         /* VDD supplied by common vref pin */
277         uc_pdata->vdd_supply = vref;
278         uc_pdata->vdd_microvolts = vref_uv;
279         uc_pdata->vss_microvolts = 0;
280
281         return 0;
282 }
283
284 int rockchip_saradc_of_to_plat(struct udevice *dev)
285 {
286         struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
287         struct rockchip_saradc_priv *priv = dev_get_priv(dev);
288         struct rockchip_saradc_data *data;
289
290         data = (struct rockchip_saradc_data *)dev_get_driver_data(dev);
291         priv->regs.v1 = dev_read_addr_ptr(dev);
292         if (!priv->regs.v1) {
293                 pr_err("Dev: %s - can't get address!", dev->name);
294                 return -EINVAL;
295         }
296
297         priv->data = data;
298         uc_pdata->data_mask = (1 << priv->data->num_bits) - 1;
299         uc_pdata->data_format = ADC_DATA_FORMAT_BIN;
300         uc_pdata->data_timeout_us = SARADC_TIMEOUT / 5;
301         uc_pdata->channel_mask = (1 << priv->data->num_channels) - 1;
302
303         return 0;
304 }
305
306 static const struct adc_ops rockchip_saradc_ops = {
307         .start_channel = rockchip_saradc_start_channel,
308         .channel_data = rockchip_saradc_channel_data,
309         .stop = rockchip_saradc_stop,
310 };
311
312 static const struct rockchip_saradc_data saradc_data = {
313         .num_bits = 10,
314         .num_channels = 3,
315         .clk_rate = 1000000,
316         .channel_data = rockchip_saradc_channel_data_v1,
317         .start_channel = rockchip_saradc_start_channel_v1,
318         .stop = rockchip_saradc_stop_v1,
319 };
320
321 static const struct rockchip_saradc_data rk3066_tsadc_data = {
322         .num_bits = 12,
323         .num_channels = 2,
324         .clk_rate = 50000,
325         .channel_data = rockchip_saradc_channel_data_v1,
326         .start_channel = rockchip_saradc_start_channel_v1,
327         .stop = rockchip_saradc_stop_v1,
328 };
329
330 static const struct rockchip_saradc_data rk3399_saradc_data = {
331         .num_bits = 10,
332         .num_channels = 6,
333         .clk_rate = 1000000,
334         .channel_data = rockchip_saradc_channel_data_v1,
335         .start_channel = rockchip_saradc_start_channel_v1,
336         .stop = rockchip_saradc_stop_v1,
337 };
338
339 static const struct rockchip_saradc_data rk3588_saradc_data = {
340         .num_bits = 12,
341         .num_channels = 8,
342         .clk_rate = 1000000,
343         .channel_data = rockchip_saradc_channel_data_v2,
344         .start_channel = rockchip_saradc_start_channel_v2,
345 };
346
347 static const struct udevice_id rockchip_saradc_ids[] = {
348         { .compatible = "rockchip,saradc",
349           .data = (ulong)&saradc_data },
350         { .compatible = "rockchip,rk3066-tsadc",
351           .data = (ulong)&rk3066_tsadc_data },
352         { .compatible = "rockchip,rk3399-saradc",
353           .data = (ulong)&rk3399_saradc_data },
354         { .compatible = "rockchip,rk3588-saradc",
355           .data = (ulong)&rk3588_saradc_data },
356         { }
357 };
358
359 U_BOOT_DRIVER(rockchip_saradc) = {
360         .name           = "rockchip_saradc",
361         .id             = UCLASS_ADC,
362         .of_match       = rockchip_saradc_ids,
363         .ops            = &rockchip_saradc_ops,
364         .probe          = rockchip_saradc_probe,
365         .of_to_plat = rockchip_saradc_of_to_plat,
366         .priv_auto      = sizeof(struct rockchip_saradc_priv),
367 };
This page took 0.045498 seconds and 4 git commands to generate.