Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / staging / iio / accel / adis16220_core.c
1 /*
2  * ADIS16220 Programmable Digital Vibration Sensor driver
3  *
4  * Copyright 2010 Analog Devices Inc.
5  *
6  * Licensed under the GPL-2 or later.
7  */
8
9 #include <linux/delay.h>
10 #include <linux/mutex.h>
11 #include <linux/device.h>
12 #include <linux/kernel.h>
13 #include <linux/spi/spi.h>
14 #include <linux/slab.h>
15 #include <linux/sysfs.h>
16 #include <linux/module.h>
17
18 #include <linux/iio/iio.h>
19 #include <linux/iio/sysfs.h>
20
21 #include "adis16220.h"
22
23 static ssize_t adis16220_read_16bit(struct device *dev,
24                                     struct device_attribute *attr,
25                                     char *buf)
26 {
27         struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
28         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
29         struct adis16220_state *st = iio_priv(indio_dev);
30         ssize_t ret;
31         u16 val;
32
33         /* Take the iio_dev status lock */
34         mutex_lock(&indio_dev->mlock);
35         ret = adis_read_reg_16(&st->adis, this_attr->address, &val);
36         mutex_unlock(&indio_dev->mlock);
37         if (ret)
38                 return ret;
39         return sprintf(buf, "%u\n", val);
40 }
41
42 static ssize_t adis16220_write_16bit(struct device *dev,
43                                      struct device_attribute *attr,
44                                      const char *buf,
45                                      size_t len)
46 {
47         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
48         struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
49         struct adis16220_state *st = iio_priv(indio_dev);
50         int ret;
51         u16 val;
52
53         ret = kstrtou16(buf, 10, &val);
54         if (ret)
55                 goto error_ret;
56         ret = adis_write_reg_16(&st->adis, this_attr->address, val);
57
58 error_ret:
59         return ret ? ret : len;
60 }
61
62 static int adis16220_capture(struct iio_dev *indio_dev)
63 {
64         struct adis16220_state *st = iio_priv(indio_dev);
65         int ret;
66
67          /* initiates a manual data capture */
68         ret = adis_write_reg_16(&st->adis, ADIS16220_GLOB_CMD, 0xBF08);
69         if (ret)
70                 dev_err(&indio_dev->dev, "problem beginning capture");
71
72         usleep_range(10000, 11000); /* delay for capture to finish */
73
74         return ret;
75 }
76
77 static ssize_t adis16220_write_capture(struct device *dev,
78                                        struct device_attribute *attr,
79                                        const char *buf, size_t len)
80 {
81         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
82         bool val;
83         int ret;
84
85         ret = strtobool(buf, &val);
86         if (ret)
87                 return ret;
88         if (!val)
89                 return -EINVAL;
90         ret = adis16220_capture(indio_dev);
91         if (ret)
92                 return ret;
93
94         return len;
95 }
96
97 static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
98                                              char *buf,
99                                              loff_t off,
100                                              size_t count,
101                                              int addr)
102 {
103         struct adis16220_state *st = iio_priv(indio_dev);
104         struct spi_transfer xfers[] = {
105                 {
106                         .tx_buf = st->tx,
107                         .bits_per_word = 8,
108                         .len = 2,
109                         .cs_change = 1,
110                         .delay_usecs = 25,
111                 }, {
112                         .tx_buf = st->tx,
113                         .rx_buf = st->rx,
114                         .bits_per_word = 8,
115                         .cs_change = 1,
116                         .delay_usecs = 25,
117                 },
118         };
119         int ret;
120         int i;
121
122         if (unlikely(!count))
123                 return count;
124
125         if ((off >= ADIS16220_CAPTURE_SIZE) || (count & 1) || (off & 1))
126                 return -EINVAL;
127
128         if (off + count > ADIS16220_CAPTURE_SIZE)
129                 count = ADIS16220_CAPTURE_SIZE - off;
130
131         /* write the begin position of capture buffer */
132         ret = adis_write_reg_16(&st->adis,
133                                 ADIS16220_CAPT_PNTR,
134                                 off > 1);
135         if (ret)
136                 return -EIO;
137
138         /* read count/2 values from capture buffer */
139         mutex_lock(&st->buf_lock);
140
141         for (i = 0; i < count; i += 2) {
142                 st->tx[i] = ADIS_READ_REG(addr);
143                 st->tx[i + 1] = 0;
144         }
145         xfers[1].len = count;
146
147         ret = spi_sync_transfer(st->adis.spi, xfers, ARRAY_SIZE(xfers));
148         if (ret) {
149                 mutex_unlock(&st->buf_lock);
150                 return -EIO;
151         }
152
153         memcpy(buf, st->rx, count);
154
155         mutex_unlock(&st->buf_lock);
156         return count;
157 }
158
159 static ssize_t adis16220_accel_bin_read(struct file *filp, struct kobject *kobj,
160                                         struct bin_attribute *attr,
161                                         char *buf,
162                                         loff_t off,
163                                         size_t count)
164 {
165         struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj));
166
167         return adis16220_capture_buffer_read(indio_dev, buf,
168                                         off, count,
169                                         ADIS16220_CAPT_BUFA);
170 }
171
172 static struct bin_attribute accel_bin = {
173         .attr = {
174                 .name = "accel_bin",
175                 .mode = S_IRUGO,
176         },
177         .read = adis16220_accel_bin_read,
178         .size = ADIS16220_CAPTURE_SIZE,
179 };
180
181 static ssize_t adis16220_adc1_bin_read(struct file *filp, struct kobject *kobj,
182                                        struct bin_attribute *attr,
183                                        char *buf, loff_t off,
184                                        size_t count)
185 {
186         struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj));
187
188         return adis16220_capture_buffer_read(indio_dev, buf,
189                                         off, count,
190                                         ADIS16220_CAPT_BUF1);
191 }
192
193 static struct bin_attribute adc1_bin = {
194         .attr = {
195                 .name = "in0_bin",
196                 .mode = S_IRUGO,
197         },
198         .read =  adis16220_adc1_bin_read,
199         .size = ADIS16220_CAPTURE_SIZE,
200 };
201
202 static ssize_t adis16220_adc2_bin_read(struct file *filp, struct kobject *kobj,
203                                        struct bin_attribute *attr,
204                                        char *buf, loff_t off,
205                                        size_t count)
206 {
207         struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj));
208
209         return adis16220_capture_buffer_read(indio_dev, buf,
210                                         off, count,
211                                         ADIS16220_CAPT_BUF2);
212 }
213
214 static struct bin_attribute adc2_bin = {
215         .attr = {
216                 .name = "in1_bin",
217                 .mode = S_IRUGO,
218         },
219         .read =  adis16220_adc2_bin_read,
220         .size = ADIS16220_CAPTURE_SIZE,
221 };
222
223 #define IIO_DEV_ATTR_CAPTURE(_store)                            \
224         IIO_DEVICE_ATTR(capture, S_IWUSR, NULL, _store, 0)
225
226 static IIO_DEV_ATTR_CAPTURE(adis16220_write_capture);
227
228 #define IIO_DEV_ATTR_CAPTURE_COUNT(_mode, _show, _store, _addr)         \
229         IIO_DEVICE_ATTR(capture_count, _mode, _show, _store, _addr)
230
231 static IIO_DEV_ATTR_CAPTURE_COUNT(S_IWUSR | S_IRUGO,
232                 adis16220_read_16bit,
233                 adis16220_write_16bit,
234                 ADIS16220_CAPT_PNTR);
235
236 enum adis16220_channel {
237         in_supply, in_1, in_2, accel, temp
238 };
239
240 struct adis16220_address_spec {
241         u8 addr;
242         u8 bits;
243         bool sign;
244 };
245
246 /* Address / bits / signed */
247 static const struct adis16220_address_spec adis16220_addresses[][3] = {
248         [in_supply] =   { { ADIS16220_CAPT_SUPPLY,      12, 0 }, },
249         [in_1] =        { { ADIS16220_CAPT_BUF1,        16, 1 },
250                           { ADIS16220_AIN1_NULL,        16, 1 },
251                           { ADIS16220_CAPT_PEAK1,       16, 1 }, },
252         [in_2] =        { { ADIS16220_CAPT_BUF2,        16, 1 },
253                           { ADIS16220_AIN2_NULL,        16, 1 },
254                           { ADIS16220_CAPT_PEAK2,       16, 1 }, },
255         [accel] =       { { ADIS16220_CAPT_BUFA,        16, 1 },
256                           { ADIS16220_ACCL_NULL,        16, 1 },
257                           { ADIS16220_CAPT_PEAKA,       16, 1 }, },
258         [temp] =        { { ADIS16220_CAPT_TEMP,        12, 0 }, }
259 };
260
261 static int adis16220_read_raw(struct iio_dev *indio_dev,
262                               struct iio_chan_spec const *chan,
263                               int *val, int *val2,
264                               long mask)
265 {
266         struct adis16220_state *st = iio_priv(indio_dev);
267         const struct adis16220_address_spec *addr;
268         int ret = -EINVAL;
269         int addrind = 0;
270         u16 uval;
271         s16 sval;
272         u8 bits;
273
274         switch (mask) {
275         case IIO_CHAN_INFO_RAW:
276                 addrind = 0;
277                 break;
278         case IIO_CHAN_INFO_OFFSET:
279                 if (chan->type == IIO_TEMP) {
280                         *val = 25000 / -470 - 1278; /* 25 C = 1278 */
281                         return IIO_VAL_INT;
282                 }
283                 addrind = 1;
284                 break;
285         case IIO_CHAN_INFO_PEAK:
286                 addrind = 2;
287                 break;
288         case IIO_CHAN_INFO_SCALE:
289                 switch (chan->type) {
290                 case IIO_TEMP:
291                         *val = -470; /* -0.47 C */
292                         *val2 = 0;
293                         return IIO_VAL_INT_PLUS_MICRO;
294                 case IIO_ACCEL:
295                         *val2 = IIO_G_TO_M_S_2(19073); /* 19.073 g */
296                         return IIO_VAL_INT_PLUS_MICRO;
297                 case IIO_VOLTAGE:
298                         if (chan->channel == 0) {
299                                 *val = 1;
300                                 *val2 = 220700; /* 1.2207 mV */
301                         } else {
302                                 /* Should really be dependent on VDD */
303                                 *val2 = 305180; /* 305.18 uV */
304                         }
305                         return IIO_VAL_INT_PLUS_MICRO;
306                 default:
307                         return -EINVAL;
308                 }
309         default:
310                 return -EINVAL;
311         }
312         addr = &adis16220_addresses[chan->address][addrind];
313         if (addr->sign) {
314                 ret = adis_read_reg_16(&st->adis, addr->addr, &sval);
315                 if (ret)
316                         return ret;
317                 bits = addr->bits;
318                 sval &= (1 << bits) - 1;
319                 sval = (s16)(sval << (16 - bits)) >> (16 - bits);
320                 *val = sval;
321                 return IIO_VAL_INT;
322         }
323         ret = adis_read_reg_16(&st->adis, addr->addr, &uval);
324         if (ret)
325                 return ret;
326         bits = addr->bits;
327         uval &= (1 << bits) - 1;
328         *val = uval;
329         return IIO_VAL_INT;
330 }
331
332 static const struct iio_chan_spec adis16220_channels[] = {
333         {
334                 .type = IIO_VOLTAGE,
335                 .indexed = 1,
336                 .channel = 0,
337                 .extend_name = "supply",
338                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
339                         BIT(IIO_CHAN_INFO_SCALE),
340                 .address = in_supply,
341         }, {
342                 .type = IIO_ACCEL,
343                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
344                         BIT(IIO_CHAN_INFO_OFFSET) |
345                         BIT(IIO_CHAN_INFO_SCALE) |
346                         BIT(IIO_CHAN_INFO_PEAK),
347                 .address = accel,
348         }, {
349                 .type = IIO_TEMP,
350                 .indexed = 1,
351                 .channel = 0,
352                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
353                         BIT(IIO_CHAN_INFO_OFFSET) |
354                         BIT(IIO_CHAN_INFO_SCALE),
355                 .address = temp,
356         }, {
357                 .type = IIO_VOLTAGE,
358                 .indexed = 1,
359                 .channel = 1,
360                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
361                         BIT(IIO_CHAN_INFO_OFFSET) |
362                         BIT(IIO_CHAN_INFO_SCALE),
363                 .address = in_1,
364         }, {
365                 .type = IIO_VOLTAGE,
366                 .indexed = 1,
367                 .channel = 2,
368                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
369                 .address = in_2,
370         }
371 };
372
373 static struct attribute *adis16220_attributes[] = {
374         &iio_dev_attr_capture.dev_attr.attr,
375         &iio_dev_attr_capture_count.dev_attr.attr,
376         NULL
377 };
378
379 static const struct attribute_group adis16220_attribute_group = {
380         .attrs = adis16220_attributes,
381 };
382
383 static const struct iio_info adis16220_info = {
384         .attrs = &adis16220_attribute_group,
385         .driver_module = THIS_MODULE,
386         .read_raw = &adis16220_read_raw,
387 };
388
389 static const char * const adis16220_status_error_msgs[] = {
390         [ADIS16220_DIAG_STAT_VIOLATION_BIT] = "Capture period violation/interruption",
391         [ADIS16220_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure",
392         [ADIS16220_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed",
393         [ADIS16220_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V",
394         [ADIS16220_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V",
395 };
396
397 static const struct adis_data adis16220_data = {
398         .read_delay = 35,
399         .write_delay = 35,
400         .msc_ctrl_reg = ADIS16220_MSC_CTRL,
401         .glob_cmd_reg = ADIS16220_GLOB_CMD,
402         .diag_stat_reg = ADIS16220_DIAG_STAT,
403
404         .self_test_mask = ADIS16220_MSC_CTRL_SELF_TEST_EN,
405         .startup_delay = ADIS16220_STARTUP_DELAY,
406
407         .status_error_msgs = adis16220_status_error_msgs,
408         .status_error_mask = BIT(ADIS16220_DIAG_STAT_VIOLATION_BIT) |
409                 BIT(ADIS16220_DIAG_STAT_SPI_FAIL_BIT) |
410                 BIT(ADIS16220_DIAG_STAT_FLASH_UPT_BIT) |
411                 BIT(ADIS16220_DIAG_STAT_POWER_HIGH_BIT) |
412                 BIT(ADIS16220_DIAG_STAT_POWER_LOW_BIT),
413 };
414
415 static int adis16220_probe(struct spi_device *spi)
416 {
417         int ret;
418         struct adis16220_state *st;
419         struct iio_dev *indio_dev;
420
421         /* setup the industrialio driver allocated elements */
422         indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
423         if (!indio_dev)
424                 return -ENOMEM;
425
426         st = iio_priv(indio_dev);
427         /* this is only used for removal purposes */
428         spi_set_drvdata(spi, indio_dev);
429
430         indio_dev->name = spi->dev.driver->name;
431         indio_dev->dev.parent = &spi->dev;
432         indio_dev->info = &adis16220_info;
433         indio_dev->modes = INDIO_DIRECT_MODE;
434         indio_dev->channels = adis16220_channels;
435         indio_dev->num_channels = ARRAY_SIZE(adis16220_channels);
436
437         ret = devm_iio_device_register(&spi->dev, indio_dev);
438         if (ret)
439                 return ret;
440
441         ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &accel_bin);
442         if (ret)
443                 return ret;
444
445         ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &adc1_bin);
446         if (ret)
447                 goto error_rm_accel_bin;
448
449         ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &adc2_bin);
450         if (ret)
451                 goto error_rm_adc1_bin;
452
453         ret = adis_init(&st->adis, indio_dev, spi, &adis16220_data);
454         if (ret)
455                 goto error_rm_adc2_bin;
456         /* Get the device into a sane initial state */
457         ret = adis_initial_startup(&st->adis);
458         if (ret)
459                 goto error_rm_adc2_bin;
460         return 0;
461
462 error_rm_adc2_bin:
463         sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc2_bin);
464 error_rm_adc1_bin:
465         sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin);
466 error_rm_accel_bin:
467         sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin);
468         return ret;
469 }
470
471 static int adis16220_remove(struct spi_device *spi)
472 {
473         struct iio_dev *indio_dev = spi_get_drvdata(spi);
474
475         sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc2_bin);
476         sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin);
477         sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin);
478
479         return 0;
480 }
481
482 static struct spi_driver adis16220_driver = {
483         .driver = {
484                 .name = "adis16220",
485                 .owner = THIS_MODULE,
486         },
487         .probe = adis16220_probe,
488         .remove = adis16220_remove,
489 };
490 module_spi_driver(adis16220_driver);
491
492 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
493 MODULE_DESCRIPTION("Analog Devices ADIS16220 Digital Vibration Sensor");
494 MODULE_LICENSE("GPL v2");
495 MODULE_ALIAS("spi:adis16220");