Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
[sfrench/cifs-2.6.git] / drivers / staging / 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@cam.ac.uk>
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/interrupt.h>
20 #include <linux/gpio.h>
21 #include <linux/fs.h>
22 #include <linux/device.h>
23 #include <linux/kernel.h>
24 #include <linux/spi/spi.h>
25 #include <linux/sysfs.h>
26 #include <linux/rtc.h>
27 #include <linux/delay.h>
28
29 #include "../iio.h"
30 #include "../sysfs.h"
31 #include "../adc/adc.h"
32 #include "accel.h"
33
34 #define KXSD9_REG_X             0x00
35 #define KXSD9_REG_Y             0x02
36 #define KXSD9_REG_Z             0x04
37 #define KXSD9_REG_AUX           0x06
38 #define KXSD9_REG_RESET         0x0a
39 #define KXSD9_REG_CTRL_C        0x0c
40
41 #define KXSD9_FS_8              0x00
42 #define KXSD9_FS_6              0x01
43 #define KXSD9_FS_4              0x02
44 #define KXSD9_FS_2              0x03
45 #define KXSD9_FS_MASK           0x03
46
47 #define KXSD9_REG_CTRL_B        0x0d
48 #define KXSD9_REG_CTRL_A        0x0e
49
50 #define KXSD9_READ(a) (0x80 | (a))
51 #define KXSD9_WRITE(a) (a)
52
53 #define IIO_DEV_ATTR_ACCEL_SET_RANGE(_mode, _show, _store)      \
54         IIO_DEVICE_ATTR(accel_range, _mode, _show, _store, 0)
55
56 #define KXSD9_STATE_RX_SIZE 2
57 #define KXSD9_STATE_TX_SIZE 4
58 /**
59  * struct kxsd9_state - device related storage
60  * @buf_lock:   protect the rx and tx buffers.
61  * @indio_dev:  associated industrial IO device
62  * @us:         spi device
63  * @rx:         single rx buffer storage
64  * @tx:         single tx buffer storage
65  **/
66 struct kxsd9_state {
67         struct mutex buf_lock;
68         struct iio_dev *indio_dev;
69         struct spi_device *us;
70         u8 *rx;
71         u8 *tx;
72 };
73
74 /* This may want to move to mili g to allow for non integer ranges */
75 static ssize_t kxsd9_read_accel_range(struct device *dev,
76                                       struct device_attribute *attr,
77                                       char *buf)
78 {
79         int ret;
80         ssize_t len = 0;
81         struct iio_dev *indio_dev = dev_get_drvdata(dev);
82         struct kxsd9_state *st = indio_dev->dev_data;
83         struct spi_transfer xfer = {
84                 .bits_per_word = 8,
85                 .len = 2,
86                 .cs_change = 1,
87                 .tx_buf = st->tx,
88                 .rx_buf = st->rx,
89         };
90         struct spi_message msg;
91
92         mutex_lock(&st->buf_lock);
93         st->tx[0] = KXSD9_READ(KXSD9_REG_CTRL_C);
94         st->tx[1] = 0;
95         spi_message_init(&msg);
96         spi_message_add_tail(&xfer, &msg);
97         ret = spi_sync(st->us, &msg);
98         if (ret)
99                 goto error_ret;
100
101         switch (st->rx[1] & KXSD9_FS_MASK) {
102         case KXSD9_FS_8:
103                 len += sprintf(buf, "8\n");
104                 break;
105         case KXSD9_FS_6:
106                 len += sprintf(buf, "6\n");
107                 break;
108         case KXSD9_FS_4:
109                 len += sprintf(buf, "4\n");
110                 break;
111         case KXSD9_FS_2:
112                 len += sprintf(buf, "2\n");
113                 break;
114         }
115
116 error_ret:
117         mutex_unlock(&st->buf_lock);
118
119         return ret ? ret : len;
120 }
121 static ssize_t kxsd9_write_accel_range(struct device *dev,
122                                       struct device_attribute *attr,
123                                       const char *buf,
124                                       size_t len)
125 {
126         long readin;
127         struct spi_message msg;
128         int ret;
129         struct iio_dev *indio_dev = dev_get_drvdata(dev);
130         struct kxsd9_state *st = indio_dev->dev_data;
131         u8 val;
132         struct spi_transfer xfers[] = {
133                 {
134                         .bits_per_word = 8,
135                         .len = 2,
136                         .cs_change = 1,
137                         .tx_buf = st->tx,
138                         .rx_buf = st->rx,
139                 }, {
140                         .bits_per_word = 8,
141                         .len = 2,
142                         .cs_change = 1,
143                         .tx_buf = st->tx,
144                 },
145         };
146
147         ret = strict_strtol(buf, 10, &readin);
148         if (ret)
149                 return ret;
150         switch (readin) {
151         case 8:
152                 val = KXSD9_FS_8;
153                 break;
154         case 6:
155                 val = KXSD9_FS_6;
156                 break;
157         case 4:
158                 val = KXSD9_FS_4;
159                 break;
160         case 2:
161                 val = KXSD9_FS_2;
162                 break;
163         default:
164                 return -EINVAL;
165         }
166         mutex_lock(&st->buf_lock);
167         st->tx[0] = KXSD9_READ(KXSD9_REG_CTRL_C);
168         st->tx[1] = 0;
169         spi_message_init(&msg);
170         spi_message_add_tail(&xfers[0], &msg);
171         ret = spi_sync(st->us, &msg);
172         if (ret)
173                 goto error_ret;
174         st->tx[0] = KXSD9_WRITE(KXSD9_REG_CTRL_C);
175         st->tx[1] = (st->rx[1] & ~KXSD9_FS_MASK) | val;
176
177         spi_message_init(&msg);
178         spi_message_add_tail(&xfers[1], &msg);
179         ret = spi_sync(st->us, &msg);
180 error_ret:
181         mutex_unlock(&st->buf_lock);
182         return ret ? ret : len;
183 }
184 static ssize_t kxsd9_read_accel(struct device *dev,
185                                 struct device_attribute *attr,
186                                 char *buf)
187 {
188         struct spi_message msg;
189         int ret;
190         ssize_t len = 0;
191         u16 val;
192         struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
193         struct iio_dev *indio_dev = dev_get_drvdata(dev);
194         struct kxsd9_state *st = indio_dev->dev_data;
195         struct spi_transfer xfers[] = {
196                 {
197                         .bits_per_word = 8,
198                         .len = 1,
199                         .cs_change = 0,
200                         .delay_usecs = 200,
201                         .tx_buf = st->tx,
202                 }, {
203                         .bits_per_word = 8,
204                         .len = 2,
205                         .cs_change = 1,
206                         .rx_buf = st->rx,
207                 },
208         };
209
210         mutex_lock(&st->buf_lock);
211         st->tx[0] = KXSD9_READ(this_attr->address);
212         spi_message_init(&msg);
213         spi_message_add_tail(&xfers[0], &msg);
214         spi_message_add_tail(&xfers[1], &msg);
215         ret = spi_sync(st->us, &msg);
216         if (ret)
217                 goto error_ret;
218         val = (((u16)(st->rx[0])) << 8) | (st->rx[1] & 0xF0);
219         len = sprintf(buf, "%d\n", val);
220 error_ret:
221         mutex_unlock(&st->buf_lock);
222
223         return ret ? ret : len;
224 }
225
226 static IIO_DEV_ATTR_ACCEL_X(kxsd9_read_accel, KXSD9_REG_X);
227 static IIO_DEV_ATTR_ACCEL_Y(kxsd9_read_accel, KXSD9_REG_Y);
228 static IIO_DEV_ATTR_ACCEL_Z(kxsd9_read_accel, KXSD9_REG_Z);
229 static IIO_DEV_ATTR_ADC(0, kxsd9_read_accel, KXSD9_REG_AUX);
230 static IIO_DEV_ATTR_ACCEL_SET_RANGE(S_IRUGO | S_IWUSR,
231                                     kxsd9_read_accel_range,
232                                     kxsd9_write_accel_range);
233
234 static struct attribute *kxsd9_attributes[] = {
235         &iio_dev_attr_accel_x.dev_attr.attr,
236         &iio_dev_attr_accel_y.dev_attr.attr,
237         &iio_dev_attr_accel_z.dev_attr.attr,
238         &iio_dev_attr_adc_0.dev_attr.attr,
239         &iio_dev_attr_accel_range.dev_attr.attr,
240         NULL,
241 };
242
243 static const struct attribute_group kxsd9_attribute_group = {
244         .attrs = kxsd9_attributes,
245 };
246
247 static int __devinit kxsd9_power_up(struct spi_device *spi)
248 {
249         int ret;
250         struct spi_transfer xfers[2] = {
251                 {
252                         .bits_per_word = 8,
253                         .len = 2,
254                         .cs_change = 1,
255                 }, {
256                         .bits_per_word = 8,
257                         .len = 2,
258                         .cs_change = 1,
259                 },
260         };
261         struct spi_message msg;
262         u8 *tx2;
263         u8 *tx = kmalloc(2, GFP_KERNEL);
264
265         if (tx == NULL) {
266                 ret = -ENOMEM;
267                 goto error_ret;
268         }
269         tx2 = kmalloc(2, GFP_KERNEL);
270         if (tx2 == NULL) {
271                 ret = -ENOMEM;
272                 goto error_free_tx;
273         }
274         tx[0] = 0x0d;
275         tx[1] = 0x40;
276
277         tx2[0] = 0x0c;
278         tx2[1] = 0x9b;
279
280         xfers[0].tx_buf = tx;
281         xfers[1].tx_buf = tx2;
282         spi_message_init(&msg);
283         spi_message_add_tail(&xfers[0], &msg);
284         spi_message_add_tail(&xfers[1], &msg);
285         ret = spi_sync(spi, &msg);
286
287         kfree(tx2);
288 error_free_tx:
289         kfree(tx);
290 error_ret:
291         return ret;
292
293 };
294
295 static int __devinit kxsd9_probe(struct spi_device *spi)
296 {
297
298         struct kxsd9_state *st;
299         int ret = 0;
300
301         st = kzalloc(sizeof(*st), GFP_KERNEL);
302         if (st == NULL) {
303                 ret = -ENOMEM;
304                 goto error_ret;
305         }
306         spi_set_drvdata(spi, st);
307
308         st->rx = kmalloc(sizeof(*st->rx)*KXSD9_STATE_RX_SIZE,
309                          GFP_KERNEL);
310         if (st->rx == NULL) {
311                 ret = -ENOMEM;
312                 goto error_free_st;
313         }
314         st->tx = kmalloc(sizeof(*st->tx)*KXSD9_STATE_TX_SIZE,
315                          GFP_KERNEL);
316         if (st->tx == NULL) {
317                 ret = -ENOMEM;
318                 goto error_free_rx;
319         }
320
321         st->us = spi;
322         mutex_init(&st->buf_lock);
323         st->indio_dev = iio_allocate_device();
324         if (st->indio_dev == NULL) {
325                 ret = -ENOMEM;
326                 goto error_free_tx;
327         }
328         st->indio_dev->dev.parent = &spi->dev;
329         /* for now */
330         st->indio_dev->num_interrupt_lines = 0;
331         st->indio_dev->event_attrs = NULL;
332
333         st->indio_dev->attrs = &kxsd9_attribute_group;
334         st->indio_dev->dev_data = (void *)(st);
335         st->indio_dev->driver_module = THIS_MODULE;
336         st->indio_dev->modes = INDIO_DIRECT_MODE;
337
338         ret = iio_device_register(st->indio_dev);
339         if (ret)
340                 goto error_free_dev;
341
342         spi->mode = SPI_MODE_0;
343         spi_setup(spi);
344         kxsd9_power_up(spi);
345
346         return 0;
347
348 error_free_dev:
349         iio_free_device(st->indio_dev);
350 error_free_tx:
351         kfree(st->tx);
352 error_free_rx:
353         kfree(st->rx);
354 error_free_st:
355         kfree(st);
356 error_ret:
357         return ret;
358 }
359
360 static int __devexit kxsd9_remove(struct spi_device *spi)
361 {
362         struct kxsd9_state *st = spi_get_drvdata(spi);
363
364         iio_device_unregister(st->indio_dev);
365         kfree(st->tx);
366         kfree(st->rx);
367         kfree(st);
368
369         return 0;
370 }
371
372 static struct spi_driver kxsd9_driver = {
373         .driver = {
374                 .name = "kxsd9",
375                 .owner = THIS_MODULE,
376         },
377         .probe = kxsd9_probe,
378         .remove = __devexit_p(kxsd9_remove),
379 };
380
381 static __init int kxsd9_spi_init(void)
382 {
383         return spi_register_driver(&kxsd9_driver);
384 }
385 module_init(kxsd9_spi_init);
386
387 static __exit void kxsd9_spi_exit(void)
388 {
389         spi_unregister_driver(&kxsd9_driver);
390 }
391 module_exit(kxsd9_spi_exit);
392
393 MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
394 MODULE_DESCRIPTION("Kionix KXSD9 SPI driver");
395 MODULE_LICENSE("GPL v2");