IIO: Move core headers to include/linux/iio
[deliverable/linux.git] / drivers / staging / iio / gyro / adis16080_core.c
CommitLineData
1b2f99e1
BS
1/*
2 * ADIS16080/100 Yaw Rate Gyroscope with SPI driver
3 *
4 * Copyright 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
1b2f99e1
BS
8#include <linux/delay.h>
9#include <linux/mutex.h>
10#include <linux/device.h>
11#include <linux/kernel.h>
12#include <linux/spi/spi.h>
13#include <linux/slab.h>
14#include <linux/sysfs.h>
99c97852 15#include <linux/module.h>
1b2f99e1 16
06458e27
JC
17#include <linux/iio/iio.h>
18#include <linux/iio/sysfs.h>
1b2f99e1 19
35d2b6f9
JC
20#define ADIS16080_DIN_GYRO (0 << 10) /* Gyroscope output */
21#define ADIS16080_DIN_TEMP (1 << 10) /* Temperature output */
22#define ADIS16080_DIN_AIN1 (2 << 10)
23#define ADIS16080_DIN_AIN2 (3 << 10)
24
25/*
26 * 1: Write contents on DIN to control register.
27 * 0: No changes to control register.
28 */
29
30#define ADIS16080_DIN_WRITE (1 << 15)
31
32/**
33 * struct adis16080_state - device instance specific data
34 * @us: actual spi_device to write data
25985edc 35 * @buf: transmit or receive buffer
35d2b6f9
JC
36 * @buf_lock: mutex to protect tx and rx
37 **/
38struct adis16080_state {
39 struct spi_device *us;
35d2b6f9
JC
40 struct mutex buf_lock;
41
42 u8 buf[2] ____cacheline_aligned;
43};
1b2f99e1 44
584c81fb 45static int adis16080_spi_write(struct iio_dev *indio_dev,
1b2f99e1
BS
46 u16 val)
47{
48 int ret;
1dd9290a 49 struct adis16080_state *st = iio_priv(indio_dev);
1b2f99e1
BS
50
51 mutex_lock(&st->buf_lock);
35d2b6f9
JC
52 st->buf[0] = val >> 8;
53 st->buf[1] = val;
1b2f99e1 54
35d2b6f9 55 ret = spi_write(st->us, st->buf, 2);
1b2f99e1
BS
56 mutex_unlock(&st->buf_lock);
57
58 return ret;
59}
60
584c81fb
JC
61static int adis16080_spi_read(struct iio_dev *indio_dev,
62 u16 *val)
1b2f99e1
BS
63{
64 int ret;
1dd9290a 65 struct adis16080_state *st = iio_priv(indio_dev);
1b2f99e1
BS
66
67 mutex_lock(&st->buf_lock);
68
35d2b6f9 69 ret = spi_read(st->us, st->buf, 2);
1b2f99e1
BS
70
71 if (ret == 0)
35d2b6f9 72 *val = ((st->buf[0] & 0xF) << 8) | st->buf[1];
1b2f99e1
BS
73 mutex_unlock(&st->buf_lock);
74
75 return ret;
76}
77
584c81fb
JC
78static int adis16080_read_raw(struct iio_dev *indio_dev,
79 struct iio_chan_spec const *chan,
80 int *val,
81 int *val2,
82 long mask)
1b2f99e1 83{
584c81fb
JC
84 int ret = -EINVAL;
85 u16 ut;
1b2f99e1 86 /* Take the iio_dev status lock */
584c81fb 87
1b2f99e1 88 mutex_lock(&indio_dev->mlock);
584c81fb 89 switch (mask) {
fbaff213 90 case IIO_CHAN_INFO_RAW:
584c81fb
JC
91 ret = adis16080_spi_write(indio_dev,
92 chan->address |
93 ADIS16080_DIN_WRITE);
94 if (ret < 0)
95 break;
96 ret = adis16080_spi_read(indio_dev, &ut);
97 if (ret < 0)
98 break;
99 *val = ut;
100 ret = IIO_VAL_INT;
101 break;
102 }
1b2f99e1
BS
103 mutex_unlock(&indio_dev->mlock);
104
584c81fb 105 return ret;
1b2f99e1 106}
1b2f99e1 107
584c81fb
JC
108static const struct iio_chan_spec adis16080_channels[] = {
109 {
41ea040c 110 .type = IIO_ANGL_VEL,
584c81fb
JC
111 .modified = 1,
112 .channel2 = IIO_MOD_Z,
fbaff213 113 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
584c81fb
JC
114 .address = ADIS16080_DIN_GYRO,
115 }, {
6835cb6b 116 .type = IIO_VOLTAGE,
584c81fb
JC
117 .indexed = 1,
118 .channel = 0,
fbaff213 119 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
584c81fb
JC
120 .address = ADIS16080_DIN_AIN1,
121 }, {
6835cb6b 122 .type = IIO_VOLTAGE,
584c81fb
JC
123 .indexed = 1,
124 .channel = 1,
fbaff213 125 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
584c81fb
JC
126 .address = ADIS16080_DIN_AIN2,
127 }, {
128 .type = IIO_TEMP,
129 .indexed = 1,
130 .channel = 0,
fbaff213 131 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
584c81fb
JC
132 .address = ADIS16080_DIN_TEMP,
133 }
1b2f99e1
BS
134};
135
6fe8135f 136static const struct iio_info adis16080_info = {
584c81fb 137 .read_raw = &adis16080_read_raw,
6fe8135f
JC
138 .driver_module = THIS_MODULE,
139};
140
1b2f99e1
BS
141static int __devinit adis16080_probe(struct spi_device *spi)
142{
26d25ae3 143 int ret;
1dd9290a
JC
144 struct adis16080_state *st;
145 struct iio_dev *indio_dev;
146
147 /* setup the industrialio driver allocated elements */
148 indio_dev = iio_allocate_device(sizeof(*st));
149 if (indio_dev == NULL) {
150 ret = -ENOMEM;
1b2f99e1
BS
151 goto error_ret;
152 }
1dd9290a 153 st = iio_priv(indio_dev);
1b2f99e1 154 /* this is only used for removal purposes */
1dd9290a 155 spi_set_drvdata(spi, indio_dev);
1b2f99e1
BS
156
157 /* Allocate the comms buffers */
1b2f99e1
BS
158 st->us = spi;
159 mutex_init(&st->buf_lock);
1b2f99e1 160
1dd9290a 161 indio_dev->name = spi->dev.driver->name;
584c81fb
JC
162 indio_dev->channels = adis16080_channels;
163 indio_dev->num_channels = ARRAY_SIZE(adis16080_channels);
1dd9290a
JC
164 indio_dev->dev.parent = &spi->dev;
165 indio_dev->info = &adis16080_info;
166 indio_dev->modes = INDIO_DIRECT_MODE;
1b2f99e1 167
1dd9290a 168 ret = iio_device_register(indio_dev);
1b2f99e1 169 if (ret)
8d016b43 170 goto error_free_dev;
1b2f99e1
BS
171 return 0;
172
1b2f99e1 173error_free_dev:
26d25ae3 174 iio_free_device(indio_dev);
1b2f99e1
BS
175error_ret:
176 return ret;
177}
178
179/* fixme, confirm ordering in this function */
180static int adis16080_remove(struct spi_device *spi)
181{
1dd9290a 182 iio_device_unregister(spi_get_drvdata(spi));
d2fffd6c 183 iio_free_device(spi_get_drvdata(spi));
1b2f99e1
BS
184
185 return 0;
186}
187
188static struct spi_driver adis16080_driver = {
189 .driver = {
190 .name = "adis16080",
191 .owner = THIS_MODULE,
192 },
193 .probe = adis16080_probe,
194 .remove = __devexit_p(adis16080_remove),
195};
ae6ae6fe 196module_spi_driver(adis16080_driver);
1b2f99e1
BS
197
198MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
8d016b43 199MODULE_DESCRIPTION("Analog Devices ADIS16080/100 Yaw Rate Gyroscope Driver");
1b2f99e1 200MODULE_LICENSE("GPL v2");
55e4390c 201MODULE_ALIAS("spi:adis16080");
This page took 0.17662 seconds and 5 git commands to generate.