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>
31 #include "../adc/adc.h"
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
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
47 #define KXSD9_REG_CTRL_B 0x0d
48 #define KXSD9_REG_CTRL_A 0x0e
50 #define KXSD9_READ(a) (0x80 | (a))
51 #define KXSD9_WRITE(a) (a)
53 #define IIO_DEV_ATTR_ACCEL_SET_RANGE(_mode, _show, _store) \
54 IIO_DEVICE_ATTR(accel_range, _mode, _show, _store, 0)
56 #define KXSD9_STATE_RX_SIZE 2
57 #define KXSD9_STATE_TX_SIZE 4
59 * struct kxsd9_state - device related storage
60 * @buf_lock: protect the rx and tx buffers.
61 * @indio_dev: associated industrial IO device
63 * @rx: single rx buffer storage
64 * @tx: single tx buffer storage
67 struct mutex buf_lock
;
68 struct iio_dev
*indio_dev
;
69 struct spi_device
*us
;
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
,
81 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
82 struct kxsd9_state
*st
= indio_dev
->dev_data
;
83 struct spi_transfer xfer
= {
90 struct spi_message msg
;
92 mutex_lock(&st
->buf_lock
);
93 st
->tx
[0] = KXSD9_READ(KXSD9_REG_CTRL_C
);
95 spi_message_init(&msg
);
96 spi_message_add_tail(&xfer
, &msg
);
97 ret
= spi_sync(st
->us
, &msg
);
101 switch (st
->rx
[1] & KXSD9_FS_MASK
) {
103 len
+= sprintf(buf
, "8\n");
106 len
+= sprintf(buf
, "6\n");
109 len
+= sprintf(buf
, "4\n");
112 len
+= sprintf(buf
, "2\n");
117 mutex_unlock(&st
->buf_lock
);
119 return ret
? ret
: len
;
121 static ssize_t
kxsd9_write_accel_range(struct device
*dev
,
122 struct device_attribute
*attr
,
127 struct spi_message msg
;
129 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
130 struct kxsd9_state
*st
= indio_dev
->dev_data
;
132 struct spi_transfer xfers
[] = {
147 ret
= strict_strtol(buf
, 10, &readin
);
166 mutex_lock(&st
->buf_lock
);
167 st
->tx
[0] = KXSD9_READ(KXSD9_REG_CTRL_C
);
169 spi_message_init(&msg
);
170 spi_message_add_tail(&xfers
[0], &msg
);
171 ret
= spi_sync(st
->us
, &msg
);
174 st
->tx
[0] = KXSD9_WRITE(KXSD9_REG_CTRL_C
);
175 st
->tx
[1] = (st
->rx
[1] & ~KXSD9_FS_MASK
) | val
;
177 spi_message_init(&msg
);
178 spi_message_add_tail(&xfers
[1], &msg
);
179 ret
= spi_sync(st
->us
, &msg
);
181 mutex_unlock(&st
->buf_lock
);
182 return ret
? ret
: len
;
184 static ssize_t
kxsd9_read_accel(struct device
*dev
,
185 struct device_attribute
*attr
,
188 struct spi_message msg
;
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
[] = {
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
);
218 val
= (((u16
)(st
->rx
[0])) << 8) | (st
->rx
[1] & 0xF0);
219 len
= sprintf(buf
, "%d\n", val
);
221 mutex_unlock(&st
->buf_lock
);
223 return ret
? ret
: len
;
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
);
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
,
243 static const struct attribute_group kxsd9_attribute_group
= {
244 .attrs
= kxsd9_attributes
,
247 static int __devinit
kxsd9_power_up(struct spi_device
*spi
)
250 struct spi_transfer xfers
[2] = {
261 struct spi_message msg
;
263 u8
*tx
= kmalloc(2, GFP_KERNEL
);
269 tx2
= kmalloc(2, GFP_KERNEL
);
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
);
295 static int __devinit
kxsd9_probe(struct spi_device
*spi
)
298 struct kxsd9_state
*st
;
301 st
= kzalloc(sizeof(*st
), GFP_KERNEL
);
306 spi_set_drvdata(spi
, st
);
308 st
->rx
= kmalloc(sizeof(*st
->rx
)*KXSD9_STATE_RX_SIZE
,
310 if (st
->rx
== NULL
) {
314 st
->tx
= kmalloc(sizeof(*st
->tx
)*KXSD9_STATE_TX_SIZE
,
316 if (st
->tx
== NULL
) {
322 mutex_init(&st
->buf_lock
);
323 st
->indio_dev
= iio_allocate_device();
324 if (st
->indio_dev
== NULL
) {
328 st
->indio_dev
->dev
.parent
= &spi
->dev
;
330 st
->indio_dev
->num_interrupt_lines
= 0;
331 st
->indio_dev
->event_attrs
= NULL
;
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
;
338 ret
= iio_device_register(st
->indio_dev
);
342 spi
->mode
= SPI_MODE_0
;
349 iio_free_device(st
->indio_dev
);
360 static int __devexit
kxsd9_remove(struct spi_device
*spi
)
362 struct kxsd9_state
*st
= spi_get_drvdata(spi
);
364 iio_device_unregister(st
->indio_dev
);
372 static struct spi_driver kxsd9_driver
= {
375 .owner
= THIS_MODULE
,
377 .probe
= kxsd9_probe
,
378 .remove
= __devexit_p(kxsd9_remove
),
381 static __init
int kxsd9_spi_init(void)
383 return spi_register_driver(&kxsd9_driver
);
385 module_init(kxsd9_spi_init
);
387 static __exit
void kxsd9_spi_exit(void)
389 spi_unregister_driver(&kxsd9_driver
);
391 module_exit(kxsd9_spi_exit
);
393 MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
394 MODULE_DESCRIPTION("Kionix KXSD9 SPI driver");
395 MODULE_LICENSE("GPL v2");