Merge remote-tracking branch 'regulator/fix/arizona' into regulator-linus
[linux-drm-fsl-dcu.git] / drivers / iio / accel / kxsd9.c
1 /*
2  * kxsd9.c      simple support for the Kionix KXSD9 3D
3  *              accelerometer.
4  *
5  * Copyright (c) 2008-2009 Jonathan Cameron <jic23@kernel.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * The i2c interface is very similar, so shouldn't be a problem once
12  * I have a suitable wire made up.
13  *
14  * TODO:        Support the motion detector
15  *              Uses register address incrementing so could have a
16  *              heavily optimized ring buffer access function.
17  */
18
19 #include <linux/device.h>
20 #include <linux/kernel.h>
21 #include <linux/spi/spi.h>
22 #include <linux/sysfs.h>
23 #include <linux/slab.h>
24 #include <linux/module.h>
25
26 #include <linux/iio/iio.h>
27 #include <linux/iio/sysfs.h>
28
29 #define KXSD9_REG_X             0x00
30 #define KXSD9_REG_Y             0x02
31 #define KXSD9_REG_Z             0x04
32 #define KXSD9_REG_AUX           0x06
33 #define KXSD9_REG_RESET         0x0a
34 #define KXSD9_REG_CTRL_C        0x0c
35
36 #define KXSD9_FS_MASK           0x03
37
38 #define KXSD9_REG_CTRL_B        0x0d
39 #define KXSD9_REG_CTRL_A        0x0e
40
41 #define KXSD9_READ(a) (0x80 | (a))
42 #define KXSD9_WRITE(a) (a)
43
44 #define KXSD9_STATE_RX_SIZE 2
45 #define KXSD9_STATE_TX_SIZE 2
46 /**
47  * struct kxsd9_state - device related storage
48  * @buf_lock:   protect the rx and tx buffers.
49  * @us:         spi device
50  * @rx:         single rx buffer storage
51  * @tx:         single tx buffer storage
52  **/
53 struct kxsd9_state {
54         struct mutex buf_lock;
55         struct spi_device *us;
56         u8 rx[KXSD9_STATE_RX_SIZE] ____cacheline_aligned;
57         u8 tx[KXSD9_STATE_TX_SIZE];
58 };
59
60 #define KXSD9_SCALE_2G "0.011978"
61 #define KXSD9_SCALE_4G "0.023927"
62 #define KXSD9_SCALE_6G "0.035934"
63 #define KXSD9_SCALE_8G "0.047853"
64
65 /* reverse order */
66 static const int kxsd9_micro_scales[4] = { 47853, 35934, 23927, 11978 };
67
68 static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
69 {
70         int ret, i;
71         struct kxsd9_state *st = iio_priv(indio_dev);
72         bool foundit = false;
73
74         for (i = 0; i < 4; i++)
75                 if (micro == kxsd9_micro_scales[i]) {
76                         foundit = true;
77                         break;
78                 }
79         if (!foundit)
80                 return -EINVAL;
81
82         mutex_lock(&st->buf_lock);
83         ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
84         if (ret)
85                 goto error_ret;
86         st->tx[0] = KXSD9_WRITE(KXSD9_REG_CTRL_C);
87         st->tx[1] = (ret & ~KXSD9_FS_MASK) | i;
88
89         ret = spi_write(st->us, st->tx, 2);
90 error_ret:
91         mutex_unlock(&st->buf_lock);
92         return ret;
93 }
94
95 static int kxsd9_read(struct iio_dev *indio_dev, u8 address)
96 {
97         int ret;
98         struct kxsd9_state *st = iio_priv(indio_dev);
99         struct spi_transfer xfers[] = {
100                 {
101                         .bits_per_word = 8,
102                         .len = 1,
103                         .delay_usecs = 200,
104                         .tx_buf = st->tx,
105                 }, {
106                         .bits_per_word = 8,
107                         .len = 2,
108                         .rx_buf = st->rx,
109                 },
110         };
111
112         mutex_lock(&st->buf_lock);
113         st->tx[0] = KXSD9_READ(address);
114         ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
115         if (ret)
116                 return ret;
117         return (((u16)(st->rx[0])) << 8) | (st->rx[1] & 0xF0);
118 }
119
120 static IIO_CONST_ATTR(accel_scale_available,
121                 KXSD9_SCALE_2G " "
122                 KXSD9_SCALE_4G " "
123                 KXSD9_SCALE_6G " "
124                 KXSD9_SCALE_8G);
125
126 static struct attribute *kxsd9_attributes[] = {
127         &iio_const_attr_accel_scale_available.dev_attr.attr,
128         NULL,
129 };
130
131 static int kxsd9_write_raw(struct iio_dev *indio_dev,
132                            struct iio_chan_spec const *chan,
133                            int val,
134                            int val2,
135                            long mask)
136 {
137         int ret = -EINVAL;
138
139         if (mask == IIO_CHAN_INFO_SCALE) {
140                 /* Check no integer component */
141                 if (val)
142                         return -EINVAL;
143                 ret = kxsd9_write_scale(indio_dev, val2);
144         }
145
146         return ret;
147 }
148
149 static int kxsd9_read_raw(struct iio_dev *indio_dev,
150                           struct iio_chan_spec const *chan,
151                           int *val, int *val2, long mask)
152 {
153         int ret = -EINVAL;
154         struct kxsd9_state *st = iio_priv(indio_dev);
155
156         switch (mask) {
157         case IIO_CHAN_INFO_RAW:
158                 ret = kxsd9_read(indio_dev, chan->address);
159                 if (ret < 0)
160                         goto error_ret;
161                 *val = ret;
162                 break;
163         case IIO_CHAN_INFO_SCALE:
164                 ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
165                 if (ret)
166                         goto error_ret;
167                 *val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK];
168                 ret = IIO_VAL_INT_PLUS_MICRO;
169                 break;
170         }
171
172 error_ret:
173         return ret;
174 };
175 #define KXSD9_ACCEL_CHAN(axis)                                          \
176         {                                                               \
177                 .type = IIO_ACCEL,                                      \
178                 .modified = 1,                                          \
179                 .channel2 = IIO_MOD_##axis,                             \
180                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
181                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
182                 .address = KXSD9_REG_##axis,                            \
183         }
184
185 static const struct iio_chan_spec kxsd9_channels[] = {
186         KXSD9_ACCEL_CHAN(X), KXSD9_ACCEL_CHAN(Y), KXSD9_ACCEL_CHAN(Z),
187         {
188                 .type = IIO_VOLTAGE,
189                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
190                 .indexed = 1,
191                 .address = KXSD9_REG_AUX,
192         }
193 };
194
195 static const struct attribute_group kxsd9_attribute_group = {
196         .attrs = kxsd9_attributes,
197 };
198
199 static int kxsd9_power_up(struct kxsd9_state *st)
200 {
201         int ret;
202
203         st->tx[0] = 0x0d;
204         st->tx[1] = 0x40;
205         ret = spi_write(st->us, st->tx, 2);
206         if (ret)
207                 return ret;
208
209         st->tx[0] = 0x0c;
210         st->tx[1] = 0x9b;
211         return spi_write(st->us, st->tx, 2);
212 };
213
214 static const struct iio_info kxsd9_info = {
215         .read_raw = &kxsd9_read_raw,
216         .write_raw = &kxsd9_write_raw,
217         .attrs = &kxsd9_attribute_group,
218         .driver_module = THIS_MODULE,
219 };
220
221 static int kxsd9_probe(struct spi_device *spi)
222 {
223         struct iio_dev *indio_dev;
224         struct kxsd9_state *st;
225
226         indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
227         if (!indio_dev)
228                 return -ENOMEM;
229
230         st = iio_priv(indio_dev);
231         spi_set_drvdata(spi, indio_dev);
232
233         st->us = spi;
234         mutex_init(&st->buf_lock);
235         indio_dev->channels = kxsd9_channels;
236         indio_dev->num_channels = ARRAY_SIZE(kxsd9_channels);
237         indio_dev->name = spi_get_device_id(spi)->name;
238         indio_dev->dev.parent = &spi->dev;
239         indio_dev->info = &kxsd9_info;
240         indio_dev->modes = INDIO_DIRECT_MODE;
241
242         spi->mode = SPI_MODE_0;
243         spi_setup(spi);
244         kxsd9_power_up(st);
245
246         return iio_device_register(indio_dev);
247 }
248
249 static int kxsd9_remove(struct spi_device *spi)
250 {
251         iio_device_unregister(spi_get_drvdata(spi));
252
253         return 0;
254 }
255
256 static const struct spi_device_id kxsd9_id[] = {
257         {"kxsd9", 0},
258         { },
259 };
260 MODULE_DEVICE_TABLE(spi, kxsd9_id);
261
262 static struct spi_driver kxsd9_driver = {
263         .driver = {
264                 .name = "kxsd9",
265                 .owner = THIS_MODULE,
266         },
267         .probe = kxsd9_probe,
268         .remove = kxsd9_remove,
269         .id_table = kxsd9_id,
270 };
271 module_spi_driver(kxsd9_driver);
272
273 MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
274 MODULE_DESCRIPTION("Kionix KXSD9 SPI driver");
275 MODULE_LICENSE("GPL v2");