aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorDenis Ciocca <denis.ciocca@gmail.com>2013-01-25 18:44:00 -0500
committerJonathan Cameron <jic23@kernel.org>2013-01-31 12:56:43 -0500
commit7be56a8f57b57cca1651fb97886e20246c168e25 (patch)
tree496822c782365a35e006ce3aa59c4c07248d9bda /drivers/iio
parentd62511689de5d34d3a07c43db1f46a234bb77b5f (diff)
iio:gyro: Add STMicroelectronics gyroscopes driver
This patch adds a generic gyroscope driver for STMicroelectronics gyroscopes, currently it supports: L3G4200D, LSM330DL, L3GD20, L3GD20H, LSM330DLC, L3G4IS, LSM330. Signed-off-by: Denis Ciocca <denis.ciocca@st.com> Reviewed-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/gyro/Kconfig30
-rw-r--r--drivers/iio/gyro/Makefile7
-rw-r--r--drivers/iio/gyro/st_gyro.h45
-rw-r--r--drivers/iio/gyro/st_gyro_buffer.c114
-rw-r--r--drivers/iio/gyro/st_gyro_core.c363
-rw-r--r--drivers/iio/gyro/st_gyro_i2c.c85
-rw-r--r--drivers/iio/gyro/st_gyro_spi.c84
7 files changed, 728 insertions, 0 deletions
diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig
index 752ac8a3448b..c9f177dd4cc7 100644
--- a/drivers/iio/gyro/Kconfig
+++ b/drivers/iio/gyro/Kconfig
@@ -30,4 +30,34 @@ config HID_SENSOR_GYRO_3D
30 Say yes here to build support for the HID SENSOR 30 Say yes here to build support for the HID SENSOR
31 Gyroscope 3D. 31 Gyroscope 3D.
32 32
33config IIO_ST_GYRO_3AXIS
34 tristate "STMicroelectronics gyroscopes 3-Axis Driver"
35 depends on (I2C || SPI_MASTER) && SYSFS
36 select IIO_ST_SENSORS_CORE
37 select IIO_ST_GYRO_I2C_3AXIS if (I2C)
38 select IIO_ST_GYRO_SPI_3AXIS if (SPI_MASTER)
39 select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
40 select IIO_ST_GYRO_BUFFER if (IIO_TRIGGERED_BUFFER)
41 help
42 Say yes here to build support for STMicroelectronics gyroscopes:
43 L3G4200D, LSM330DL, L3GD20, L3GD20H, LSM330DLC, L3G4IS, LSM330.
44
45 This driver can also be built as a module. If so, will be created
46 these modules:
47 - st_gyro (core functions for the driver [it is mandatory]);
48 - st_gyro_i2c (necessary for the I2C devices [optional*]);
49 - st_gyro_spi (necessary for the SPI devices [optional*]);
50
51 (*) one of these is necessary to do something.
52
53config IIO_ST_GYRO_I2C_3AXIS
54 tristate
55 depends on IIO_ST_GYRO_3AXIS
56 depends on IIO_ST_SENSORS_I2C
57
58config IIO_ST_GYRO_SPI_3AXIS
59 tristate
60 depends on IIO_ST_GYRO_3AXIS
61 depends on IIO_ST_SENSORS_SPI
62
33endmenu 63endmenu
diff --git a/drivers/iio/gyro/Makefile b/drivers/iio/gyro/Makefile
index 9b090ee084d3..66b517d9468a 100644
--- a/drivers/iio/gyro/Makefile
+++ b/drivers/iio/gyro/Makefile
@@ -5,3 +5,10 @@
5obj-$(CONFIG_ADIS16080) += adis16080.o 5obj-$(CONFIG_ADIS16080) += adis16080.o
6obj-$(CONFIG_ADIS16136) += adis16136.o 6obj-$(CONFIG_ADIS16136) += adis16136.o
7obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o 7obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o
8
9obj-$(CONFIG_IIO_ST_GYRO_3AXIS) += st_gyro.o
10st_gyro-y := st_gyro_core.o
11st_gyro-$(CONFIG_IIO_BUFFER) += st_gyro_buffer.o
12
13obj-$(CONFIG_IIO_ST_GYRO_I2C_3AXIS) += st_gyro_i2c.o
14obj-$(CONFIG_IIO_ST_GYRO_SPI_3AXIS) += st_gyro_spi.o
diff --git a/drivers/iio/gyro/st_gyro.h b/drivers/iio/gyro/st_gyro.h
new file mode 100644
index 000000000000..3ad9907bb154
--- /dev/null
+++ b/drivers/iio/gyro/st_gyro.h
@@ -0,0 +1,45 @@
1/*
2 * STMicroelectronics gyroscopes driver
3 *
4 * Copyright 2012-2013 STMicroelectronics Inc.
5 *
6 * Denis Ciocca <denis.ciocca@st.com>
7 * v. 1.0.0
8 * Licensed under the GPL-2.
9 */
10
11#ifndef ST_GYRO_H
12#define ST_GYRO_H
13
14#include <linux/types.h>
15#include <linux/iio/common/st_sensors.h>
16
17#define L3G4200D_GYRO_DEV_NAME "l3g4200d"
18#define LSM330D_GYRO_DEV_NAME "lsm330d_gyro"
19#define LSM330DL_GYRO_DEV_NAME "lsm330dl_gyro"
20#define LSM330DLC_GYRO_DEV_NAME "lsm330dlc_gyro"
21#define L3GD20_GYRO_DEV_NAME "l3gd20"
22#define L3GD20H_GYRO_DEV_NAME "l3gd20h"
23#define L3G4IS_GYRO_DEV_NAME "l3g4is_ui"
24#define LSM330_GYRO_DEV_NAME "lsm330_gyro"
25
26int st_gyro_common_probe(struct iio_dev *indio_dev);
27void st_gyro_common_remove(struct iio_dev *indio_dev);
28
29#ifdef CONFIG_IIO_BUFFER
30int st_gyro_allocate_ring(struct iio_dev *indio_dev);
31void st_gyro_deallocate_ring(struct iio_dev *indio_dev);
32int st_gyro_trig_set_state(struct iio_trigger *trig, bool state);
33#define ST_GYRO_TRIGGER_SET_STATE (&st_gyro_trig_set_state)
34#else /* CONFIG_IIO_BUFFER */
35static inline int st_gyro_allocate_ring(struct iio_dev *indio_dev)
36{
37 return 0;
38}
39static inline void st_gyro_deallocate_ring(struct iio_dev *indio_dev)
40{
41}
42#define ST_GYRO_TRIGGER_SET_STATE NULL
43#endif /* CONFIG_IIO_BUFFER */
44
45#endif /* ST_GYRO_H */
diff --git a/drivers/iio/gyro/st_gyro_buffer.c b/drivers/iio/gyro/st_gyro_buffer.c
new file mode 100644
index 000000000000..da4d122ec7dc
--- /dev/null
+++ b/drivers/iio/gyro/st_gyro_buffer.c
@@ -0,0 +1,114 @@
1/*
2 * STMicroelectronics gyroscopes driver
3 *
4 * Copyright 2012-2013 STMicroelectronics Inc.
5 *
6 * Denis Ciocca <denis.ciocca@st.com>
7 *
8 * Licensed under the GPL-2.
9 */
10
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/slab.h>
14#include <linux/stat.h>
15#include <linux/interrupt.h>
16#include <linux/i2c.h>
17#include <linux/delay.h>
18#include <linux/iio/iio.h>
19#include <linux/iio/buffer.h>
20#include <linux/iio/trigger_consumer.h>
21#include <linux/iio/triggered_buffer.h>
22
23#include <linux/iio/common/st_sensors.h>
24#include "st_gyro.h"
25
26int st_gyro_trig_set_state(struct iio_trigger *trig, bool state)
27{
28 struct iio_dev *indio_dev = trig->private_data;
29
30 return st_sensors_set_dataready_irq(indio_dev, state);
31}
32
33static int st_gyro_buffer_preenable(struct iio_dev *indio_dev)
34{
35 int err;
36
37 err = st_sensors_set_enable(indio_dev, true);
38 if (err < 0)
39 goto st_gyro_set_enable_error;
40
41 err = iio_sw_buffer_preenable(indio_dev);
42
43st_gyro_set_enable_error:
44 return err;
45}
46
47static int st_gyro_buffer_postenable(struct iio_dev *indio_dev)
48{
49 int err;
50 struct st_sensor_data *gdata = iio_priv(indio_dev);
51
52 gdata->buffer_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
53 if (gdata->buffer_data == NULL) {
54 err = -ENOMEM;
55 goto allocate_memory_error;
56 }
57
58 err = st_sensors_set_axis_enable(indio_dev,
59 (u8)indio_dev->active_scan_mask[0]);
60 if (err < 0)
61 goto st_gyro_buffer_postenable_error;
62
63 err = iio_triggered_buffer_postenable(indio_dev);
64 if (err < 0)
65 goto st_gyro_buffer_postenable_error;
66
67 return err;
68
69st_gyro_buffer_postenable_error:
70 kfree(gdata->buffer_data);
71allocate_memory_error:
72 return err;
73}
74
75static int st_gyro_buffer_predisable(struct iio_dev *indio_dev)
76{
77 int err;
78 struct st_sensor_data *gdata = iio_priv(indio_dev);
79
80 err = iio_triggered_buffer_predisable(indio_dev);
81 if (err < 0)
82 goto st_gyro_buffer_predisable_error;
83
84 err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
85 if (err < 0)
86 goto st_gyro_buffer_predisable_error;
87
88 err = st_sensors_set_enable(indio_dev, false);
89
90st_gyro_buffer_predisable_error:
91 kfree(gdata->buffer_data);
92 return err;
93}
94
95static const struct iio_buffer_setup_ops st_gyro_buffer_setup_ops = {
96 .preenable = &st_gyro_buffer_preenable,
97 .postenable = &st_gyro_buffer_postenable,
98 .predisable = &st_gyro_buffer_predisable,
99};
100
101int st_gyro_allocate_ring(struct iio_dev *indio_dev)
102{
103 return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
104 &st_sensors_trigger_handler, &st_gyro_buffer_setup_ops);
105}
106
107void st_gyro_deallocate_ring(struct iio_dev *indio_dev)
108{
109 iio_triggered_buffer_cleanup(indio_dev);
110}
111
112MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
113MODULE_DESCRIPTION("STMicroelectronics gyroscopes buffer");
114MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c
new file mode 100644
index 000000000000..0a09998276c0
--- /dev/null
+++ b/drivers/iio/gyro/st_gyro_core.c
@@ -0,0 +1,363 @@
1/*
2 * STMicroelectronics gyroscopes driver
3 *
4 * Copyright 2012-2013 STMicroelectronics Inc.
5 *
6 * Denis Ciocca <denis.ciocca@st.com>
7 *
8 * Licensed under the GPL-2.
9 */
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/slab.h>
14#include <linux/errno.h>
15#include <linux/types.h>
16#include <linux/mutex.h>
17#include <linux/interrupt.h>
18#include <linux/i2c.h>
19#include <linux/gpio.h>
20#include <linux/irq.h>
21#include <linux/delay.h>
22#include <linux/iio/iio.h>
23#include <linux/iio/sysfs.h>
24#include <linux/iio/trigger_consumer.h>
25#include <linux/iio/buffer.h>
26
27#include <linux/iio/common/st_sensors.h>
28#include "st_gyro.h"
29
30/* DEFAULT VALUE FOR SENSORS */
31#define ST_GYRO_DEFAULT_OUT_X_L_ADDR 0x28
32#define ST_GYRO_DEFAULT_OUT_Y_L_ADDR 0x2a
33#define ST_GYRO_DEFAULT_OUT_Z_L_ADDR 0x2c
34
35/* FULLSCALE */
36#define ST_GYRO_FS_AVL_250DPS 250
37#define ST_GYRO_FS_AVL_500DPS 500
38#define ST_GYRO_FS_AVL_2000DPS 2000
39
40/* CUSTOM VALUES FOR SENSOR 1 */
41#define ST_GYRO_1_WAI_EXP 0xd3
42#define ST_GYRO_1_ODR_ADDR 0x20
43#define ST_GYRO_1_ODR_MASK 0xc0
44#define ST_GYRO_1_ODR_AVL_100HZ_VAL 0x00
45#define ST_GYRO_1_ODR_AVL_200HZ_VAL 0x01
46#define ST_GYRO_1_ODR_AVL_400HZ_VAL 0x02
47#define ST_GYRO_1_ODR_AVL_800HZ_VAL 0x03
48#define ST_GYRO_1_PW_ADDR 0x20
49#define ST_GYRO_1_PW_MASK 0x08
50#define ST_GYRO_1_FS_ADDR 0x23
51#define ST_GYRO_1_FS_MASK 0x30
52#define ST_GYRO_1_FS_AVL_250_VAL 0x00
53#define ST_GYRO_1_FS_AVL_500_VAL 0x01
54#define ST_GYRO_1_FS_AVL_2000_VAL 0x02
55#define ST_GYRO_1_FS_AVL_250_GAIN IIO_DEGREE_TO_RAD(8750)
56#define ST_GYRO_1_FS_AVL_500_GAIN IIO_DEGREE_TO_RAD(17500)
57#define ST_GYRO_1_FS_AVL_2000_GAIN IIO_DEGREE_TO_RAD(70000)
58#define ST_GYRO_1_BDU_ADDR 0x23
59#define ST_GYRO_1_BDU_MASK 0x80
60#define ST_GYRO_1_DRDY_IRQ_ADDR 0x22
61#define ST_GYRO_1_DRDY_IRQ_MASK 0x08
62#define ST_GYRO_1_MULTIREAD_BIT true
63
64/* CUSTOM VALUES FOR SENSOR 2 */
65#define ST_GYRO_2_WAI_EXP 0xd4
66#define ST_GYRO_2_ODR_ADDR 0x20
67#define ST_GYRO_2_ODR_MASK 0xc0
68#define ST_GYRO_2_ODR_AVL_95HZ_VAL 0x00
69#define ST_GYRO_2_ODR_AVL_190HZ_VAL 0x01
70#define ST_GYRO_2_ODR_AVL_380HZ_VAL 0x02
71#define ST_GYRO_2_ODR_AVL_760HZ_VAL 0x03
72#define ST_GYRO_2_PW_ADDR 0x20
73#define ST_GYRO_2_PW_MASK 0x08
74#define ST_GYRO_2_FS_ADDR 0x23
75#define ST_GYRO_2_FS_MASK 0x30
76#define ST_GYRO_2_FS_AVL_250_VAL 0x00
77#define ST_GYRO_2_FS_AVL_500_VAL 0x01
78#define ST_GYRO_2_FS_AVL_2000_VAL 0x02
79#define ST_GYRO_2_FS_AVL_250_GAIN IIO_DEGREE_TO_RAD(8750)
80#define ST_GYRO_2_FS_AVL_500_GAIN IIO_DEGREE_TO_RAD(17500)
81#define ST_GYRO_2_FS_AVL_2000_GAIN IIO_DEGREE_TO_RAD(70000)
82#define ST_GYRO_2_BDU_ADDR 0x23
83#define ST_GYRO_2_BDU_MASK 0x80
84#define ST_GYRO_2_DRDY_IRQ_ADDR 0x22
85#define ST_GYRO_2_DRDY_IRQ_MASK 0x08
86#define ST_GYRO_2_MULTIREAD_BIT true
87
88static const struct iio_chan_spec st_gyro_16bit_channels[] = {
89 ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, ST_SENSORS_SCAN_X,
90 IIO_MOD_X, IIO_LE, ST_SENSORS_DEFAULT_16_REALBITS,
91 ST_GYRO_DEFAULT_OUT_X_L_ADDR),
92 ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, ST_SENSORS_SCAN_Y,
93 IIO_MOD_Y, IIO_LE, ST_SENSORS_DEFAULT_16_REALBITS,
94 ST_GYRO_DEFAULT_OUT_Y_L_ADDR),
95 ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, ST_SENSORS_SCAN_Z,
96 IIO_MOD_Z, IIO_LE, ST_SENSORS_DEFAULT_16_REALBITS,
97 ST_GYRO_DEFAULT_OUT_Z_L_ADDR),
98 IIO_CHAN_SOFT_TIMESTAMP(3)
99};
100
101static const struct st_sensors st_gyro_sensors[] = {
102 {
103 .wai = ST_GYRO_1_WAI_EXP,
104 .sensors_supported = {
105 [0] = L3G4200D_GYRO_DEV_NAME,
106 [1] = LSM330DL_GYRO_DEV_NAME,
107 },
108 .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
109 .odr = {
110 .addr = ST_GYRO_1_ODR_ADDR,
111 .mask = ST_GYRO_1_ODR_MASK,
112 .odr_avl = {
113 { 100, ST_GYRO_1_ODR_AVL_100HZ_VAL, },
114 { 200, ST_GYRO_1_ODR_AVL_200HZ_VAL, },
115 { 400, ST_GYRO_1_ODR_AVL_400HZ_VAL, },
116 { 800, ST_GYRO_1_ODR_AVL_800HZ_VAL, },
117 },
118 },
119 .pw = {
120 .addr = ST_GYRO_1_PW_ADDR,
121 .mask = ST_GYRO_1_PW_MASK,
122 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
123 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
124 },
125 .enable_axis = {
126 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
127 .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
128 },
129 .fs = {
130 .addr = ST_GYRO_1_FS_ADDR,
131 .mask = ST_GYRO_1_FS_MASK,
132 .fs_avl = {
133 [0] = {
134 .num = ST_GYRO_FS_AVL_250DPS,
135 .value = ST_GYRO_1_FS_AVL_250_VAL,
136 .gain = ST_GYRO_1_FS_AVL_250_GAIN,
137 },
138 [1] = {
139 .num = ST_GYRO_FS_AVL_500DPS,
140 .value = ST_GYRO_1_FS_AVL_500_VAL,
141 .gain = ST_GYRO_1_FS_AVL_500_GAIN,
142 },
143 [2] = {
144 .num = ST_GYRO_FS_AVL_2000DPS,
145 .value = ST_GYRO_1_FS_AVL_2000_VAL,
146 .gain = ST_GYRO_1_FS_AVL_2000_GAIN,
147 },
148 },
149 },
150 .bdu = {
151 .addr = ST_GYRO_1_BDU_ADDR,
152 .mask = ST_GYRO_1_BDU_MASK,
153 },
154 .drdy_irq = {
155 .addr = ST_GYRO_1_DRDY_IRQ_ADDR,
156 .mask = ST_GYRO_1_DRDY_IRQ_MASK,
157 },
158 .multi_read_bit = ST_GYRO_1_MULTIREAD_BIT,
159 .bootime = 2,
160 },
161 {
162 .wai = ST_GYRO_2_WAI_EXP,
163 .sensors_supported = {
164 [0] = L3GD20_GYRO_DEV_NAME,
165 [1] = L3GD20H_GYRO_DEV_NAME,
166 [2] = LSM330D_GYRO_DEV_NAME,
167 [3] = LSM330DLC_GYRO_DEV_NAME,
168 [4] = L3G4IS_GYRO_DEV_NAME,
169 [5] = LSM330_GYRO_DEV_NAME,
170 },
171 .ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
172 .odr = {
173 .addr = ST_GYRO_2_ODR_ADDR,
174 .mask = ST_GYRO_2_ODR_MASK,
175 .odr_avl = {
176 { 95, ST_GYRO_2_ODR_AVL_95HZ_VAL, },
177 { 190, ST_GYRO_2_ODR_AVL_190HZ_VAL, },
178 { 380, ST_GYRO_2_ODR_AVL_380HZ_VAL, },
179 { 760, ST_GYRO_2_ODR_AVL_760HZ_VAL, },
180 },
181 },
182 .pw = {
183 .addr = ST_GYRO_2_PW_ADDR,
184 .mask = ST_GYRO_2_PW_MASK,
185 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
186 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
187 },
188 .enable_axis = {
189 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
190 .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
191 },
192 .fs = {
193 .addr = ST_GYRO_2_FS_ADDR,
194 .mask = ST_GYRO_2_FS_MASK,
195 .fs_avl = {
196 [0] = {
197 .num = ST_GYRO_FS_AVL_250DPS,
198 .value = ST_GYRO_2_FS_AVL_250_VAL,
199 .gain = ST_GYRO_2_FS_AVL_250_GAIN,
200 },
201 [1] = {
202 .num = ST_GYRO_FS_AVL_500DPS,
203 .value = ST_GYRO_2_FS_AVL_500_VAL,
204 .gain = ST_GYRO_2_FS_AVL_500_GAIN,
205 },
206 [2] = {
207 .num = ST_GYRO_FS_AVL_2000DPS,
208 .value = ST_GYRO_2_FS_AVL_2000_VAL,
209 .gain = ST_GYRO_2_FS_AVL_2000_GAIN,
210 },
211 },
212 },
213 .bdu = {
214 .addr = ST_GYRO_2_BDU_ADDR,
215 .mask = ST_GYRO_2_BDU_MASK,
216 },
217 .drdy_irq = {
218 .addr = ST_GYRO_2_DRDY_IRQ_ADDR,
219 .mask = ST_GYRO_2_DRDY_IRQ_MASK,
220 },
221 .multi_read_bit = ST_GYRO_2_MULTIREAD_BIT,
222 .bootime = 2,
223 },
224};
225
226static int st_gyro_read_raw(struct iio_dev *indio_dev,
227 struct iio_chan_spec const *ch, int *val,
228 int *val2, long mask)
229{
230 int err;
231 struct st_sensor_data *gdata = iio_priv(indio_dev);
232
233 switch (mask) {
234 case IIO_CHAN_INFO_RAW:
235 err = st_sensors_read_info_raw(indio_dev, ch, val);
236 if (err < 0)
237 goto read_error;
238
239 return IIO_VAL_INT;
240 case IIO_CHAN_INFO_SCALE:
241 *val = 0;
242 *val2 = gdata->current_fullscale->gain;
243 return IIO_VAL_INT_PLUS_MICRO;
244 default:
245 return -EINVAL;
246 }
247
248read_error:
249 return err;
250}
251
252static int st_gyro_write_raw(struct iio_dev *indio_dev,
253 struct iio_chan_spec const *chan, int val, int val2, long mask)
254{
255 int err;
256
257 switch (mask) {
258 case IIO_CHAN_INFO_SCALE:
259 err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
260 break;
261 default:
262 err = -EINVAL;
263 }
264
265 return err;
266}
267
268static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
269static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
270static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_anglvel_scale_available);
271
272static struct attribute *st_gyro_attributes[] = {
273 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
274 &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
275 &iio_dev_attr_sampling_frequency.dev_attr.attr,
276 NULL,
277};
278
279static const struct attribute_group st_gyro_attribute_group = {
280 .attrs = st_gyro_attributes,
281};
282
283static const struct iio_info gyro_info = {
284 .driver_module = THIS_MODULE,
285 .attrs = &st_gyro_attribute_group,
286 .read_raw = &st_gyro_read_raw,
287 .write_raw = &st_gyro_write_raw,
288};
289
290static const struct iio_trigger_ops st_gyro_trigger_ops = {
291 .owner = THIS_MODULE,
292 .set_trigger_state = ST_GYRO_TRIGGER_SET_STATE,
293};
294
295int st_gyro_common_probe(struct iio_dev *indio_dev)
296{
297 int err;
298 struct st_sensor_data *gdata = iio_priv(indio_dev);
299
300 indio_dev->modes = INDIO_DIRECT_MODE;
301 indio_dev->info = &gyro_info;
302
303 err = st_sensors_check_device_support(indio_dev,
304 ARRAY_SIZE(st_gyro_sensors), st_gyro_sensors);
305 if (err < 0)
306 goto st_gyro_common_probe_error;
307
308 gdata->multiread_bit = gdata->sensor->multi_read_bit;
309 indio_dev->channels = gdata->sensor->ch;
310 indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
311
312 gdata->current_fullscale = (struct st_sensor_fullscale_avl *)
313 &gdata->sensor->fs.fs_avl[0];
314 gdata->odr = gdata->sensor->odr.odr_avl[0].hz;
315
316 err = st_sensors_init_sensor(indio_dev);
317 if (err < 0)
318 goto st_gyro_common_probe_error;
319
320 if (gdata->get_irq_data_ready(indio_dev) > 0) {
321 err = st_gyro_allocate_ring(indio_dev);
322 if (err < 0)
323 goto st_gyro_common_probe_error;
324
325 err = st_sensors_allocate_trigger(indio_dev,
326 &st_gyro_trigger_ops);
327 if (err < 0)
328 goto st_gyro_probe_trigger_error;
329 }
330
331 err = iio_device_register(indio_dev);
332 if (err)
333 goto st_gyro_device_register_error;
334
335 return err;
336
337st_gyro_device_register_error:
338 if (gdata->get_irq_data_ready(indio_dev) > 0)
339 st_sensors_deallocate_trigger(indio_dev);
340st_gyro_probe_trigger_error:
341 if (gdata->get_irq_data_ready(indio_dev) > 0)
342 st_gyro_deallocate_ring(indio_dev);
343st_gyro_common_probe_error:
344 return err;
345}
346EXPORT_SYMBOL(st_gyro_common_probe);
347
348void st_gyro_common_remove(struct iio_dev *indio_dev)
349{
350 struct st_sensor_data *gdata = iio_priv(indio_dev);
351
352 iio_device_unregister(indio_dev);
353 if (gdata->get_irq_data_ready(indio_dev) > 0) {
354 st_sensors_deallocate_trigger(indio_dev);
355 st_gyro_deallocate_ring(indio_dev);
356 }
357 iio_device_free(indio_dev);
358}
359EXPORT_SYMBOL(st_gyro_common_remove);
360
361MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
362MODULE_DESCRIPTION("STMicroelectronics gyroscopes driver");
363MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c
new file mode 100644
index 000000000000..a44b5b4a2013
--- /dev/null
+++ b/drivers/iio/gyro/st_gyro_i2c.c
@@ -0,0 +1,85 @@
1/*
2 * STMicroelectronics gyroscopes driver
3 *
4 * Copyright 2012-2013 STMicroelectronics Inc.
5 *
6 * Denis Ciocca <denis.ciocca@st.com>
7 *
8 * Licensed under the GPL-2.
9 */
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/slab.h>
14#include <linux/i2c.h>
15#include <linux/iio/iio.h>
16#include <linux/iio/trigger.h>
17
18#include <linux/iio/common/st_sensors.h>
19#include <linux/iio/common/st_sensors_i2c.h>
20#include "st_gyro.h"
21
22static int st_gyro_i2c_probe(struct i2c_client *client,
23 const struct i2c_device_id *id)
24{
25 struct iio_dev *indio_dev;
26 struct st_sensor_data *gdata;
27 int err;
28
29 indio_dev = iio_device_alloc(sizeof(*gdata));
30 if (indio_dev == NULL) {
31 err = -ENOMEM;
32 goto iio_device_alloc_error;
33 }
34
35 gdata = iio_priv(indio_dev);
36 gdata->dev = &client->dev;
37
38 st_sensors_i2c_configure(indio_dev, client, gdata);
39
40 err = st_gyro_common_probe(indio_dev);
41 if (err < 0)
42 goto st_gyro_common_probe_error;
43
44 return 0;
45
46st_gyro_common_probe_error:
47 iio_device_free(indio_dev);
48iio_device_alloc_error:
49 return err;
50}
51
52static int st_gyro_i2c_remove(struct i2c_client *client)
53{
54 st_gyro_common_remove(i2c_get_clientdata(client));
55
56 return 0;
57}
58
59static const struct i2c_device_id st_gyro_id_table[] = {
60 { L3G4200D_GYRO_DEV_NAME },
61 { LSM330D_GYRO_DEV_NAME },
62 { LSM330DL_GYRO_DEV_NAME },
63 { LSM330DLC_GYRO_DEV_NAME },
64 { L3GD20_GYRO_DEV_NAME },
65 { L3GD20H_GYRO_DEV_NAME },
66 { L3G4IS_GYRO_DEV_NAME },
67 { LSM330_GYRO_DEV_NAME },
68 {},
69};
70MODULE_DEVICE_TABLE(i2c, st_gyro_id_table);
71
72static struct i2c_driver st_gyro_driver = {
73 .driver = {
74 .owner = THIS_MODULE,
75 .name = "st-gyro-i2c",
76 },
77 .probe = st_gyro_i2c_probe,
78 .remove = st_gyro_i2c_remove,
79 .id_table = st_gyro_id_table,
80};
81module_i2c_driver(st_gyro_driver);
82
83MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
84MODULE_DESCRIPTION("STMicroelectronics gyroscopes i2c driver");
85MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/gyro/st_gyro_spi.c b/drivers/iio/gyro/st_gyro_spi.c
new file mode 100644
index 000000000000..8b4dcc5eab0c
--- /dev/null
+++ b/drivers/iio/gyro/st_gyro_spi.c
@@ -0,0 +1,84 @@
1/*
2 * STMicroelectronics gyroscopes driver
3 *
4 * Copyright 2012-2013 STMicroelectronics Inc.
5 *
6 * Denis Ciocca <denis.ciocca@st.com>
7 *
8 * Licensed under the GPL-2.
9 */
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/slab.h>
14#include <linux/spi/spi.h>
15#include <linux/iio/iio.h>
16#include <linux/iio/trigger.h>
17
18#include <linux/iio/common/st_sensors.h>
19#include <linux/iio/common/st_sensors_spi.h>
20#include "st_gyro.h"
21
22static int st_gyro_spi_probe(struct spi_device *spi)
23{
24 struct iio_dev *indio_dev;
25 struct st_sensor_data *gdata;
26 int err;
27
28 indio_dev = iio_device_alloc(sizeof(*gdata));
29 if (indio_dev == NULL) {
30 err = -ENOMEM;
31 goto iio_device_alloc_error;
32 }
33
34 gdata = iio_priv(indio_dev);
35 gdata->dev = &spi->dev;
36
37 st_sensors_spi_configure(indio_dev, spi, gdata);
38
39 err = st_gyro_common_probe(indio_dev);
40 if (err < 0)
41 goto st_gyro_common_probe_error;
42
43 return 0;
44
45st_gyro_common_probe_error:
46 iio_device_free(indio_dev);
47iio_device_alloc_error:
48 return err;
49}
50
51static int st_gyro_spi_remove(struct spi_device *spi)
52{
53 st_gyro_common_remove(spi_get_drvdata(spi));
54
55 return 0;
56}
57
58static const struct spi_device_id st_gyro_id_table[] = {
59 { L3G4200D_GYRO_DEV_NAME },
60 { LSM330D_GYRO_DEV_NAME },
61 { LSM330DL_GYRO_DEV_NAME },
62 { LSM330DLC_GYRO_DEV_NAME },
63 { L3GD20_GYRO_DEV_NAME },
64 { L3GD20H_GYRO_DEV_NAME },
65 { L3G4IS_GYRO_DEV_NAME },
66 { LSM330_GYRO_DEV_NAME },
67 {},
68};
69MODULE_DEVICE_TABLE(spi, st_gyro_id_table);
70
71static struct spi_driver st_gyro_driver = {
72 .driver = {
73 .owner = THIS_MODULE,
74 .name = "st-gyro-spi",
75 },
76 .probe = st_gyro_spi_probe,
77 .remove = st_gyro_spi_remove,
78 .id_table = st_gyro_id_table,
79};
80module_spi_driver(st_gyro_driver);
81
82MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
83MODULE_DESCRIPTION("STMicroelectronics gyroscopes spi driver");
84MODULE_LICENSE("GPL v2");