• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Rockchip Successive Approximation Register (SAR) A/D Converter
4  * Copyright (C) 2014 ROCKCHIP, Inc.
5  */
6 
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
9 #include <linux/interrupt.h>
10 #include <linux/io.h>
11 #include <linux/of.h>
12 #include <linux/of_device.h>
13 #include <linux/clk.h>
14 #include <linux/completion.h>
15 #include <linux/delay.h>
16 #include <linux/reset.h>
17 #include <linux/regulator/consumer.h>
18 #include <linux/iio/buffer.h>
19 #include <linux/iio/iio.h>
20 #include <linux/iio/trigger_consumer.h>
21 #include <linux/iio/triggered_buffer.h>
22 
23 #define SARADC_DATA 0x00
24 
25 #define SARADC_STAS 0x04
26 #define SARADC_STAS_BUSY BIT(0)
27 
28 #define SARADC_CTRL 0x08
29 #define SARADC_CTRL_IRQ_STATUS BIT(6)
30 #define SARADC_CTRL_IRQ_ENABLE BIT(5)
31 #define SARADC_CTRL_POWER_CTRL BIT(3)
32 #define SARADC_CTRL_CHN_MASK 0x7
33 
34 #define SARADC_DLY_PU_SOC 0x0c
35 #define SARADC_DLY_PU_SOC_MASK 0x3f
36 
37 #define SARADC_TIMEOUT msecs_to_jiffies(100)
38 #define SARADC_MAX_CHANNELS 4
39 
40 struct rockchip_saradc_data {
41     const struct iio_chan_spec *channels;
42     int num_channels;
43     unsigned long clk_rate;
44 };
45 
46 struct rockchip_saradc {
47     void __iomem *regs;
48     struct clk *pclk;
49     struct clk *clk;
50     struct completion completion;
51     struct regulator *vref;
52     int uv_vref;
53     struct reset_control *reset;
54     const struct rockchip_saradc_data *data;
55     u16 last_val;
56     const struct iio_chan_spec *last_chan;
57 #ifdef CONFIG_ROCKCHIP_SARADC_TEST_CHN
58     struct timer_list timer;
59     bool test;
60     u32 chn;
61     spinlock_t lock;
62 #endif
63 };
64 
rockchip_saradc_power_down(struct rockchip_saradc * info)65 static void rockchip_saradc_power_down(struct rockchip_saradc *info)
66 {
67     /* Clear irq & power down adc */
68     writel_relaxed(0, info->regs + SARADC_CTRL);
69 }
70 
rockchip_saradc_conversion(struct rockchip_saradc * info,struct iio_chan_spec const * chan)71 static int rockchip_saradc_conversion(struct rockchip_saradc *info, struct iio_chan_spec const *chan)
72 {
73     reinit_completion(&info->completion);
74 
75     /* 8 clock periods as delay between power up and start cmd */
76     writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC);
77 
78     info->last_chan = chan;
79 
80     /* Select the channel to be used and trigger conversion */
81     writel(SARADC_CTRL_POWER_CTRL | (chan->channel & SARADC_CTRL_CHN_MASK) | SARADC_CTRL_IRQ_ENABLE,
82            info->regs + SARADC_CTRL);
83 
84     if (!wait_for_completion_timeout(&info->completion, SARADC_TIMEOUT)) {
85         return -ETIMEDOUT;
86     }
87 
88     return 0;
89 }
90 
rockchip_saradc_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)91 static int rockchip_saradc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2,
92                                     long mask)
93 {
94     struct rockchip_saradc *info = iio_priv(indio_dev);
95     int ret;
96 
97 #ifdef CONFIG_ROCKCHIP_SARADC_TEST_CHN
98     if (info->test) {
99         return 0;
100     }
101 #endif
102     switch (mask) {
103         case IIO_CHAN_INFO_RAW:
104             mutex_lock(&indio_dev->mlock);
105 
106             ret = rockchip_saradc_conversion(info, chan);
107             if (ret) {
108                 rockchip_saradc_power_down(info);
109                 mutex_unlock(&indio_dev->mlock);
110                 return ret;
111             }
112 
113             *val = info->last_val;
114             mutex_unlock(&indio_dev->mlock);
115             return IIO_VAL_INT;
116         case IIO_CHAN_INFO_SCALE:
117             /* It is a dummy regulator */
118             if (info->uv_vref < 0) {
119                 return info->uv_vref;
120             }
121 
122             *val = info->uv_vref / 0x3E8;
123             *val2 = chan->scan_type.realbits;
124             return IIO_VAL_FRACTIONAL_LOG2;
125         default:
126             return -EINVAL;
127     }
128 }
129 
rockchip_saradc_isr(int irq,void * dev_id)130 static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id)
131 {
132     struct rockchip_saradc *info = dev_id;
133 #ifdef CONFIG_ROCKCHIP_SARADC_TEST_CHN
134     unsigned long flags;
135 #endif
136 
137     /* Read value */
138     info->last_val = readl_relaxed(info->regs + SARADC_DATA);
139     info->last_val &= GENMASK(info->last_chan->scan_type.realbits - 1, 0);
140 
141     rockchip_saradc_power_down(info);
142 
143     complete(&info->completion);
144 #ifdef CONFIG_ROCKCHIP_SARADC_TEST_CHN
145     spin_lock_irqsave(&info->lock, flags);
146     if (info->test) {
147         pr_info("chn[%d] val = %d\n", info->chn, info->last_val);
148         mod_timer(&info->timer, jiffies + HZ / 0x3E8);
149     }
150     spin_unlock_irqrestore(&info->lock, flags);
151 #endif
152     return IRQ_HANDLED;
153 }
154 
155 static const struct iio_info rockchip_saradc_iio_info = {
156     .read_raw = rockchip_saradc_read_raw,
157 };
158 
159 #define SARADC_CHANNEL(index, id, res)                                                                                 \
160     {                                                                                                                  \
161         .type = IIO_VOLTAGE, .indexed = 1, .channel = index, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),             \
162         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), .datasheet_name = id, .scan_index = index,               \
163         .scan_type = {                                                                                                 \
164             .sign = 'u',                                                                                               \
165             .realbits = res,                                                                                           \
166             .storagebits = 16,                                                                                         \
167             .endianness = IIO_CPU,                                                                                     \
168         },                                                                                                             \
169     }
170 
171 static const struct iio_chan_spec rockchip_saradc_iio_channels[] = {
172     SARADC_CHANNEL(0, "adc0", 10),
173     SARADC_CHANNEL(1, "adc1", 10),
174     SARADC_CHANNEL(2, "adc2", 10),
175 };
176 
177 static const struct rockchip_saradc_data saradc_data = {
178     .channels = rockchip_saradc_iio_channels,
179     .num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels),
180     .clk_rate = 1000000,
181 };
182 
183 static const struct iio_chan_spec rockchip_rk3066_tsadc_iio_channels[] = {
184     SARADC_CHANNEL(0, "adc0", 12),
185     SARADC_CHANNEL(1, "adc1", 12),
186 };
187 
188 static const struct rockchip_saradc_data rk3066_tsadc_data = {
189     .channels = rockchip_rk3066_tsadc_iio_channels,
190     .num_channels = ARRAY_SIZE(rockchip_rk3066_tsadc_iio_channels),
191     .clk_rate = 50000,
192 };
193 
194 static const struct iio_chan_spec rockchip_rk3399_saradc_iio_channels[] = {
195     SARADC_CHANNEL(0, "adc0", 10), SARADC_CHANNEL(1, "adc1", 10), SARADC_CHANNEL(2, "adc2", 10),
196     SARADC_CHANNEL(3, "adc3", 10), SARADC_CHANNEL(4, "adc4", 10), SARADC_CHANNEL(5, "adc5", 10),
197 };
198 
199 static const struct rockchip_saradc_data rk3399_saradc_data = {
200     .channels = rockchip_rk3399_saradc_iio_channels,
201     .num_channels = ARRAY_SIZE(rockchip_rk3399_saradc_iio_channels),
202     .clk_rate = 1000000,
203 };
204 
205 static const struct iio_chan_spec rockchip_rk3568_saradc_iio_channels[] = {
206     SARADC_CHANNEL(0, "adc0", 10), SARADC_CHANNEL(1, "adc1", 10), SARADC_CHANNEL(2, "adc2", 10),
207     SARADC_CHANNEL(3, "adc3", 10), SARADC_CHANNEL(4, "adc4", 10), SARADC_CHANNEL(5, "adc5", 10),
208     SARADC_CHANNEL(6, "adc6", 10), SARADC_CHANNEL(7, "adc7", 10),
209 };
210 
211 static const struct rockchip_saradc_data rk3568_saradc_data = {
212     .channels = rockchip_rk3568_saradc_iio_channels,
213     .num_channels = ARRAY_SIZE(rockchip_rk3568_saradc_iio_channels),
214     .clk_rate = 1000000,
215 };
216 
217 static const struct of_device_id rockchip_saradc_match[] = {
218     {
219         .compatible = "rockchip,saradc",
220         .data = &saradc_data,
221     },
222     {
223         .compatible = "rockchip,rk3066-tsadc",
224         .data = &rk3066_tsadc_data,
225     },
226     {
227         .compatible = "rockchip,rk3399-saradc",
228         .data = &rk3399_saradc_data,
229     },
230     {
231         .compatible = "rockchip,rk3568-saradc",
232         .data = &rk3568_saradc_data,
233     },
234     {},
235 };
236 MODULE_DEVICE_TABLE(of, rockchip_saradc_match);
237 
238 /*
239  * Reset SARADC Controller.
240  */
rockchip_saradc_reset_controller(struct reset_control * reset)241 static void rockchip_saradc_reset_controller(struct reset_control *reset)
242 {
243     reset_control_assert(reset);
244     usleep_range(0xa, 0x14);
245     reset_control_deassert(reset);
246 }
247 
rockchip_saradc_clk_disable(void * data)248 static void rockchip_saradc_clk_disable(void *data)
249 {
250     struct rockchip_saradc *info = data;
251 
252     clk_disable_unprepare(info->clk);
253 }
254 
rockchip_saradc_pclk_disable(void * data)255 static void rockchip_saradc_pclk_disable(void *data)
256 {
257     struct rockchip_saradc *info = data;
258 
259     clk_disable_unprepare(info->pclk);
260 }
261 
rockchip_saradc_regulator_disable(void * data)262 static void rockchip_saradc_regulator_disable(void *data)
263 {
264     struct rockchip_saradc *info = data;
265 
266     regulator_disable(info->vref);
267 }
268 
rockchip_saradc_trigger_handler(int irq,void * p)269 static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p)
270 {
271     struct iio_poll_func *pf = p;
272     struct iio_dev *i_dev = pf->indio_dev;
273     struct rockchip_saradc *info = iio_priv(i_dev);
274     /*
275      * @values: each channel takes an u16 value
276      * @timestamp: will be 8-byte aligned automatically
277      */
278     struct {
279         u16 values[SARADC_MAX_CHANNELS];
280         int64_t timestamp;
281     } data;
282     int ret;
283     int i, j = 0;
284 
285     mutex_lock(&i_dev->mlock);
286 
287     for_each_set_bit(i, i_dev->active_scan_mask, i_dev->masklength)
288     {
289         const struct iio_chan_spec *chan = &i_dev->channels[i];
290 
291         ret = rockchip_saradc_conversion(info, chan);
292         if (ret) {
293             rockchip_saradc_power_down(info);
294             goto out;
295         }
296 
297         data.values[j] = info->last_val;
298         j++;
299     }
300 
301     iio_push_to_buffers_with_timestamp(i_dev, &data, iio_get_time_ns(i_dev));
302 out:
303     mutex_unlock(&i_dev->mlock);
304 
305     iio_trigger_notify_done(i_dev->trig);
306 
307     return IRQ_HANDLED;
308 }
309 
310 #ifdef CONFIG_ROCKCHIP_SARADC_TEST_CHN
rockchip_saradc_timer(struct timer_list * t)311 static void rockchip_saradc_timer(struct timer_list *t)
312 {
313     struct rockchip_saradc *info = from_timer(info, t, timer);
314 
315     /* 8 clock periods as delay between power up and start cmd */
316     writel_relaxed(0x8, info->regs + SARADC_DLY_PU_SOC);
317 
318     /* Select the channel to be used and trigger conversion */
319     writel(SARADC_CTRL_POWER_CTRL | (info->chn & SARADC_CTRL_CHN_MASK) | SARADC_CTRL_IRQ_ENABLE,
320            info->regs + SARADC_CTRL);
321 }
322 
saradc_test_chn_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)323 static ssize_t saradc_test_chn_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
324 {
325     u32 val = 0;
326     int err;
327     struct iio_dev *indio_dev = dev_get_drvdata(dev);
328     struct rockchip_saradc *info = iio_priv(indio_dev);
329     unsigned long flags;
330 
331     err = kstrtou32(buf, 0xa, &val);
332     if (err) {
333         return err;
334     }
335 
336     spin_lock_irqsave(&info->lock, flags);
337 
338     if (val > SARADC_CTRL_CHN_MASK && info->test) {
339         info->test = false;
340         del_timer_sync(&info->timer);
341         spin_unlock_irqrestore(&info->lock, flags);
342         return size;
343     }
344 
345     if (!info->test && val < SARADC_CTRL_CHN_MASK) {
346         info->test = true;
347         info->chn = val;
348         mod_timer(&info->timer, jiffies + HZ / 0x3E8);
349     }
350 
351     spin_unlock_irqrestore(&info->lock, flags);
352 
353     return size;
354 }
355 
356 static DEVICE_ATTR_WO(saradc_test_chn);
357 
358 static struct attribute *saradc_attrs[] = {&dev_attr_saradc_test_chn.attr, NULL};
359 
360 static const struct attribute_group rockchip_saradc_attr_group = {
361     .attrs = saradc_attrs,
362 };
363 
rockchip_saradc_remove_sysgroup(void * data)364 static void rockchip_saradc_remove_sysgroup(void *data)
365 {
366     struct platform_device *pdev = data;
367 
368     sysfs_remove_group(&pdev->dev.kobj, &rockchip_saradc_attr_group);
369 }
370 #endif
371 
rockchip_saradc_probe(struct platform_device * pdev)372 static int rockchip_saradc_probe(struct platform_device *pdev)
373 {
374     struct rockchip_saradc *info = NULL;
375     struct device_node *np = pdev->dev.of_node;
376     struct iio_dev *indio_dev = NULL;
377     struct resource *mem;
378     const struct of_device_id *match;
379     int ret;
380     int irq;
381 
382     if (!np) {
383         return -ENODEV;
384     }
385 
386     indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
387     if (!indio_dev) {
388         dev_err(&pdev->dev, "failed allocating iio device\n");
389         return -ENOMEM;
390     }
391     info = iio_priv(indio_dev);
392 
393     match = of_match_device(rockchip_saradc_match, &pdev->dev);
394     if (!match) {
395         dev_err(&pdev->dev, "failed to match device\n");
396         return -ENODEV;
397     }
398 
399     info->data = match->data;
400 
401     /* Sanity check for possible later IP variants with more channels */
402     if (info->data->num_channels > SARADC_MAX_CHANNELS) {
403         dev_err(&pdev->dev, "max channels exceeded");
404         return -EINVAL;
405     }
406 
407     mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
408     info->regs = devm_ioremap_resource(&pdev->dev, mem);
409     if (IS_ERR(info->regs)) {
410         return PTR_ERR(info->regs);
411     }
412 
413     /*
414      * The reset should be an optional property, as it should work
415      * with old devicetrees as well
416      */
417     info->reset = devm_reset_control_get_exclusive(&pdev->dev, "saradc-apb");
418     if (IS_ERR(info->reset)) {
419         ret = PTR_ERR(info->reset);
420         if (ret != -ENOENT) {
421             return ret;
422         }
423 
424         dev_dbg(&pdev->dev, "no reset control found\n");
425         info->reset = NULL;
426     }
427 
428     init_completion(&info->completion);
429 
430     irq = platform_get_irq(pdev, 0);
431     if (irq < 0) {
432         return irq;
433     }
434 
435     ret = devm_request_irq(&pdev->dev, irq, rockchip_saradc_isr, 0, dev_name(&pdev->dev), info);
436     if (ret < 0) {
437         dev_err(&pdev->dev, "failed requesting irq %d\n", irq);
438         return ret;
439     }
440 
441     info->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
442     if (IS_ERR(info->pclk)) {
443         dev_err(&pdev->dev, "failed to get pclk\n");
444         return PTR_ERR(info->pclk);
445     }
446 
447     info->clk = devm_clk_get(&pdev->dev, "saradc");
448     if (IS_ERR(info->clk)) {
449         dev_err(&pdev->dev, "failed to get adc clock\n");
450         return PTR_ERR(info->clk);
451     }
452 
453     info->vref = devm_regulator_get(&pdev->dev, "vref");
454     if (IS_ERR(info->vref)) {
455         dev_err(&pdev->dev, "failed to get regulator, %ld\n", PTR_ERR(info->vref));
456         return PTR_ERR(info->vref);
457     }
458 
459     if (info->reset) {
460         rockchip_saradc_reset_controller(info->reset);
461     }
462 
463     /*
464      * Use a default value for the converter clock.
465      * This may become user-configurable in the future.
466      */
467     ret = clk_set_rate(info->clk, info->data->clk_rate);
468     if (ret < 0) {
469         dev_err(&pdev->dev, "failed to set adc clk rate, %d\n", ret);
470         return ret;
471     }
472 
473     ret = regulator_enable(info->vref);
474     if (ret < 0) {
475         dev_err(&pdev->dev, "failed to enable vref regulator\n");
476         return ret;
477     }
478     ret = devm_add_action_or_reset(&pdev->dev, rockchip_saradc_regulator_disable, info);
479     if (ret) {
480         dev_err(&pdev->dev, "failed to register devm action, %d\n", ret);
481         return ret;
482     }
483 
484     info->uv_vref = regulator_get_voltage(info->vref);
485     if (info->uv_vref < 0) {
486         dev_err(&pdev->dev, "failed to get voltage\n");
487         ret = info->uv_vref;
488         return ret;
489     }
490 
491     ret = clk_prepare_enable(info->pclk);
492     if (ret < 0) {
493         dev_err(&pdev->dev, "failed to enable pclk\n");
494         return ret;
495     }
496     ret = devm_add_action_or_reset(&pdev->dev, rockchip_saradc_pclk_disable, info);
497     if (ret) {
498         dev_err(&pdev->dev, "failed to register devm action, %d\n", ret);
499         return ret;
500     }
501 
502     ret = clk_prepare_enable(info->clk);
503     if (ret < 0) {
504         dev_err(&pdev->dev, "failed to enable converter clock\n");
505         return ret;
506     }
507     ret = devm_add_action_or_reset(&pdev->dev, rockchip_saradc_clk_disable, info);
508     if (ret) {
509         dev_err(&pdev->dev, "failed to register devm action, %d\n", ret);
510         return ret;
511     }
512 
513     platform_set_drvdata(pdev, indio_dev);
514 
515     indio_dev->name = dev_name(&pdev->dev);
516     indio_dev->info = &rockchip_saradc_iio_info;
517     indio_dev->modes = INDIO_DIRECT_MODE;
518 
519     indio_dev->channels = info->data->channels;
520     indio_dev->num_channels = info->data->num_channels;
521     ret = devm_iio_triggered_buffer_setup(&indio_dev->dev, indio_dev, NULL, rockchip_saradc_trigger_handler, NULL);
522     if (ret) {
523         return ret;
524     }
525 
526 #ifdef CONFIG_ROCKCHIP_SARADC_TEST_CHN
527     spin_lock_init(&info->lock);
528     timer_setup(&info->timer, rockchip_saradc_timer, 0);
529     ret = sysfs_create_group(&pdev->dev.kobj, &rockchip_saradc_attr_group);
530     if (ret) {
531         return ret;
532     }
533 
534     ret = devm_add_action_or_reset(&pdev->dev, rockchip_saradc_remove_sysgroup, pdev);
535     if (ret) {
536         dev_err(&pdev->dev, "failed to register devm action, %d\n", ret);
537         return ret;
538     }
539 #endif
540     return devm_iio_device_register(&pdev->dev, indio_dev);
541 }
542 
543 #ifdef CONFIG_PM_SLEEP
rockchip_saradc_suspend(struct device * dev)544 static int rockchip_saradc_suspend(struct device *dev)
545 {
546     struct iio_dev *indio_dev = dev_get_drvdata(dev);
547     struct rockchip_saradc *info = iio_priv(indio_dev);
548 
549     clk_disable_unprepare(info->clk);
550     clk_disable_unprepare(info->pclk);
551     regulator_disable(info->vref);
552 
553     return 0;
554 }
555 
rockchip_saradc_resume(struct device * dev)556 static int rockchip_saradc_resume(struct device *dev)
557 {
558     struct iio_dev *indio_dev = dev_get_drvdata(dev);
559     struct rockchip_saradc *info = iio_priv(indio_dev);
560     int ret;
561 
562     ret = regulator_enable(info->vref);
563     if (ret) {
564         return ret;
565     }
566 
567     ret = clk_prepare_enable(info->pclk);
568     if (ret) {
569         return ret;
570     }
571 
572     ret = clk_prepare_enable(info->clk);
573     if (ret) {
574         clk_disable_unprepare(info->pclk);
575     }
576 
577     return ret;
578 }
579 #endif
580 
581 static SIMPLE_DEV_PM_OPS(rockchip_saradc_pm_ops, rockchip_saradc_suspend, rockchip_saradc_resume);
582 
583 static struct platform_driver rockchip_saradc_driver = {
584     .probe = rockchip_saradc_probe,
585     .driver =
586         {
587             .name = "rockchip-saradc",
588             .of_match_table = rockchip_saradc_match,
589             .pm = &rockchip_saradc_pm_ops,
590         },
591 };
592 
593 module_platform_driver(rockchip_saradc_driver);
594 
595 MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
596 MODULE_DESCRIPTION("Rockchip SARADC driver");
597 MODULE_LICENSE("GPL v2");
598