2 * kxsd9.c simple support for the Kionix KXSD9 3D
5 * Copyright (c) 2008-2009 Jonathan Cameron <jic23@cam.ac.uk>
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.
11 * The i2c interface is very similar, so shouldn't be a problem once
12 * I have a suitable wire made up.
14 * TODO: Support the motion detector
15 * Uses register address incrementing so could have a
16 * heavily optimized ring buffer access function.
19 #include <linux/interrupt.h>
20 #include <linux/gpio.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 #include <linux/slab.h>
32 #include "../adc/adc.h"
35 #define KXSD9_REG_X 0x00
36 #define KXSD9_REG_Y 0x02
37 #define KXSD9_REG_Z 0x04
38 #define KXSD9_REG_AUX 0x06
39 #define KXSD9_REG_RESET 0x0a
40 #define KXSD9_REG_CTRL_C 0x0c
42 #define KXSD9_FS_8 0x00
43 #define KXSD9_FS_6 0x01
44 #define KXSD9_FS_4 0x02
45 #define KXSD9_FS_2 0x03
46 #define KXSD9_FS_MASK 0x03
48 #define KXSD9_REG_CTRL_B 0x0d
49 #define KXSD9_REG_CTRL_A 0x0e
51 #define KXSD9_READ(a) (0x80 | (a))
52 #define KXSD9_WRITE(a) (a)
54 #define IIO_DEV_ATTR_ACCEL_SET_RANGE(_mode, _show, _store) \
55 IIO_DEVICE_ATTR(accel_range, _mode, _show, _store, 0)
57 #define KXSD9_STATE_RX_SIZE 2
58 #define KXSD9_STATE_TX_SIZE 4
60 * struct kxsd9_state - device related storage
61 * @buf_lock: protect the rx and tx buffers.
62 * @indio_dev: associated industrial IO device
64 * @rx: single rx buffer storage
65 * @tx: single tx buffer storage
68 struct mutex buf_lock
;
69 struct iio_dev
*indio_dev
;
70 struct spi_device
*us
;
75 /* This may want to move to mili g to allow for non integer ranges */
76 static ssize_t
kxsd9_read_accel_range(struct device
*dev
,
77 struct device_attribute
*attr
,
82 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
83 struct kxsd9_state
*st
= indio_dev
->dev_data
;
84 struct spi_transfer xfer
= {
91 struct spi_message msg
;
93 mutex_lock(&st
->buf_lock
);
94 st
->tx
[0] = KXSD9_READ(KXSD9_REG_CTRL_C
);
96 spi_message_init(&msg
);
97 spi_message_add_tail(&xfer
, &msg
);
98 ret
= spi_sync(st
->us
, &msg
);
102 switch (st
->rx
[1] & KXSD9_FS_MASK
) {
104 len
+= sprintf(buf
, "8\n");
107 len
+= sprintf(buf
, "6\n");
110 len
+= sprintf(buf
, "4\n");
113 len
+= sprintf(buf
, "2\n");
118 mutex_unlock(&st
->buf_lock
);
120 return ret
? ret
: len
;
122 static ssize_t
kxsd9_write_accel_range(struct device
*dev
,
123 struct device_attribute
*attr
,
128 struct spi_message msg
;
130 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
131 struct kxsd9_state
*st
= indio_dev
->dev_data
;
133 struct spi_transfer xfers
[] = {
148 ret
= strict_strtol(buf
, 10, &readin
);
167 mutex_lock(&st
->buf_lock
);
168 st
->tx
[0] = KXSD9_READ(KXSD9_REG_CTRL_C
);
170 spi_message_init(&msg
);
171 spi_message_add_tail(&xfers
[0], &msg
);
172 ret
= spi_sync(st
->us
, &msg
);
175 st
->tx
[0] = KXSD9_WRITE(KXSD9_REG_CTRL_C
);
176 st
->tx
[1] = (st
->rx
[1] & ~KXSD9_FS_MASK
) | val
;
178 spi_message_init(&msg
);
179 spi_message_add_tail(&xfers
[1], &msg
);
180 ret
= spi_sync(st
->us
, &msg
);
182 mutex_unlock(&st
->buf_lock
);
183 return ret
? ret
: len
;
185 static ssize_t
kxsd9_read_accel(struct device
*dev
,
186 struct device_attribute
*attr
,
189 struct spi_message msg
;
193 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
194 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
195 struct kxsd9_state
*st
= indio_dev
->dev_data
;
196 struct spi_transfer xfers
[] = {
211 mutex_lock(&st
->buf_lock
);
212 st
->tx
[0] = KXSD9_READ(this_attr
->address
);
213 spi_message_init(&msg
);
214 spi_message_add_tail(&xfers
[0], &msg
);
215 spi_message_add_tail(&xfers
[1], &msg
);
216 ret
= spi_sync(st
->us
, &msg
);
219 val
= (((u16
)(st
->rx
[0])) << 8) | (st
->rx
[1] & 0xF0);
220 len
= sprintf(buf
, "%d\n", val
);
222 mutex_unlock(&st
->buf_lock
);
224 return ret
? ret
: len
;
227 static IIO_DEV_ATTR_ACCEL_X(kxsd9_read_accel
, KXSD9_REG_X
);
228 static IIO_DEV_ATTR_ACCEL_Y(kxsd9_read_accel
, KXSD9_REG_Y
);
229 static IIO_DEV_ATTR_ACCEL_Z(kxsd9_read_accel
, KXSD9_REG_Z
);
230 static IIO_DEV_ATTR_ADC(0, kxsd9_read_accel
, KXSD9_REG_AUX
);
231 static IIO_DEV_ATTR_ACCEL_SET_RANGE(S_IRUGO
| S_IWUSR
,
232 kxsd9_read_accel_range
,
233 kxsd9_write_accel_range
);
235 static struct attribute
*kxsd9_attributes
[] = {
236 &iio_dev_attr_accel_x
.dev_attr
.attr
,
237 &iio_dev_attr_accel_y
.dev_attr
.attr
,
238 &iio_dev_attr_accel_z
.dev_attr
.attr
,
239 &iio_dev_attr_adc_0
.dev_attr
.attr
,
240 &iio_dev_attr_accel_range
.dev_attr
.attr
,
244 static const struct attribute_group kxsd9_attribute_group
= {
245 .attrs
= kxsd9_attributes
,
248 static int __devinit
kxsd9_power_up(struct spi_device
*spi
)
251 struct spi_transfer xfers
[2] = {
262 struct spi_message msg
;
264 u8
*tx
= kmalloc(2, GFP_KERNEL
);
270 tx2
= kmalloc(2, GFP_KERNEL
);
281 xfers
[0].tx_buf
= tx
;
282 xfers
[1].tx_buf
= tx2
;
283 spi_message_init(&msg
);
284 spi_message_add_tail(&xfers
[0], &msg
);
285 spi_message_add_tail(&xfers
[1], &msg
);
286 ret
= spi_sync(spi
, &msg
);
296 static int __devinit
kxsd9_probe(struct spi_device
*spi
)
299 struct kxsd9_state
*st
;
302 st
= kzalloc(sizeof(*st
), GFP_KERNEL
);
307 spi_set_drvdata(spi
, st
);
309 st
->rx
= kmalloc(sizeof(*st
->rx
)*KXSD9_STATE_RX_SIZE
,
311 if (st
->rx
== NULL
) {
315 st
->tx
= kmalloc(sizeof(*st
->tx
)*KXSD9_STATE_TX_SIZE
,
317 if (st
->tx
== NULL
) {
323 mutex_init(&st
->buf_lock
);
324 st
->indio_dev
= iio_allocate_device();
325 if (st
->indio_dev
== NULL
) {
329 st
->indio_dev
->dev
.parent
= &spi
->dev
;
331 st
->indio_dev
->num_interrupt_lines
= 0;
332 st
->indio_dev
->event_attrs
= NULL
;
334 st
->indio_dev
->attrs
= &kxsd9_attribute_group
;
335 st
->indio_dev
->dev_data
= (void *)(st
);
336 st
->indio_dev
->driver_module
= THIS_MODULE
;
337 st
->indio_dev
->modes
= INDIO_DIRECT_MODE
;
339 ret
= iio_device_register(st
->indio_dev
);
343 spi
->mode
= SPI_MODE_0
;
350 iio_free_device(st
->indio_dev
);
361 static int __devexit
kxsd9_remove(struct spi_device
*spi
)
363 struct kxsd9_state
*st
= spi_get_drvdata(spi
);
365 iio_device_unregister(st
->indio_dev
);
373 static struct spi_driver kxsd9_driver
= {
376 .owner
= THIS_MODULE
,
378 .probe
= kxsd9_probe
,
379 .remove
= __devexit_p(kxsd9_remove
),
382 static __init
int kxsd9_spi_init(void)
384 return spi_register_driver(&kxsd9_driver
);
386 module_init(kxsd9_spi_init
);
388 static __exit
void kxsd9_spi_exit(void)
390 spi_unregister_driver(&kxsd9_driver
);
392 module_exit(kxsd9_spi_exit
);
394 MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
395 MODULE_DESCRIPTION("Kionix KXSD9 SPI driver");
396 MODULE_LICENSE("GPL v2");