1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Driver for ADC module on the Cirrus Logic EP93xx series of SoCs |
4 | * |
5 | * Copyright (C) 2015 Alexander Sverdlin |
6 | * |
7 | * The driver uses polling to get the conversion status. According to EP93xx |
8 | * datasheets, reading ADCResult register starts the conversion, but user is also |
9 | * responsible for ensuring that delay between adjacent conversion triggers is |
10 | * long enough so that maximum allowed conversion rate is not exceeded. This |
11 | * basically renders IRQ mode unusable. |
12 | */ |
13 | |
14 | #include <linux/clk.h> |
15 | #include <linux/delay.h> |
16 | #include <linux/device.h> |
17 | #include <linux/err.h> |
18 | #include <linux/iio/iio.h> |
19 | #include <linux/io.h> |
20 | #include <linux/irqflags.h> |
21 | #include <linux/module.h> |
22 | #include <linux/mutex.h> |
23 | #include <linux/platform_device.h> |
24 | #include <linux/of.h> |
25 | |
26 | /* |
27 | * This code could benefit from real HR Timers, but jiffy granularity would |
28 | * lower ADC conversion rate down to CONFIG_HZ, so we fallback to busy wait |
29 | * in such case. |
30 | * |
31 | * HR Timers-based version loads CPU only up to 10% during back to back ADC |
32 | * conversion, while busy wait-based version consumes whole CPU power. |
33 | */ |
34 | #ifdef CONFIG_HIGH_RES_TIMERS |
35 | #define ep93xx_adc_delay(usmin, usmax) usleep_range(usmin, usmax) |
36 | #else |
37 | #define ep93xx_adc_delay(usmin, usmax) udelay(usmin) |
38 | #endif |
39 | |
40 | #define EP93XX_ADC_RESULT 0x08 |
41 | #define EP93XX_ADC_SDR BIT(31) |
42 | #define EP93XX_ADC_SWITCH 0x18 |
43 | #define EP93XX_ADC_SW_LOCK 0x20 |
44 | |
45 | struct ep93xx_adc_priv { |
46 | struct clk *clk; |
47 | void __iomem *base; |
48 | int lastch; |
49 | struct mutex lock; |
50 | }; |
51 | |
52 | #define EP93XX_ADC_CH(index, dname, swcfg) { \ |
53 | .type = IIO_VOLTAGE, \ |
54 | .indexed = 1, \ |
55 | .channel = index, \ |
56 | .address = swcfg, \ |
57 | .datasheet_name = dname, \ |
58 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
59 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE) | \ |
60 | BIT(IIO_CHAN_INFO_OFFSET), \ |
61 | } |
62 | |
63 | /* |
64 | * Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets. |
65 | * EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is |
66 | * not defined. So the last three are numbered randomly, let's say. |
67 | */ |
68 | static const struct iio_chan_spec ep93xx_adc_channels[8] = { |
69 | EP93XX_ADC_CH(0, "YM" , 0x608), |
70 | EP93XX_ADC_CH(1, "SXP" , 0x680), |
71 | EP93XX_ADC_CH(2, "SXM" , 0x640), |
72 | EP93XX_ADC_CH(3, "SYP" , 0x620), |
73 | EP93XX_ADC_CH(4, "SYM" , 0x610), |
74 | EP93XX_ADC_CH(5, "XP" , 0x601), |
75 | EP93XX_ADC_CH(6, "XM" , 0x602), |
76 | EP93XX_ADC_CH(7, "YP" , 0x604), |
77 | }; |
78 | |
79 | static int ep93xx_read_raw(struct iio_dev *iiodev, |
80 | struct iio_chan_spec const *channel, int *value, |
81 | int *shift, long mask) |
82 | { |
83 | struct ep93xx_adc_priv *priv = iio_priv(indio_dev: iiodev); |
84 | unsigned long timeout; |
85 | int ret; |
86 | |
87 | switch (mask) { |
88 | case IIO_CHAN_INFO_RAW: |
89 | mutex_lock(&priv->lock); |
90 | if (priv->lastch != channel->channel) { |
91 | priv->lastch = channel->channel; |
92 | /* |
93 | * Switch register is software-locked, unlocking must be |
94 | * immediately followed by write |
95 | */ |
96 | local_irq_disable(); |
97 | writel_relaxed(0xAA, priv->base + EP93XX_ADC_SW_LOCK); |
98 | writel_relaxed(channel->address, |
99 | priv->base + EP93XX_ADC_SWITCH); |
100 | local_irq_enable(); |
101 | /* |
102 | * Settling delay depends on module clock and could be |
103 | * 2ms or 500us |
104 | */ |
105 | ep93xx_adc_delay(2000, 2000); |
106 | } |
107 | /* Start the conversion, eventually discarding old result */ |
108 | readl_relaxed(priv->base + EP93XX_ADC_RESULT); |
109 | /* Ensure maximum conversion rate is not exceeded */ |
110 | ep93xx_adc_delay(DIV_ROUND_UP(1000000, 925), |
111 | DIV_ROUND_UP(1000000, 925)); |
112 | /* At this point conversion must be completed, but anyway... */ |
113 | ret = IIO_VAL_INT; |
114 | timeout = jiffies + msecs_to_jiffies(m: 1) + 1; |
115 | while (1) { |
116 | u32 t; |
117 | |
118 | t = readl_relaxed(priv->base + EP93XX_ADC_RESULT); |
119 | if (t & EP93XX_ADC_SDR) { |
120 | *value = sign_extend32(value: t, index: 15); |
121 | break; |
122 | } |
123 | |
124 | if (time_after(jiffies, timeout)) { |
125 | dev_err(&iiodev->dev, "Conversion timeout\n" ); |
126 | ret = -ETIMEDOUT; |
127 | break; |
128 | } |
129 | |
130 | cpu_relax(); |
131 | } |
132 | mutex_unlock(lock: &priv->lock); |
133 | return ret; |
134 | |
135 | case IIO_CHAN_INFO_OFFSET: |
136 | /* According to datasheet, range is -25000..25000 */ |
137 | *value = 25000; |
138 | return IIO_VAL_INT; |
139 | |
140 | case IIO_CHAN_INFO_SCALE: |
141 | /* Typical supply voltage is 3.3v */ |
142 | *value = (1ULL << 32) * 3300 / 50000; |
143 | *shift = 32; |
144 | return IIO_VAL_FRACTIONAL_LOG2; |
145 | } |
146 | |
147 | return -EINVAL; |
148 | } |
149 | |
150 | static const struct iio_info ep93xx_adc_info = { |
151 | .read_raw = ep93xx_read_raw, |
152 | }; |
153 | |
154 | static int ep93xx_adc_probe(struct platform_device *pdev) |
155 | { |
156 | int ret; |
157 | struct iio_dev *iiodev; |
158 | struct ep93xx_adc_priv *priv; |
159 | struct clk *pclk; |
160 | |
161 | iiodev = devm_iio_device_alloc(parent: &pdev->dev, sizeof_priv: sizeof(*priv)); |
162 | if (!iiodev) |
163 | return -ENOMEM; |
164 | priv = iio_priv(indio_dev: iiodev); |
165 | |
166 | priv->base = devm_platform_ioremap_resource(pdev, index: 0); |
167 | if (IS_ERR(ptr: priv->base)) |
168 | return PTR_ERR(ptr: priv->base); |
169 | |
170 | iiodev->name = dev_name(dev: &pdev->dev); |
171 | iiodev->modes = INDIO_DIRECT_MODE; |
172 | iiodev->info = &ep93xx_adc_info; |
173 | iiodev->num_channels = ARRAY_SIZE(ep93xx_adc_channels); |
174 | iiodev->channels = ep93xx_adc_channels; |
175 | |
176 | priv->lastch = -1; |
177 | mutex_init(&priv->lock); |
178 | |
179 | platform_set_drvdata(pdev, data: iiodev); |
180 | |
181 | priv->clk = devm_clk_get(dev: &pdev->dev, NULL); |
182 | if (IS_ERR(ptr: priv->clk)) { |
183 | dev_err(&pdev->dev, "Cannot obtain clock\n" ); |
184 | return PTR_ERR(ptr: priv->clk); |
185 | } |
186 | |
187 | pclk = clk_get_parent(clk: priv->clk); |
188 | if (!pclk) { |
189 | dev_warn(&pdev->dev, "Cannot obtain parent clock\n" ); |
190 | } else { |
191 | /* |
192 | * This is actually a place for improvement: |
193 | * EP93xx ADC supports two clock divisors -- 4 and 16, |
194 | * resulting in conversion rates 3750 and 925 samples per second |
195 | * with 500us or 2ms settling time respectively. |
196 | * One might find this interesting enough to be configurable. |
197 | */ |
198 | ret = clk_set_rate(clk: priv->clk, rate: clk_get_rate(clk: pclk) / 16); |
199 | if (ret) |
200 | dev_warn(&pdev->dev, "Cannot set clock rate\n" ); |
201 | /* |
202 | * We can tolerate rate setting failure because the module should |
203 | * work in any case. |
204 | */ |
205 | } |
206 | |
207 | ret = clk_prepare_enable(clk: priv->clk); |
208 | if (ret) { |
209 | dev_err(&pdev->dev, "Cannot enable clock\n" ); |
210 | return ret; |
211 | } |
212 | |
213 | ret = iio_device_register(iiodev); |
214 | if (ret) |
215 | clk_disable_unprepare(clk: priv->clk); |
216 | |
217 | return ret; |
218 | } |
219 | |
220 | static void ep93xx_adc_remove(struct platform_device *pdev) |
221 | { |
222 | struct iio_dev *iiodev = platform_get_drvdata(pdev); |
223 | struct ep93xx_adc_priv *priv = iio_priv(indio_dev: iiodev); |
224 | |
225 | iio_device_unregister(indio_dev: iiodev); |
226 | clk_disable_unprepare(clk: priv->clk); |
227 | } |
228 | |
229 | static const struct of_device_id ep93xx_adc_of_ids[] = { |
230 | { .compatible = "cirrus,ep9301-adc" }, |
231 | {} |
232 | }; |
233 | MODULE_DEVICE_TABLE(of, ep93xx_adc_of_ids); |
234 | |
235 | static struct platform_driver ep93xx_adc_driver = { |
236 | .driver = { |
237 | .name = "ep93xx-adc" , |
238 | .of_match_table = ep93xx_adc_of_ids, |
239 | }, |
240 | .probe = ep93xx_adc_probe, |
241 | .remove_new = ep93xx_adc_remove, |
242 | }; |
243 | module_platform_driver(ep93xx_adc_driver); |
244 | |
245 | MODULE_AUTHOR("Alexander Sverdlin <alexander.sverdlin@gmail.com>" ); |
246 | MODULE_DESCRIPTION("Cirrus Logic EP93XX ADC driver" ); |
247 | MODULE_LICENSE("GPL" ); |
248 | MODULE_ALIAS("platform:ep93xx-adc" ); |
249 | |