aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/iio/gyro
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/staging/iio/gyro
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/staging/iio/gyro')
-rw-r--r--drivers/staging/iio/gyro/adis16260_ring.c155
-rw-r--r--drivers/staging/iio/gyro/adis16260_trigger.c76
-rw-r--r--drivers/staging/iio/gyro/gyro.h85
3 files changed, 316 insertions, 0 deletions
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
new file mode 100644
index 00000000000..a4df8b32251
--- /dev/null
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -0,0 +1,155 @@
1#include <linux/interrupt.h>
2#include <linux/irq.h>
3#include <linux/gpio.h>
4#include <linux/workqueue.h>
5#include <linux/mutex.h>
6#include <linux/device.h>
7#include <linux/kernel.h>
8#include <linux/spi/spi.h>
9#include <linux/slab.h>
10#include <linux/sysfs.h>
11#include <linux/list.h>
12
13#include "../iio.h"
14#include "../sysfs.h"
15#include "../ring_sw.h"
16#include "../accel/accel.h"
17#include "../trigger.h"
18#include "adis16260.h"
19
20/**
21 * adis16260_read_ring_data() read data registers which will be placed into ring
22 * @dev: device associated with child of actual device (iio_dev or iio_trig)
23 * @rx: somewhere to pass back the value read
24 **/
25static int adis16260_read_ring_data(struct device *dev, u8 *rx)
26{
27 struct spi_message msg;
28 struct iio_dev *indio_dev = dev_get_drvdata(dev);
29 struct adis16260_state *st = iio_priv(indio_dev);
30 struct spi_transfer xfers[ADIS16260_OUTPUTS + 1];
31 int ret;
32 int i;
33
34 mutex_lock(&st->buf_lock);
35
36 spi_message_init(&msg);
37
38 memset(xfers, 0, sizeof(xfers));
39 for (i = 0; i <= ADIS16260_OUTPUTS; i++) {
40 xfers[i].bits_per_word = 8;
41 xfers[i].cs_change = 1;
42 xfers[i].len = 2;
43 xfers[i].delay_usecs = 30;
44 xfers[i].tx_buf = st->tx + 2 * i;
45 if (i < 2) /* SUPPLY_OUT:0x02 GYRO_OUT:0x04 */
46 st->tx[2 * i]
47 = ADIS16260_READ_REG(ADIS16260_SUPPLY_OUT
48 + 2 * i);
49 else /* 0x06 to 0x09 is reserved */
50 st->tx[2 * i]
51 = ADIS16260_READ_REG(ADIS16260_SUPPLY_OUT
52 + 2 * i + 4);
53 st->tx[2 * i + 1] = 0;
54 if (i >= 1)
55 xfers[i].rx_buf = rx + 2 * (i - 1);
56 spi_message_add_tail(&xfers[i], &msg);
57 }
58
59 ret = spi_sync(st->us, &msg);
60 if (ret)
61 dev_err(&st->us->dev, "problem when burst reading");
62
63 mutex_unlock(&st->buf_lock);
64
65 return ret;
66}
67
68static irqreturn_t adis16260_trigger_handler(int irq, void *p)
69{
70 struct iio_poll_func *pf = p;
71 struct iio_dev *indio_dev = pf->private_data;
72 struct adis16260_state *st = iio_priv(indio_dev);
73 struct iio_ring_buffer *ring = indio_dev->ring;
74 int i = 0;
75 s16 *data;
76 size_t datasize = ring->access->get_bytes_per_datum(ring);
77
78 data = kmalloc(datasize , GFP_KERNEL);
79 if (data == NULL) {
80 dev_err(&st->us->dev, "memory alloc failed in ring bh");
81 return -ENOMEM;
82 }
83
84 if (ring->scan_count &&
85 adis16260_read_ring_data(&indio_dev->dev, st->rx) >= 0)
86 for (; i < ring->scan_count; i++)
87 data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
88
89 /* Guaranteed to be aligned with 8 byte boundary */
90 if (ring->scan_timestamp)
91 *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
92
93 ring->access->store_to(ring, (u8 *)data, pf->timestamp);
94
95 iio_trigger_notify_done(indio_dev->trig);
96 kfree(data);
97
98 return IRQ_HANDLED;
99}
100
101void adis16260_unconfigure_ring(struct iio_dev *indio_dev)
102{
103 iio_dealloc_pollfunc(indio_dev->pollfunc);
104 iio_sw_rb_free(indio_dev->ring);
105}
106
107static const struct iio_ring_setup_ops adis16260_ring_setup_ops = {
108 .preenable = &iio_sw_ring_preenable,
109 .postenable = &iio_triggered_ring_postenable,
110 .predisable = &iio_triggered_ring_predisable,
111};
112
113int adis16260_configure_ring(struct iio_dev *indio_dev)
114{
115 int ret = 0;
116 struct iio_ring_buffer *ring;
117
118 ring = iio_sw_rb_allocate(indio_dev);
119 if (!ring) {
120 ret = -ENOMEM;
121 return ret;
122 }
123 indio_dev->ring = ring;
124 /* Effectively select the ring buffer implementation */
125 ring->access = &ring_sw_access_funcs;
126 ring->bpe = 2;
127 ring->scan_timestamp = true;
128 ring->setup_ops = &adis16260_ring_setup_ops;
129 ring->owner = THIS_MODULE;
130
131 /* Set default scan mode */
132 iio_scan_mask_set(ring, ADIS16260_SCAN_SUPPLY);
133 iio_scan_mask_set(ring, ADIS16260_SCAN_GYRO);
134 iio_scan_mask_set(ring, ADIS16260_SCAN_AUX_ADC);
135 iio_scan_mask_set(ring, ADIS16260_SCAN_TEMP);
136 iio_scan_mask_set(ring, ADIS16260_SCAN_ANGL);
137
138 indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
139 &adis16260_trigger_handler,
140 IRQF_ONESHOT,
141 indio_dev,
142 "adis16260_consumer%d",
143 indio_dev->id);
144 if (indio_dev->pollfunc == NULL) {
145 ret = -ENOMEM;
146 goto error_iio_sw_rb_free;
147 }
148
149 indio_dev->modes |= INDIO_RING_TRIGGERED;
150 return 0;
151
152error_iio_sw_rb_free:
153 iio_sw_rb_free(indio_dev->ring);
154 return ret;
155}
diff --git a/drivers/staging/iio/gyro/adis16260_trigger.c b/drivers/staging/iio/gyro/adis16260_trigger.c
new file mode 100644
index 00000000000..01094d0e714
--- /dev/null
+++ b/drivers/staging/iio/gyro/adis16260_trigger.c
@@ -0,0 +1,76 @@
1#include <linux/interrupt.h>
2#include <linux/irq.h>
3#include <linux/mutex.h>
4#include <linux/device.h>
5#include <linux/kernel.h>
6#include <linux/sysfs.h>
7#include <linux/list.h>
8#include <linux/spi/spi.h>
9
10#include "../iio.h"
11#include "../sysfs.h"
12#include "../trigger.h"
13#include "adis16260.h"
14
15/**
16 * adis16260_data_rdy_trigger_set_state() set datardy interrupt state
17 **/
18static int adis16260_data_rdy_trigger_set_state(struct iio_trigger *trig,
19 bool state)
20{
21 struct iio_dev *indio_dev = trig->private_data;
22
23 dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
24 return adis16260_set_irq(indio_dev, state);
25}
26
27int adis16260_probe_trigger(struct iio_dev *indio_dev)
28{
29 int ret;
30 struct adis16260_state *st = iio_priv(indio_dev);
31
32 st->trig = iio_allocate_trigger("%s-dev%d",
33 spi_get_device_id(st->us)->name,
34 indio_dev->id);
35 if (st->trig == NULL) {
36 ret = -ENOMEM;
37 goto error_ret;
38 }
39
40 ret = request_irq(st->us->irq,
41 &iio_trigger_generic_data_rdy_poll,
42 IRQF_TRIGGER_RISING,
43 "adis16260",
44 st->trig);
45 if (ret)
46 goto error_free_trig;
47
48 st->trig->dev.parent = &st->us->dev;
49 st->trig->owner = THIS_MODULE;
50 st->trig->private_data = indio_dev;
51 st->trig->set_trigger_state = &adis16260_data_rdy_trigger_set_state;
52 ret = iio_trigger_register(st->trig);
53
54 /* select default trigger */
55 indio_dev->trig = st->trig;
56 if (ret)
57 goto error_free_irq;
58
59 return 0;
60
61error_free_irq:
62 free_irq(st->us->irq, st->trig);
63error_free_trig:
64 iio_free_trigger(st->trig);
65error_ret:
66 return ret;
67}
68
69void adis16260_remove_trigger(struct iio_dev *indio_dev)
70{
71 struct adis16260_state *st = iio_priv(indio_dev);
72
73 iio_trigger_unregister(st->trig);
74 free_irq(st->us->irq, st->trig);
75 iio_free_trigger(st->trig);
76}
diff --git a/drivers/staging/iio/gyro/gyro.h b/drivers/staging/iio/gyro/gyro.h
new file mode 100644
index 00000000000..b5495613407
--- /dev/null
+++ b/drivers/staging/iio/gyro/gyro.h
@@ -0,0 +1,85 @@
1
2#include "../sysfs.h"
3
4/* Gyroscope types of attribute */
5
6#define IIO_CONST_ATTR_GYRO_OFFSET(_string) \
7 IIO_CONST_ATTR(gyro_offset, _string)
8
9#define IIO_DEV_ATTR_GYRO_OFFSET(_mode, _show, _store, _addr) \
10 IIO_DEVICE_ATTR(gyro_offset, _mode, _show, _store, _addr)
11
12#define IIO_DEV_ATTR_GYRO_X_OFFSET(_mode, _show, _store, _addr) \
13 IIO_DEVICE_ATTR(gyro_x_offset, _mode, _show, _store, _addr)
14
15#define IIO_DEV_ATTR_GYRO_Y_OFFSET(_mode, _show, _store, _addr) \
16 IIO_DEVICE_ATTR(gyro_y_offset, _mode, _show, _store, _addr)
17
18#define IIO_DEV_ATTR_GYRO_Z_OFFSET(_mode, _show, _store, _addr) \
19 IIO_DEVICE_ATTR(gyro_z_offset, _mode, _show, _store, _addr)
20
21#define IIO_CONST_ATTR_GYRO_SCALE(_string) \
22 IIO_CONST_ATTR(gyro_scale, _string)
23
24#define IIO_DEV_ATTR_GYRO_SCALE(_mode, _show, _store, _addr) \
25 IIO_DEVICE_ATTR(gyro_scale, S_IRUGO, _show, _store, _addr)
26
27#define IIO_DEV_ATTR_GYRO_X_SCALE(_mode, _show, _store, _addr) \
28 IIO_DEVICE_ATTR(gyro_x_scale, _mode, _show, _store, _addr)
29
30#define IIO_DEV_ATTR_GYRO_Y_SCALE(_mode, _show, _store, _addr) \
31 IIO_DEVICE_ATTR(gyro_y_scale, _mode, _show, _store, _addr)
32
33#define IIO_DEV_ATTR_GYRO_Z_SCALE(_mode, _show, _store, _addr) \
34 IIO_DEVICE_ATTR(gyro_z_scale, _mode, _show, _store, _addr)
35
36#define IIO_DEV_ATTR_GYRO_CALIBBIAS(_mode, _show, _store, _addr) \
37 IIO_DEVICE_ATTR(gyro_calibbias, S_IRUGO, _show, _store, _addr)
38
39#define IIO_DEV_ATTR_GYRO_X_CALIBBIAS(_mode, _show, _store, _addr) \
40 IIO_DEVICE_ATTR(gyro_x_calibbias, _mode, _show, _store, _addr)
41
42#define IIO_DEV_ATTR_GYRO_Y_CALIBBIAS(_mode, _show, _store, _addr) \
43 IIO_DEVICE_ATTR(gyro_y_calibbias, _mode, _show, _store, _addr)
44
45#define IIO_DEV_ATTR_GYRO_Z_CALIBBIAS(_mode, _show, _store, _addr) \
46 IIO_DEVICE_ATTR(gyro_z_calibbias, _mode, _show, _store, _addr)
47
48#define IIO_DEV_ATTR_GYRO_CALIBSCALE(_mode, _show, _store, _addr) \
49 IIO_DEVICE_ATTR(gyro_calibscale, S_IRUGO, _show, _store, _addr)
50
51#define IIO_DEV_ATTR_GYRO_X_CALIBSCALE(_mode, _show, _store, _addr) \
52 IIO_DEVICE_ATTR(gyro_x_calibscale, _mode, _show, _store, _addr)
53
54#define IIO_DEV_ATTR_GYRO_Y_CALIBSCALE(_mode, _show, _store, _addr) \
55 IIO_DEVICE_ATTR(gyro_y_calibscale, _mode, _show, _store, _addr)
56
57#define IIO_DEV_ATTR_GYRO_Z_CALIBSCALE(_mode, _show, _store, _addr) \
58 IIO_DEVICE_ATTR(gyro_z_calibscale, _mode, _show, _store, _addr)
59
60#define IIO_DEV_ATTR_GYRO_Z_QUADRATURE_CORRECTION(_show, _addr) \
61 IIO_DEVICE_ATTR(gyro_z_quadrature_correction_raw, S_IRUGO, _show, NULL, _addr)
62
63#define IIO_DEV_ATTR_GYRO(_show, _addr) \
64 IIO_DEVICE_ATTR(gyro_raw, S_IRUGO, _show, NULL, _addr)
65
66#define IIO_DEV_ATTR_GYRO_X(_show, _addr) \
67 IIO_DEVICE_ATTR(gyro_x_raw, S_IRUGO, _show, NULL, _addr)
68
69#define IIO_DEV_ATTR_GYRO_Y(_show, _addr) \
70 IIO_DEVICE_ATTR(gyro_y_raw, S_IRUGO, _show, NULL, _addr)
71
72#define IIO_DEV_ATTR_GYRO_Z(_show, _addr) \
73 IIO_DEVICE_ATTR(gyro_z_raw, S_IRUGO, _show, NULL, _addr)
74
75#define IIO_DEV_ATTR_ANGL(_show, _addr) \
76 IIO_DEVICE_ATTR(angl_raw, S_IRUGO, _show, NULL, _addr)
77
78#define IIO_DEV_ATTR_ANGL_X(_show, _addr) \
79 IIO_DEVICE_ATTR(angl_x_raw, S_IRUGO, _show, NULL, _addr)
80
81#define IIO_DEV_ATTR_ANGL_Y(_show, _addr) \
82 IIO_DEVICE_ATTR(angl_y_raw, S_IRUGO, _show, NULL, _addr)
83
84#define IIO_DEV_ATTR_ANGL_Z(_show, _addr) \
85 IIO_DEVICE_ATTR(angl_z_raw, S_IRUGO, _show, NULL, _addr)