Merge remote-tracking branches 'regmap/topic/const' and 'regmap/topic/hwspinlock...
[linux-2.6-block.git] / drivers / iio / adc / spear_adc.c
CommitLineData
b3201b56
SR
1/*
2 * ST SPEAr ADC driver
3 *
4 * Copyright 2012 Stefan Roese <sr@denx.de>
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/module.h>
10#include <linux/platform_device.h>
11#include <linux/interrupt.h>
12#include <linux/device.h>
13#include <linux/kernel.h>
14#include <linux/slab.h>
15#include <linux/io.h>
16#include <linux/clk.h>
17#include <linux/err.h>
18#include <linux/completion.h>
19#include <linux/of.h>
20#include <linux/of_address.h>
21
06458e27
JC
22#include <linux/iio/iio.h>
23#include <linux/iio/sysfs.h>
b3201b56 24
b64aef70
JC
25/* SPEAR registers definitions */
26#define SPEAR600_ADC_SCAN_RATE_LO(x) ((x) & 0xFFFF)
27#define SPEAR600_ADC_SCAN_RATE_HI(x) (((x) >> 0x10) & 0xFFFF)
28#define SPEAR_ADC_CLK_LOW(x) (((x) & 0xf) << 0)
29#define SPEAR_ADC_CLK_HIGH(x) (((x) & 0xf) << 4)
b3201b56
SR
30
31/* Bit definitions for SPEAR_ADC_STATUS */
418880f5 32#define SPEAR_ADC_STATUS_START_CONVERSION BIT(0)
b64aef70 33#define SPEAR_ADC_STATUS_CHANNEL_NUM(x) ((x) << 1)
418880f5 34#define SPEAR_ADC_STATUS_ADC_ENABLE BIT(4)
b64aef70 35#define SPEAR_ADC_STATUS_AVG_SAMPLE(x) ((x) << 5)
418880f5 36#define SPEAR_ADC_STATUS_VREF_INTERNAL BIT(9)
b3201b56 37
b64aef70
JC
38#define SPEAR_ADC_DATA_MASK 0x03ff
39#define SPEAR_ADC_DATA_BITS 10
b3201b56 40
b64aef70 41#define SPEAR_ADC_MOD_NAME "spear-adc"
b3201b56 42
b64aef70 43#define SPEAR_ADC_CHANNEL_NUM 8
b3201b56 44
b64aef70
JC
45#define SPEAR_ADC_CLK_MIN 2500000
46#define SPEAR_ADC_CLK_MAX 20000000
b3201b56
SR
47
48struct adc_regs_spear3xx {
49 u32 status;
50 u32 average;
51 u32 scan_rate;
52 u32 clk; /* Not avail for 1340 & 1310 */
b64aef70
JC
53 u32 ch_ctrl[SPEAR_ADC_CHANNEL_NUM];
54 u32 ch_data[SPEAR_ADC_CHANNEL_NUM];
b3201b56
SR
55};
56
57struct chan_data {
58 u32 lsb;
59 u32 msb;
60};
61
62struct adc_regs_spear6xx {
63 u32 status;
64 u32 pad[2];
65 u32 clk;
b64aef70
JC
66 u32 ch_ctrl[SPEAR_ADC_CHANNEL_NUM];
67 struct chan_data ch_data[SPEAR_ADC_CHANNEL_NUM];
b3201b56
SR
68 u32 scan_rate_lo;
69 u32 scan_rate_hi;
70 struct chan_data average;
71};
72
b586e5d9 73struct spear_adc_state {
b3201b56
SR
74 struct device_node *np;
75 struct adc_regs_spear3xx __iomem *adc_base_spear3xx;
76 struct adc_regs_spear6xx __iomem *adc_base_spear6xx;
77 struct clk *clk;
78 struct completion completion;
79 u32 current_clk;
80 u32 sampling_freq;
81 u32 avg_samples;
82 u32 vref_external;
83 u32 value;
84};
85
86/*
87 * Functions to access some SPEAr ADC register. Abstracted into
88 * static inline functions, because of different register offsets
89 * on different SoC variants (SPEAr300 vs SPEAr600 etc).
90 */
b586e5d9 91static void spear_adc_set_status(struct spear_adc_state *st, u32 val)
b3201b56 92{
b586e5d9 93 __raw_writel(val, &st->adc_base_spear6xx->status);
b3201b56
SR
94}
95
b586e5d9 96static void spear_adc_set_clk(struct spear_adc_state *st, u32 val)
b3201b56
SR
97{
98 u32 clk_high, clk_low, count;
b586e5d9 99 u32 apb_clk = clk_get_rate(st->clk);
b3201b56 100
ffceca8c 101 count = DIV_ROUND_UP(apb_clk, val);
b3201b56
SR
102 clk_low = count / 2;
103 clk_high = count - clk_low;
b586e5d9 104 st->current_clk = apb_clk / count;
b3201b56 105
b64aef70 106 __raw_writel(SPEAR_ADC_CLK_LOW(clk_low) | SPEAR_ADC_CLK_HIGH(clk_high),
b586e5d9 107 &st->adc_base_spear6xx->clk);
b3201b56
SR
108}
109
b586e5d9 110static void spear_adc_set_ctrl(struct spear_adc_state *st, int n,
b3201b56
SR
111 u32 val)
112{
b586e5d9 113 __raw_writel(val, &st->adc_base_spear6xx->ch_ctrl[n]);
b3201b56
SR
114}
115
b586e5d9 116static u32 spear_adc_get_average(struct spear_adc_state *st)
b3201b56 117{
b586e5d9
JC
118 if (of_device_is_compatible(st->np, "st,spear600-adc")) {
119 return __raw_readl(&st->adc_base_spear6xx->average.msb) &
b64aef70 120 SPEAR_ADC_DATA_MASK;
b3201b56 121 } else {
b586e5d9 122 return __raw_readl(&st->adc_base_spear3xx->average) &
b64aef70 123 SPEAR_ADC_DATA_MASK;
b3201b56
SR
124 }
125}
126
b586e5d9 127static void spear_adc_set_scanrate(struct spear_adc_state *st, u32 rate)
b3201b56 128{
b586e5d9 129 if (of_device_is_compatible(st->np, "st,spear600-adc")) {
b64aef70 130 __raw_writel(SPEAR600_ADC_SCAN_RATE_LO(rate),
b586e5d9 131 &st->adc_base_spear6xx->scan_rate_lo);
b64aef70 132 __raw_writel(SPEAR600_ADC_SCAN_RATE_HI(rate),
b586e5d9 133 &st->adc_base_spear6xx->scan_rate_hi);
b3201b56 134 } else {
b586e5d9 135 __raw_writel(rate, &st->adc_base_spear3xx->scan_rate);
b3201b56
SR
136 }
137}
138
e20d6090
JC
139static int spear_adc_read_raw(struct iio_dev *indio_dev,
140 struct iio_chan_spec const *chan,
141 int *val,
142 int *val2,
143 long mask)
b3201b56 144{
b586e5d9 145 struct spear_adc_state *st = iio_priv(indio_dev);
b3201b56
SR
146 u32 status;
147
148 switch (mask) {
b11f98ff 149 case IIO_CHAN_INFO_RAW:
b3201b56
SR
150 mutex_lock(&indio_dev->mlock);
151
b64aef70 152 status = SPEAR_ADC_STATUS_CHANNEL_NUM(chan->channel) |
b586e5d9 153 SPEAR_ADC_STATUS_AVG_SAMPLE(st->avg_samples) |
b64aef70
JC
154 SPEAR_ADC_STATUS_START_CONVERSION |
155 SPEAR_ADC_STATUS_ADC_ENABLE;
b586e5d9 156 if (st->vref_external == 0)
b64aef70 157 status |= SPEAR_ADC_STATUS_VREF_INTERNAL;
b3201b56 158
b586e5d9
JC
159 spear_adc_set_status(st, status);
160 wait_for_completion(&st->completion); /* set by ISR */
161 *val = st->value;
b3201b56
SR
162
163 mutex_unlock(&indio_dev->mlock);
164
165 return IIO_VAL_INT;
166
167 case IIO_CHAN_INFO_SCALE:
b586e5d9 168 *val = st->vref_external;
b64aef70 169 *val2 = SPEAR_ADC_DATA_BITS;
bfbab2bc 170 return IIO_VAL_FRACTIONAL_LOG2;
932de74b 171 case IIO_CHAN_INFO_SAMP_FREQ:
b586e5d9 172 *val = st->current_clk;
932de74b 173 return IIO_VAL_INT;
b3201b56
SR
174 }
175
176 return -EINVAL;
177}
178
932de74b
JC
179static int spear_adc_write_raw(struct iio_dev *indio_dev,
180 struct iio_chan_spec const *chan,
181 int val,
182 int val2,
183 long mask)
184{
b586e5d9 185 struct spear_adc_state *st = iio_priv(indio_dev);
932de74b
JC
186 int ret = 0;
187
188 if (mask != IIO_CHAN_INFO_SAMP_FREQ)
189 return -EINVAL;
190
191 mutex_lock(&indio_dev->mlock);
192
193 if ((val < SPEAR_ADC_CLK_MIN) ||
e8ef49f0
IC
194 (val > SPEAR_ADC_CLK_MAX) ||
195 (val2 != 0)) {
932de74b
JC
196 ret = -EINVAL;
197 goto out;
198 }
199
b586e5d9 200 spear_adc_set_clk(st, val);
932de74b
JC
201
202out:
203 mutex_unlock(&indio_dev->mlock);
204 return ret;
205}
206
b3201b56
SR
207#define SPEAR_ADC_CHAN(idx) { \
208 .type = IIO_VOLTAGE, \
209 .indexed = 1, \
f1e067ba
JC
210 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
211 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
932de74b 212 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
b3201b56 213 .channel = idx, \
b3201b56
SR
214}
215
f4e4b955 216static const struct iio_chan_spec spear_adc_iio_channels[] = {
b3201b56
SR
217 SPEAR_ADC_CHAN(0),
218 SPEAR_ADC_CHAN(1),
219 SPEAR_ADC_CHAN(2),
220 SPEAR_ADC_CHAN(3),
221 SPEAR_ADC_CHAN(4),
222 SPEAR_ADC_CHAN(5),
223 SPEAR_ADC_CHAN(6),
224 SPEAR_ADC_CHAN(7),
225};
226
227static irqreturn_t spear_adc_isr(int irq, void *dev_id)
228{
31f8f066 229 struct spear_adc_state *st = dev_id;
b3201b56
SR
230
231 /* Read value to clear IRQ */
b586e5d9
JC
232 st->value = spear_adc_get_average(st);
233 complete(&st->completion);
b3201b56
SR
234
235 return IRQ_HANDLED;
236}
237
b586e5d9 238static int spear_adc_configure(struct spear_adc_state *st)
b3201b56
SR
239{
240 int i;
241
242 /* Reset ADC core */
b586e5d9
JC
243 spear_adc_set_status(st, 0);
244 __raw_writel(0, &st->adc_base_spear6xx->clk);
b3201b56 245 for (i = 0; i < 8; i++)
b586e5d9
JC
246 spear_adc_set_ctrl(st, i, 0);
247 spear_adc_set_scanrate(st, 0);
b3201b56 248
b586e5d9 249 spear_adc_set_clk(st, st->sampling_freq);
b3201b56
SR
250
251 return 0;
252}
253
b586e5d9 254static const struct iio_info spear_adc_info = {
e20d6090 255 .read_raw = &spear_adc_read_raw,
932de74b 256 .write_raw = &spear_adc_write_raw,
b3201b56
SR
257 .driver_module = THIS_MODULE,
258};
259
4ae1c61f 260static int spear_adc_probe(struct platform_device *pdev)
b3201b56
SR
261{
262 struct device_node *np = pdev->dev.of_node;
263 struct device *dev = &pdev->dev;
b586e5d9 264 struct spear_adc_state *st;
09b9da33 265 struct resource *res;
e90ba52f 266 struct iio_dev *indio_dev = NULL;
b3201b56
SR
267 int ret = -ENODEV;
268 int irq;
269
e90ba52f
JC
270 indio_dev = devm_iio_device_alloc(dev, sizeof(struct spear_adc_state));
271 if (!indio_dev) {
b3201b56 272 dev_err(dev, "failed allocating iio device\n");
8c7f6d56 273 return -ENOMEM;
b3201b56
SR
274 }
275
e90ba52f 276 st = iio_priv(indio_dev);
b586e5d9 277 st->np = np;
b3201b56
SR
278
279 /*
280 * SPEAr600 has a different register layout than other SPEAr SoC's
281 * (e.g. SPEAr3xx). Let's provide two register base addresses
282 * to support multi-arch kernels.
283 */
09b9da33
AKC
284 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
285 st->adc_base_spear6xx = devm_ioremap_resource(&pdev->dev, res);
286 if (IS_ERR(st->adc_base_spear6xx))
287 return PTR_ERR(st->adc_base_spear6xx);
288
b586e5d9
JC
289 st->adc_base_spear3xx =
290 (struct adc_regs_spear3xx __iomem *)st->adc_base_spear6xx;
b3201b56 291
b8cc27ca 292 st->clk = devm_clk_get(dev, NULL);
b586e5d9 293 if (IS_ERR(st->clk)) {
b3201b56 294 dev_err(dev, "failed getting clock\n");
09b9da33 295 return PTR_ERR(st->clk);
b3201b56
SR
296 }
297
b586e5d9 298 ret = clk_prepare_enable(st->clk);
b3201b56
SR
299 if (ret) {
300 dev_err(dev, "failed enabling clock\n");
09b9da33 301 return ret;
b3201b56
SR
302 }
303
304 irq = platform_get_irq(pdev, 0);
a47f6e08 305 if (irq <= 0) {
b3201b56
SR
306 dev_err(dev, "failed getting interrupt resource\n");
307 ret = -EINVAL;
b8cc27ca 308 goto errout2;
b3201b56
SR
309 }
310
b64aef70 311 ret = devm_request_irq(dev, irq, spear_adc_isr, 0, SPEAR_ADC_MOD_NAME,
b586e5d9 312 st);
b3201b56
SR
313 if (ret < 0) {
314 dev_err(dev, "failed requesting interrupt\n");
b8cc27ca 315 goto errout2;
b3201b56
SR
316 }
317
318 if (of_property_read_u32(np, "sampling-frequency",
b586e5d9 319 &st->sampling_freq)) {
b3201b56
SR
320 dev_err(dev, "sampling-frequency missing in DT\n");
321 ret = -EINVAL;
b8cc27ca 322 goto errout2;
b3201b56
SR
323 }
324
325 /*
326 * Optional avg_samples defaults to 0, resulting in single data
327 * conversion
328 */
b586e5d9 329 of_property_read_u32(np, "average-samples", &st->avg_samples);
b3201b56
SR
330
331 /*
332 * Optional vref_external defaults to 0, resulting in internal vref
333 * selection
334 */
b586e5d9 335 of_property_read_u32(np, "vref-external", &st->vref_external);
b3201b56 336
b586e5d9 337 spear_adc_configure(st);
b3201b56 338
e90ba52f 339 platform_set_drvdata(pdev, indio_dev);
b3201b56 340
b586e5d9 341 init_completion(&st->completion);
b3201b56 342
e90ba52f
JC
343 indio_dev->name = SPEAR_ADC_MOD_NAME;
344 indio_dev->dev.parent = dev;
345 indio_dev->info = &spear_adc_info;
346 indio_dev->modes = INDIO_DIRECT_MODE;
347 indio_dev->channels = spear_adc_iio_channels;
348 indio_dev->num_channels = ARRAY_SIZE(spear_adc_iio_channels);
b3201b56 349
e90ba52f 350 ret = iio_device_register(indio_dev);
b3201b56 351 if (ret)
b8cc27ca 352 goto errout2;
b3201b56
SR
353
354 dev_info(dev, "SPEAR ADC driver loaded, IRQ %d\n", irq);
355
356 return 0;
357
b3201b56 358errout2:
b8cc27ca 359 clk_disable_unprepare(st->clk);
b3201b56
SR
360 return ret;
361}
362
447d4f29 363static int spear_adc_remove(struct platform_device *pdev)
b3201b56 364{
e90ba52f
JC
365 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
366 struct spear_adc_state *st = iio_priv(indio_dev);
b3201b56 367
e90ba52f 368 iio_device_unregister(indio_dev);
b586e5d9 369 clk_disable_unprepare(st->clk);
b3201b56
SR
370
371 return 0;
372}
373
e89b6747 374#ifdef CONFIG_OF
b3201b56
SR
375static const struct of_device_id spear_adc_dt_ids[] = {
376 { .compatible = "st,spear600-adc", },
377 { /* sentinel */ }
378};
379MODULE_DEVICE_TABLE(of, spear_adc_dt_ids);
e89b6747 380#endif
b3201b56
SR
381
382static struct platform_driver spear_adc_driver = {
383 .probe = spear_adc_probe,
e543acf0 384 .remove = spear_adc_remove,
b3201b56 385 .driver = {
b64aef70 386 .name = SPEAR_ADC_MOD_NAME,
b3201b56
SR
387 .of_match_table = of_match_ptr(spear_adc_dt_ids),
388 },
389};
390
391module_platform_driver(spear_adc_driver);
392
393MODULE_AUTHOR("Stefan Roese <sr@denx.de>");
394MODULE_DESCRIPTION("SPEAr ADC driver");
395MODULE_LICENSE("GPL");