aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-02-05 14:25:37 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-02-05 14:25:37 -0500
commit4e98fcfb95dfd9c40976dcfa2f3b878eeec4dbaa (patch)
tree8afe7ff2f2a3bf960dfd637bfa1ae56838f9f0bb
parentcc400e185c07c15a42d2635995f422de5b94b696 (diff)
parent6cb2afd7c0abb93bd9dc6d36b858b1e312e2407d (diff)
Merge tag 'iio-for-3.9c' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes: "Third set of IIO new drivers, cleanups and fixes for the 3.9 cycle New drivers 1) A driver for ST microelectronics sensors. This driver already covers a large set of new parts (20 gyros, accelerometer and magnetometers) not currently covered by the existing drivers. The intent moving forward is to merge this with the other drivers for similar parts already in tree. The lis3l02dq driver currently in staging/iio will be trivial, the lis3 driver in misc more complex as it has a number of additional interfaces. Any merging in of the lis3 driver will rely on the not currently merged iio_input bridge driver and handling of freefall notifications etc. 2) A driver for the itg3200 gyroscope. Graduations from staging 1) Cleanup and move out of staging of the adxrs450 gyroscope driver. The cleanup required was all minor but there were a couple of fixes hidden in there. Core and driver additions 1) Initial work from Guenter Roeck on device tree support for IIO's provider/ consumer code. Focuses on the iio_hwmon driver and the max1363 adc driver. The full device tree syntax is currently under discussion but should follow shortly. Cleanups and fixes 1) Remove a noop function __iio_update_buffer 2) Couple of small fixes and cleanups for the max1363 "
-rw-r--r--drivers/iio/accel/Kconfig31
-rw-r--r--drivers/iio/accel/Makefile8
-rw-r--r--drivers/iio/accel/st_accel.h47
-rw-r--r--drivers/iio/accel/st_accel_buffer.c114
-rw-r--r--drivers/iio/accel/st_accel_core.c495
-rw-r--r--drivers/iio/accel/st_accel_i2c.c87
-rw-r--r--drivers/iio/accel/st_accel_spi.c86
-rw-r--r--drivers/iio/adc/lp8788_adc.c12
-rw-r--r--drivers/iio/adc/max1363.c12
-rw-r--r--drivers/iio/buffer_cb.c4
-rw-r--r--drivers/iio/common/Kconfig1
-rw-r--r--drivers/iio/common/Makefile1
-rw-r--r--drivers/iio/common/st_sensors/Kconfig14
-rw-r--r--drivers/iio/common/st_sensors/Makefile10
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_buffer.c116
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_core.c446
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_i2c.c81
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_spi.c128
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_trigger.c77
-rw-r--r--drivers/iio/gyro/Kconfig48
-rw-r--r--drivers/iio/gyro/Makefile13
-rw-r--r--drivers/iio/gyro/adxrs450.c (renamed from drivers/staging/iio/gyro/adxrs450_core.c)197
-rw-r--r--drivers/iio/gyro/itg3200_buffer.c156
-rw-r--r--drivers/iio/gyro/itg3200_core.c401
-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
-rw-r--r--drivers/iio/inkern.c42
-rw-r--r--drivers/iio/kfifo_buf.c1
-rw-r--r--drivers/iio/magnetometer/Kconfig30
-rw-r--r--drivers/iio/magnetometer/Makefile7
-rw-r--r--drivers/iio/magnetometer/st_magn.h45
-rw-r--r--drivers/iio/magnetometer/st_magn_buffer.c98
-rw-r--r--drivers/iio/magnetometer/st_magn_core.c401
-rw-r--r--drivers/iio/magnetometer/st_magn_i2c.c81
-rw-r--r--drivers/iio/magnetometer/st_magn_spi.c80
-rw-r--r--drivers/staging/iio/gyro/Kconfig10
-rw-r--r--drivers/staging/iio/gyro/Makefile3
-rw-r--r--drivers/staging/iio/gyro/adxrs450.h62
-rw-r--r--drivers/staging/iio/iio_hwmon.c83
-rw-r--r--include/linux/iio/buffer.h13
-rw-r--r--include/linux/iio/common/st_sensors.h270
-rw-r--r--include/linux/iio/common/st_sensors_i2c.h20
-rw-r--r--include/linux/iio/common/st_sensors_spi.h20
-rw-r--r--include/linux/iio/consumer.h9
-rw-r--r--include/linux/iio/driver.h9
-rw-r--r--include/linux/iio/gyro/itg3200.h154
49 files changed, 4455 insertions, 259 deletions
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index d6003531bd63..bb594963f91e 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -21,4 +21,35 @@ config KXSD9
21 Say yes here to build support for the Kionix KXSD9 accelerometer. 21 Say yes here to build support for the Kionix KXSD9 accelerometer.
22 Currently this only supports the device via an SPI interface. 22 Currently this only supports the device via an SPI interface.
23 23
24config IIO_ST_ACCEL_3AXIS
25 tristate "STMicroelectronics accelerometers 3-Axis Driver"
26 depends on (I2C || SPI_MASTER) && SYSFS
27 select IIO_ST_SENSORS_CORE
28 select IIO_ST_ACCEL_I2C_3AXIS if (I2C)
29 select IIO_ST_ACCEL_SPI_3AXIS if (SPI_MASTER)
30 select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
31 select IIO_ST_ACCEL_BUFFER if (IIO_TRIGGERED_BUFFER)
32 help
33 Say yes here to build support for STMicroelectronics accelerometers:
34 LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC,
35 LIS331DLH, LSM303DL, LSM303DLM, LSM330.
36
37 This driver can also be built as a module. If so, will be created
38 these modules:
39 - st_accel (core functions for the driver [it is mandatory]);
40 - st_accel_i2c (necessary for the I2C devices [optional*]);
41 - st_accel_spi (necessary for the SPI devices [optional*]);
42
43 (*) one of these is necessary to do something.
44
45config IIO_ST_ACCEL_I2C_3AXIS
46 tristate
47 depends on IIO_ST_ACCEL_3AXIS
48 depends on IIO_ST_SENSORS_I2C
49
50config IIO_ST_ACCEL_SPI_3AXIS
51 tristate
52 depends on IIO_ST_ACCEL_3AXIS
53 depends on IIO_ST_SENSORS_SPI
54
24endmenu 55endmenu
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 4e1c85987d13..87d8fa264894 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -3,4 +3,12 @@
3# 3#
4 4
5obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o 5obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
6
7obj-$(CONFIG_IIO_ST_ACCEL_3AXIS) += st_accel.o
8st_accel-y := st_accel_core.o
9st_accel-$(CONFIG_IIO_BUFFER) += st_accel_buffer.o
10
11obj-$(CONFIG_IIO_ST_ACCEL_I2C_3AXIS) += st_accel_i2c.o
12obj-$(CONFIG_IIO_ST_ACCEL_SPI_3AXIS) += st_accel_spi.o
13
6obj-$(CONFIG_KXSD9) += kxsd9.o 14obj-$(CONFIG_KXSD9) += kxsd9.o
diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h
new file mode 100644
index 000000000000..37949b94377d
--- /dev/null
+++ b/drivers/iio/accel/st_accel.h
@@ -0,0 +1,47 @@
1/*
2 * STMicroelectronics accelerometers 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_ACCEL_H
12#define ST_ACCEL_H
13
14#include <linux/types.h>
15#include <linux/iio/common/st_sensors.h>
16
17#define LSM303DLHC_ACCEL_DEV_NAME "lsm303dlhc_accel"
18#define LIS3DH_ACCEL_DEV_NAME "lis3dh"
19#define LSM330D_ACCEL_DEV_NAME "lsm330d_accel"
20#define LSM330DL_ACCEL_DEV_NAME "lsm330dl_accel"
21#define LSM330DLC_ACCEL_DEV_NAME "lsm330dlc_accel"
22#define LIS331DLH_ACCEL_DEV_NAME "lis331dlh"
23#define LSM303DL_ACCEL_DEV_NAME "lsm303dl_accel"
24#define LSM303DLH_ACCEL_DEV_NAME "lsm303dlh_accel"
25#define LSM303DLM_ACCEL_DEV_NAME "lsm303dlm_accel"
26#define LSM330_ACCEL_DEV_NAME "lsm330_accel"
27
28int st_accel_common_probe(struct iio_dev *indio_dev);
29void st_accel_common_remove(struct iio_dev *indio_dev);
30
31#ifdef CONFIG_IIO_BUFFER
32int st_accel_allocate_ring(struct iio_dev *indio_dev);
33void st_accel_deallocate_ring(struct iio_dev *indio_dev);
34int st_accel_trig_set_state(struct iio_trigger *trig, bool state);
35#define ST_ACCEL_TRIGGER_SET_STATE (&st_accel_trig_set_state)
36#else /* CONFIG_IIO_BUFFER */
37static inline int st_accel_allocate_ring(struct iio_dev *indio_dev)
38{
39 return 0;
40}
41static inline void st_accel_deallocate_ring(struct iio_dev *indio_dev)
42{
43}
44#define ST_ACCEL_TRIGGER_SET_STATE NULL
45#endif /* CONFIG_IIO_BUFFER */
46
47#endif /* ST_ACCEL_H */
diff --git a/drivers/iio/accel/st_accel_buffer.c b/drivers/iio/accel/st_accel_buffer.c
new file mode 100644
index 000000000000..6bd82c7f769c
--- /dev/null
+++ b/drivers/iio/accel/st_accel_buffer.c
@@ -0,0 +1,114 @@
1/*
2 * STMicroelectronics accelerometers 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_accel.h"
25
26int st_accel_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_accel_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_accel_set_enable_error;
40
41 err = iio_sw_buffer_preenable(indio_dev);
42
43st_accel_set_enable_error:
44 return err;
45}
46
47static int st_accel_buffer_postenable(struct iio_dev *indio_dev)
48{
49 int err;
50 struct st_sensor_data *adata = iio_priv(indio_dev);
51
52 adata->buffer_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
53 if (adata->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_accel_buffer_postenable_error;
62
63 err = iio_triggered_buffer_postenable(indio_dev);
64 if (err < 0)
65 goto st_accel_buffer_postenable_error;
66
67 return err;
68
69st_accel_buffer_postenable_error:
70 kfree(adata->buffer_data);
71allocate_memory_error:
72 return err;
73}
74
75static int st_accel_buffer_predisable(struct iio_dev *indio_dev)
76{
77 int err;
78 struct st_sensor_data *adata = iio_priv(indio_dev);
79
80 err = iio_triggered_buffer_predisable(indio_dev);
81 if (err < 0)
82 goto st_accel_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_accel_buffer_predisable_error;
87
88 err = st_sensors_set_enable(indio_dev, false);
89
90st_accel_buffer_predisable_error:
91 kfree(adata->buffer_data);
92 return err;
93}
94
95static const struct iio_buffer_setup_ops st_accel_buffer_setup_ops = {
96 .preenable = &st_accel_buffer_preenable,
97 .postenable = &st_accel_buffer_postenable,
98 .predisable = &st_accel_buffer_predisable,
99};
100
101int st_accel_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_accel_buffer_setup_ops);
105}
106
107void st_accel_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 accelerometers buffer");
114MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
new file mode 100644
index 000000000000..a235de252a90
--- /dev/null
+++ b/drivers/iio/accel/st_accel_core.c
@@ -0,0 +1,495 @@
1/*
2 * STMicroelectronics accelerometers 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/iio/iio.h>
22#include <linux/iio/sysfs.h>
23#include <linux/iio/trigger_consumer.h>
24#include <linux/iio/buffer.h>
25
26#include <linux/iio/common/st_sensors.h>
27#include "st_accel.h"
28
29/* DEFAULT VALUE FOR SENSORS */
30#define ST_ACCEL_DEFAULT_OUT_X_L_ADDR 0x28
31#define ST_ACCEL_DEFAULT_OUT_Y_L_ADDR 0x2a
32#define ST_ACCEL_DEFAULT_OUT_Z_L_ADDR 0x2c
33
34/* FULLSCALE */
35#define ST_ACCEL_FS_AVL_2G 2
36#define ST_ACCEL_FS_AVL_4G 4
37#define ST_ACCEL_FS_AVL_6G 6
38#define ST_ACCEL_FS_AVL_8G 8
39#define ST_ACCEL_FS_AVL_16G 16
40
41/* CUSTOM VALUES FOR SENSOR 1 */
42#define ST_ACCEL_1_WAI_EXP 0x33
43#define ST_ACCEL_1_ODR_ADDR 0x20
44#define ST_ACCEL_1_ODR_MASK 0xf0
45#define ST_ACCEL_1_ODR_AVL_1HZ_VAL 0x01
46#define ST_ACCEL_1_ODR_AVL_10HZ_VAL 0x02
47#define ST_ACCEL_1_ODR_AVL_25HZ_VAL 0x03
48#define ST_ACCEL_1_ODR_AVL_50HZ_VAL 0x04
49#define ST_ACCEL_1_ODR_AVL_100HZ_VAL 0x05
50#define ST_ACCEL_1_ODR_AVL_200HZ_VAL 0x06
51#define ST_ACCEL_1_ODR_AVL_400HZ_VAL 0x07
52#define ST_ACCEL_1_ODR_AVL_1600HZ_VAL 0x08
53#define ST_ACCEL_1_FS_ADDR 0x23
54#define ST_ACCEL_1_FS_MASK 0x30
55#define ST_ACCEL_1_FS_AVL_2_VAL 0x00
56#define ST_ACCEL_1_FS_AVL_4_VAL 0x01
57#define ST_ACCEL_1_FS_AVL_8_VAL 0x02
58#define ST_ACCEL_1_FS_AVL_16_VAL 0x03
59#define ST_ACCEL_1_FS_AVL_2_GAIN IIO_G_TO_M_S_2(1000)
60#define ST_ACCEL_1_FS_AVL_4_GAIN IIO_G_TO_M_S_2(2000)
61#define ST_ACCEL_1_FS_AVL_8_GAIN IIO_G_TO_M_S_2(4000)
62#define ST_ACCEL_1_FS_AVL_16_GAIN IIO_G_TO_M_S_2(12000)
63#define ST_ACCEL_1_BDU_ADDR 0x23
64#define ST_ACCEL_1_BDU_MASK 0x80
65#define ST_ACCEL_1_DRDY_IRQ_ADDR 0x22
66#define ST_ACCEL_1_DRDY_IRQ_MASK 0x10
67#define ST_ACCEL_1_MULTIREAD_BIT true
68
69/* CUSTOM VALUES FOR SENSOR 2 */
70#define ST_ACCEL_2_WAI_EXP 0x32
71#define ST_ACCEL_2_ODR_ADDR 0x20
72#define ST_ACCEL_2_ODR_MASK 0x18
73#define ST_ACCEL_2_ODR_AVL_50HZ_VAL 0x00
74#define ST_ACCEL_2_ODR_AVL_100HZ_VAL 0x01
75#define ST_ACCEL_2_ODR_AVL_400HZ_VAL 0x02
76#define ST_ACCEL_2_ODR_AVL_1000HZ_VAL 0x03
77#define ST_ACCEL_2_PW_ADDR 0x20
78#define ST_ACCEL_2_PW_MASK 0xe0
79#define ST_ACCEL_2_FS_ADDR 0x23
80#define ST_ACCEL_2_FS_MASK 0x30
81#define ST_ACCEL_2_FS_AVL_2_VAL 0X00
82#define ST_ACCEL_2_FS_AVL_4_VAL 0X01
83#define ST_ACCEL_2_FS_AVL_8_VAL 0x03
84#define ST_ACCEL_2_FS_AVL_2_GAIN IIO_G_TO_M_S_2(1000)
85#define ST_ACCEL_2_FS_AVL_4_GAIN IIO_G_TO_M_S_2(2000)
86#define ST_ACCEL_2_FS_AVL_8_GAIN IIO_G_TO_M_S_2(3900)
87#define ST_ACCEL_2_BDU_ADDR 0x23
88#define ST_ACCEL_2_BDU_MASK 0x80
89#define ST_ACCEL_2_DRDY_IRQ_ADDR 0x22
90#define ST_ACCEL_2_DRDY_IRQ_MASK 0x02
91#define ST_ACCEL_2_MULTIREAD_BIT true
92
93/* CUSTOM VALUES FOR SENSOR 3 */
94#define ST_ACCEL_3_WAI_EXP 0x40
95#define ST_ACCEL_3_ODR_ADDR 0x20
96#define ST_ACCEL_3_ODR_MASK 0xf0
97#define ST_ACCEL_3_ODR_AVL_3HZ_VAL 0x01
98#define ST_ACCEL_3_ODR_AVL_6HZ_VAL 0x02
99#define ST_ACCEL_3_ODR_AVL_12HZ_VAL 0x03
100#define ST_ACCEL_3_ODR_AVL_25HZ_VAL 0x04
101#define ST_ACCEL_3_ODR_AVL_50HZ_VAL 0x05
102#define ST_ACCEL_3_ODR_AVL_100HZ_VAL 0x06
103#define ST_ACCEL_3_ODR_AVL_200HZ_VAL 0x07
104#define ST_ACCEL_3_ODR_AVL_400HZ_VAL 0x08
105#define ST_ACCEL_3_ODR_AVL_800HZ_VAL 0x09
106#define ST_ACCEL_3_ODR_AVL_1600HZ_VAL 0x0a
107#define ST_ACCEL_3_FS_ADDR 0x24
108#define ST_ACCEL_3_FS_MASK 0x38
109#define ST_ACCEL_3_FS_AVL_2_VAL 0X00
110#define ST_ACCEL_3_FS_AVL_4_VAL 0X01
111#define ST_ACCEL_3_FS_AVL_6_VAL 0x02
112#define ST_ACCEL_3_FS_AVL_8_VAL 0x03
113#define ST_ACCEL_3_FS_AVL_16_VAL 0x04
114#define ST_ACCEL_3_FS_AVL_2_GAIN IIO_G_TO_M_S_2(61)
115#define ST_ACCEL_3_FS_AVL_4_GAIN IIO_G_TO_M_S_2(122)
116#define ST_ACCEL_3_FS_AVL_6_GAIN IIO_G_TO_M_S_2(183)
117#define ST_ACCEL_3_FS_AVL_8_GAIN IIO_G_TO_M_S_2(244)
118#define ST_ACCEL_3_FS_AVL_16_GAIN IIO_G_TO_M_S_2(732)
119#define ST_ACCEL_3_BDU_ADDR 0x20
120#define ST_ACCEL_3_BDU_MASK 0x08
121#define ST_ACCEL_3_DRDY_IRQ_ADDR 0x23
122#define ST_ACCEL_3_DRDY_IRQ_MASK 0x80
123#define ST_ACCEL_3_IG1_EN_ADDR 0x23
124#define ST_ACCEL_3_IG1_EN_MASK 0x08
125#define ST_ACCEL_3_MULTIREAD_BIT false
126
127static const struct iio_chan_spec st_accel_12bit_channels[] = {
128 ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE,
129 ST_SENSORS_DEFAULT_12_REALBITS, ST_ACCEL_DEFAULT_OUT_X_L_ADDR),
130 ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE,
131 ST_SENSORS_DEFAULT_12_REALBITS, ST_ACCEL_DEFAULT_OUT_Y_L_ADDR),
132 ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE,
133 ST_SENSORS_DEFAULT_12_REALBITS, ST_ACCEL_DEFAULT_OUT_Z_L_ADDR),
134 IIO_CHAN_SOFT_TIMESTAMP(3)
135};
136
137static const struct iio_chan_spec st_accel_16bit_channels[] = {
138 ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE,
139 ST_SENSORS_DEFAULT_16_REALBITS, ST_ACCEL_DEFAULT_OUT_X_L_ADDR),
140 ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE,
141 ST_SENSORS_DEFAULT_16_REALBITS, ST_ACCEL_DEFAULT_OUT_Y_L_ADDR),
142 ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE,
143 ST_SENSORS_DEFAULT_16_REALBITS, ST_ACCEL_DEFAULT_OUT_Z_L_ADDR),
144 IIO_CHAN_SOFT_TIMESTAMP(3)
145};
146
147static const struct st_sensors st_accel_sensors[] = {
148 {
149 .wai = ST_ACCEL_1_WAI_EXP,
150 .sensors_supported = {
151 [0] = LIS3DH_ACCEL_DEV_NAME,
152 [1] = LSM303DLHC_ACCEL_DEV_NAME,
153 [2] = LSM330D_ACCEL_DEV_NAME,
154 [3] = LSM330DL_ACCEL_DEV_NAME,
155 [4] = LSM330DLC_ACCEL_DEV_NAME,
156 },
157 .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
158 .odr = {
159 .addr = ST_ACCEL_1_ODR_ADDR,
160 .mask = ST_ACCEL_1_ODR_MASK,
161 .odr_avl = {
162 { 1, ST_ACCEL_1_ODR_AVL_1HZ_VAL, },
163 { 10, ST_ACCEL_1_ODR_AVL_10HZ_VAL, },
164 { 25, ST_ACCEL_1_ODR_AVL_25HZ_VAL, },
165 { 50, ST_ACCEL_1_ODR_AVL_50HZ_VAL, },
166 { 100, ST_ACCEL_1_ODR_AVL_100HZ_VAL, },
167 { 200, ST_ACCEL_1_ODR_AVL_200HZ_VAL, },
168 { 400, ST_ACCEL_1_ODR_AVL_400HZ_VAL, },
169 { 1600, ST_ACCEL_1_ODR_AVL_1600HZ_VAL, },
170 },
171 },
172 .pw = {
173 .addr = ST_ACCEL_1_ODR_ADDR,
174 .mask = ST_ACCEL_1_ODR_MASK,
175 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
176 },
177 .enable_axis = {
178 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
179 .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
180 },
181 .fs = {
182 .addr = ST_ACCEL_1_FS_ADDR,
183 .mask = ST_ACCEL_1_FS_MASK,
184 .fs_avl = {
185 [0] = {
186 .num = ST_ACCEL_FS_AVL_2G,
187 .value = ST_ACCEL_1_FS_AVL_2_VAL,
188 .gain = ST_ACCEL_1_FS_AVL_2_GAIN,
189 },
190 [1] = {
191 .num = ST_ACCEL_FS_AVL_4G,
192 .value = ST_ACCEL_1_FS_AVL_4_VAL,
193 .gain = ST_ACCEL_1_FS_AVL_4_GAIN,
194 },
195 [2] = {
196 .num = ST_ACCEL_FS_AVL_8G,
197 .value = ST_ACCEL_1_FS_AVL_8_VAL,
198 .gain = ST_ACCEL_1_FS_AVL_8_GAIN,
199 },
200 [3] = {
201 .num = ST_ACCEL_FS_AVL_16G,
202 .value = ST_ACCEL_1_FS_AVL_16_VAL,
203 .gain = ST_ACCEL_1_FS_AVL_16_GAIN,
204 },
205 },
206 },
207 .bdu = {
208 .addr = ST_ACCEL_1_BDU_ADDR,
209 .mask = ST_ACCEL_1_BDU_MASK,
210 },
211 .drdy_irq = {
212 .addr = ST_ACCEL_1_DRDY_IRQ_ADDR,
213 .mask = ST_ACCEL_1_DRDY_IRQ_MASK,
214 },
215 .multi_read_bit = ST_ACCEL_1_MULTIREAD_BIT,
216 .bootime = 2,
217 },
218 {
219 .wai = ST_ACCEL_2_WAI_EXP,
220 .sensors_supported = {
221 [0] = LIS331DLH_ACCEL_DEV_NAME,
222 [1] = LSM303DL_ACCEL_DEV_NAME,
223 [2] = LSM303DLH_ACCEL_DEV_NAME,
224 [3] = LSM303DLM_ACCEL_DEV_NAME,
225 },
226 .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
227 .odr = {
228 .addr = ST_ACCEL_2_ODR_ADDR,
229 .mask = ST_ACCEL_2_ODR_MASK,
230 .odr_avl = {
231 { 50, ST_ACCEL_2_ODR_AVL_50HZ_VAL, },
232 { 100, ST_ACCEL_2_ODR_AVL_100HZ_VAL, },
233 { 400, ST_ACCEL_2_ODR_AVL_400HZ_VAL, },
234 { 1000, ST_ACCEL_2_ODR_AVL_1000HZ_VAL, },
235 },
236 },
237 .pw = {
238 .addr = ST_ACCEL_2_PW_ADDR,
239 .mask = ST_ACCEL_2_PW_MASK,
240 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
241 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
242 },
243 .enable_axis = {
244 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
245 .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
246 },
247 .fs = {
248 .addr = ST_ACCEL_2_FS_ADDR,
249 .mask = ST_ACCEL_2_FS_MASK,
250 .fs_avl = {
251 [0] = {
252 .num = ST_ACCEL_FS_AVL_2G,
253 .value = ST_ACCEL_2_FS_AVL_2_VAL,
254 .gain = ST_ACCEL_2_FS_AVL_2_GAIN,
255 },
256 [1] = {
257 .num = ST_ACCEL_FS_AVL_4G,
258 .value = ST_ACCEL_2_FS_AVL_4_VAL,
259 .gain = ST_ACCEL_2_FS_AVL_4_GAIN,
260 },
261 [2] = {
262 .num = ST_ACCEL_FS_AVL_8G,
263 .value = ST_ACCEL_2_FS_AVL_8_VAL,
264 .gain = ST_ACCEL_2_FS_AVL_8_GAIN,
265 },
266 },
267 },
268 .bdu = {
269 .addr = ST_ACCEL_2_BDU_ADDR,
270 .mask = ST_ACCEL_2_BDU_MASK,
271 },
272 .drdy_irq = {
273 .addr = ST_ACCEL_2_DRDY_IRQ_ADDR,
274 .mask = ST_ACCEL_2_DRDY_IRQ_MASK,
275 },
276 .multi_read_bit = ST_ACCEL_2_MULTIREAD_BIT,
277 .bootime = 2,
278 },
279 {
280 .wai = ST_ACCEL_3_WAI_EXP,
281 .sensors_supported = {
282 [0] = LSM330_ACCEL_DEV_NAME,
283 },
284 .ch = (struct iio_chan_spec *)st_accel_16bit_channels,
285 .odr = {
286 .addr = ST_ACCEL_3_ODR_ADDR,
287 .mask = ST_ACCEL_3_ODR_MASK,
288 .odr_avl = {
289 { 3, ST_ACCEL_3_ODR_AVL_3HZ_VAL },
290 { 6, ST_ACCEL_3_ODR_AVL_6HZ_VAL, },
291 { 12, ST_ACCEL_3_ODR_AVL_12HZ_VAL, },
292 { 25, ST_ACCEL_3_ODR_AVL_25HZ_VAL, },
293 { 50, ST_ACCEL_3_ODR_AVL_50HZ_VAL, },
294 { 100, ST_ACCEL_3_ODR_AVL_100HZ_VAL, },
295 { 200, ST_ACCEL_3_ODR_AVL_200HZ_VAL, },
296 { 400, ST_ACCEL_3_ODR_AVL_400HZ_VAL, },
297 { 800, ST_ACCEL_3_ODR_AVL_800HZ_VAL, },
298 { 1600, ST_ACCEL_3_ODR_AVL_1600HZ_VAL, },
299 },
300 },
301 .pw = {
302 .addr = ST_ACCEL_3_ODR_ADDR,
303 .mask = ST_ACCEL_3_ODR_MASK,
304 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
305 },
306 .enable_axis = {
307 .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
308 .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
309 },
310 .fs = {
311 .addr = ST_ACCEL_3_FS_ADDR,
312 .mask = ST_ACCEL_3_FS_MASK,
313 .fs_avl = {
314 [0] = {
315 .num = ST_ACCEL_FS_AVL_2G,
316 .value = ST_ACCEL_3_FS_AVL_2_VAL,
317 .gain = ST_ACCEL_3_FS_AVL_2_GAIN,
318 },
319 [1] = {
320 .num = ST_ACCEL_FS_AVL_4G,
321 .value = ST_ACCEL_3_FS_AVL_4_VAL,
322 .gain = ST_ACCEL_3_FS_AVL_4_GAIN,
323 },
324 [2] = {
325 .num = ST_ACCEL_FS_AVL_6G,
326 .value = ST_ACCEL_3_FS_AVL_6_VAL,
327 .gain = ST_ACCEL_3_FS_AVL_6_GAIN,
328 },
329 [3] = {
330 .num = ST_ACCEL_FS_AVL_8G,
331 .value = ST_ACCEL_3_FS_AVL_8_VAL,
332 .gain = ST_ACCEL_3_FS_AVL_8_GAIN,
333 },
334 [4] = {
335 .num = ST_ACCEL_FS_AVL_16G,
336 .value = ST_ACCEL_3_FS_AVL_16_VAL,
337 .gain = ST_ACCEL_3_FS_AVL_16_GAIN,
338 },
339 },
340 },
341 .bdu = {
342 .addr = ST_ACCEL_3_BDU_ADDR,
343 .mask = ST_ACCEL_3_BDU_MASK,
344 },
345 .drdy_irq = {
346 .addr = ST_ACCEL_3_DRDY_IRQ_ADDR,
347 .mask = ST_ACCEL_3_DRDY_IRQ_MASK,
348 .ig1 = {
349 .en_addr = ST_ACCEL_3_IG1_EN_ADDR,
350 .en_mask = ST_ACCEL_3_IG1_EN_MASK,
351 },
352 },
353 .multi_read_bit = ST_ACCEL_3_MULTIREAD_BIT,
354 .bootime = 2,
355 },
356};
357
358static int st_accel_read_raw(struct iio_dev *indio_dev,
359 struct iio_chan_spec const *ch, int *val,
360 int *val2, long mask)
361{
362 int err;
363 struct st_sensor_data *adata = iio_priv(indio_dev);
364
365 switch (mask) {
366 case IIO_CHAN_INFO_RAW:
367 err = st_sensors_read_info_raw(indio_dev, ch, val);
368 if (err < 0)
369 goto read_error;
370
371 return IIO_VAL_INT;
372 case IIO_CHAN_INFO_SCALE:
373 *val = 0;
374 *val2 = adata->current_fullscale->gain;
375 return IIO_VAL_INT_PLUS_MICRO;
376 default:
377 return -EINVAL;
378 }
379
380read_error:
381 return err;
382}
383
384static int st_accel_write_raw(struct iio_dev *indio_dev,
385 struct iio_chan_spec const *chan, int val, int val2, long mask)
386{
387 int err;
388
389 switch (mask) {
390 case IIO_CHAN_INFO_SCALE:
391 err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
392 break;
393 default:
394 return -EINVAL;
395 }
396
397 return err;
398}
399
400static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
401static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
402static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_accel_scale_available);
403
404static struct attribute *st_accel_attributes[] = {
405 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
406 &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
407 &iio_dev_attr_sampling_frequency.dev_attr.attr,
408 NULL,
409};
410
411static const struct attribute_group st_accel_attribute_group = {
412 .attrs = st_accel_attributes,
413};
414
415static const struct iio_info accel_info = {
416 .driver_module = THIS_MODULE,
417 .attrs = &st_accel_attribute_group,
418 .read_raw = &st_accel_read_raw,
419 .write_raw = &st_accel_write_raw,
420};
421
422static const struct iio_trigger_ops st_accel_trigger_ops = {
423 .owner = THIS_MODULE,
424 .set_trigger_state = ST_ACCEL_TRIGGER_SET_STATE,
425};
426
427int st_accel_common_probe(struct iio_dev *indio_dev)
428{
429 int err;
430 struct st_sensor_data *adata = iio_priv(indio_dev);
431
432 indio_dev->modes = INDIO_DIRECT_MODE;
433 indio_dev->info = &accel_info;
434
435 err = st_sensors_check_device_support(indio_dev,
436 ARRAY_SIZE(st_accel_sensors), st_accel_sensors);
437 if (err < 0)
438 goto st_accel_common_probe_error;
439
440 adata->multiread_bit = adata->sensor->multi_read_bit;
441 indio_dev->channels = adata->sensor->ch;
442 indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
443
444 adata->current_fullscale = (struct st_sensor_fullscale_avl *)
445 &adata->sensor->fs.fs_avl[0];
446 adata->odr = adata->sensor->odr.odr_avl[0].hz;
447
448 err = st_sensors_init_sensor(indio_dev);
449 if (err < 0)
450 goto st_accel_common_probe_error;
451
452 if (adata->get_irq_data_ready(indio_dev) > 0) {
453 err = st_accel_allocate_ring(indio_dev);
454 if (err < 0)
455 goto st_accel_common_probe_error;
456
457 err = st_sensors_allocate_trigger(indio_dev,
458 &st_accel_trigger_ops);
459 if (err < 0)
460 goto st_accel_probe_trigger_error;
461 }
462
463 err = iio_device_register(indio_dev);
464 if (err)
465 goto st_accel_device_register_error;
466
467 return err;
468
469st_accel_device_register_error:
470 if (adata->get_irq_data_ready(indio_dev) > 0)
471 st_sensors_deallocate_trigger(indio_dev);
472st_accel_probe_trigger_error:
473 if (adata->get_irq_data_ready(indio_dev) > 0)
474 st_accel_deallocate_ring(indio_dev);
475st_accel_common_probe_error:
476 return err;
477}
478EXPORT_SYMBOL(st_accel_common_probe);
479
480void st_accel_common_remove(struct iio_dev *indio_dev)
481{
482 struct st_sensor_data *adata = iio_priv(indio_dev);
483
484 iio_device_unregister(indio_dev);
485 if (adata->get_irq_data_ready(indio_dev) > 0) {
486 st_sensors_deallocate_trigger(indio_dev);
487 st_accel_deallocate_ring(indio_dev);
488 }
489 iio_device_free(indio_dev);
490}
491EXPORT_SYMBOL(st_accel_common_remove);
492
493MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
494MODULE_DESCRIPTION("STMicroelectronics accelerometers driver");
495MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c
new file mode 100644
index 000000000000..90b8ddfb61ed
--- /dev/null
+++ b/drivers/iio/accel/st_accel_i2c.c
@@ -0,0 +1,87 @@
1/*
2 * STMicroelectronics accelerometers 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_accel.h"
21
22static int st_accel_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 *adata;
27 int err;
28
29 indio_dev = iio_device_alloc(sizeof(*adata));
30 if (indio_dev == NULL) {
31 err = -ENOMEM;
32 goto iio_device_alloc_error;
33 }
34
35 adata = iio_priv(indio_dev);
36 adata->dev = &client->dev;
37
38 st_sensors_i2c_configure(indio_dev, client, adata);
39
40 err = st_accel_common_probe(indio_dev);
41 if (err < 0)
42 goto st_accel_common_probe_error;
43
44 return 0;
45
46st_accel_common_probe_error:
47 iio_device_free(indio_dev);
48iio_device_alloc_error:
49 return err;
50}
51
52static int st_accel_i2c_remove(struct i2c_client *client)
53{
54 st_accel_common_remove(i2c_get_clientdata(client));
55
56 return 0;
57}
58
59static const struct i2c_device_id st_accel_id_table[] = {
60 { LSM303DLH_ACCEL_DEV_NAME },
61 { LSM303DLHC_ACCEL_DEV_NAME },
62 { LIS3DH_ACCEL_DEV_NAME },
63 { LSM330D_ACCEL_DEV_NAME },
64 { LSM330DL_ACCEL_DEV_NAME },
65 { LSM330DLC_ACCEL_DEV_NAME },
66 { LIS331DLH_ACCEL_DEV_NAME },
67 { LSM303DL_ACCEL_DEV_NAME },
68 { LSM303DLM_ACCEL_DEV_NAME },
69 { LSM330_ACCEL_DEV_NAME },
70 {},
71};
72MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
73
74static struct i2c_driver st_accel_driver = {
75 .driver = {
76 .owner = THIS_MODULE,
77 .name = "st-accel-i2c",
78 },
79 .probe = st_accel_i2c_probe,
80 .remove = st_accel_i2c_remove,
81 .id_table = st_accel_id_table,
82};
83module_i2c_driver(st_accel_driver);
84
85MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
86MODULE_DESCRIPTION("STMicroelectronics accelerometers i2c driver");
87MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c
new file mode 100644
index 000000000000..dbd45c08711f
--- /dev/null
+++ b/drivers/iio/accel/st_accel_spi.c
@@ -0,0 +1,86 @@
1/*
2 * STMicroelectronics accelerometers 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_accel.h"
21
22static int st_accel_spi_probe(struct spi_device *spi)
23{
24 struct iio_dev *indio_dev;
25 struct st_sensor_data *adata;
26 int err;
27
28 indio_dev = iio_device_alloc(sizeof(*adata));
29 if (indio_dev == NULL) {
30 err = -ENOMEM;
31 goto iio_device_alloc_error;
32 }
33
34 adata = iio_priv(indio_dev);
35 adata->dev = &spi->dev;
36
37 st_sensors_spi_configure(indio_dev, spi, adata);
38
39 err = st_accel_common_probe(indio_dev);
40 if (err < 0)
41 goto st_accel_common_probe_error;
42
43 return 0;
44
45st_accel_common_probe_error:
46 iio_device_free(indio_dev);
47iio_device_alloc_error:
48 return err;
49}
50
51static int st_accel_spi_remove(struct spi_device *spi)
52{
53 st_accel_common_remove(spi_get_drvdata(spi));
54
55 return 0;
56}
57
58static const struct spi_device_id st_accel_id_table[] = {
59 { LSM303DLH_ACCEL_DEV_NAME },
60 { LSM303DLHC_ACCEL_DEV_NAME },
61 { LIS3DH_ACCEL_DEV_NAME },
62 { LSM330D_ACCEL_DEV_NAME },
63 { LSM330DL_ACCEL_DEV_NAME },
64 { LSM330DLC_ACCEL_DEV_NAME },
65 { LIS331DLH_ACCEL_DEV_NAME },
66 { LSM303DL_ACCEL_DEV_NAME },
67 { LSM303DLM_ACCEL_DEV_NAME },
68 { LSM330_ACCEL_DEV_NAME },
69 {},
70};
71MODULE_DEVICE_TABLE(spi, st_accel_id_table);
72
73static struct spi_driver st_accel_driver = {
74 .driver = {
75 .owner = THIS_MODULE,
76 .name = "st-accel-spi",
77 },
78 .probe = st_accel_spi_probe,
79 .remove = st_accel_spi_remove,
80 .id_table = st_accel_id_table,
81};
82module_spi_driver(st_accel_driver);
83
84MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
85MODULE_DESCRIPTION("STMicroelectronics accelerometers spi driver");
86MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/lp8788_adc.c b/drivers/iio/adc/lp8788_adc.c
index f8bcb1f5892d..763f57565ee4 100644
--- a/drivers/iio/adc/lp8788_adc.c
+++ b/drivers/iio/adc/lp8788_adc.c
@@ -187,12 +187,6 @@ static int lp8788_iio_map_register(struct iio_dev *indio_dev,
187 return 0; 187 return 0;
188} 188}
189 189
190static inline void lp8788_iio_map_unregister(struct iio_dev *indio_dev,
191 struct lp8788_adc *adc)
192{
193 iio_map_array_unregister(indio_dev, adc->map);
194}
195
196static int lp8788_adc_probe(struct platform_device *pdev) 190static int lp8788_adc_probe(struct platform_device *pdev)
197{ 191{
198 struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); 192 struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
@@ -208,6 +202,7 @@ static int lp8788_adc_probe(struct platform_device *pdev)
208 adc->lp = lp; 202 adc->lp = lp;
209 platform_set_drvdata(pdev, indio_dev); 203 platform_set_drvdata(pdev, indio_dev);
210 204
205 indio_dev->dev.of_node = pdev->dev.of_node;
211 ret = lp8788_iio_map_register(indio_dev, lp->pdata, adc); 206 ret = lp8788_iio_map_register(indio_dev, lp->pdata, adc);
212 if (ret) 207 if (ret)
213 goto err_iio_map; 208 goto err_iio_map;
@@ -230,7 +225,7 @@ static int lp8788_adc_probe(struct platform_device *pdev)
230 return 0; 225 return 0;
231 226
232err_iio_device: 227err_iio_device:
233 lp8788_iio_map_unregister(indio_dev, adc); 228 iio_map_array_unregister(indio_dev);
234err_iio_map: 229err_iio_map:
235 iio_device_free(indio_dev); 230 iio_device_free(indio_dev);
236 return ret; 231 return ret;
@@ -239,10 +234,9 @@ err_iio_map:
239static int lp8788_adc_remove(struct platform_device *pdev) 234static int lp8788_adc_remove(struct platform_device *pdev)
240{ 235{
241 struct iio_dev *indio_dev = platform_get_drvdata(pdev); 236 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
242 struct lp8788_adc *adc = iio_priv(indio_dev);
243 237
244 iio_device_unregister(indio_dev); 238 iio_device_unregister(indio_dev);
245 lp8788_iio_map_unregister(indio_dev, adc); 239 iio_map_array_unregister(indio_dev);
246 iio_device_free(indio_dev); 240 iio_device_free(indio_dev);
247 241
248 return 0; 242 return 0;
diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c
index 5db56f5ce7dc..08e4feb4f6ee 100644
--- a/drivers/iio/adc/max1363.c
+++ b/drivers/iio/adc/max1363.c
@@ -335,7 +335,7 @@ static int max1363_read_single_chan(struct iio_dev *indio_dev,
335{ 335{
336 int ret = 0; 336 int ret = 0;
337 s32 data; 337 s32 data;
338 char rxbuf[2]; 338 u8 rxbuf[2];
339 struct max1363_state *st = iio_priv(indio_dev); 339 struct max1363_state *st = iio_priv(indio_dev);
340 struct i2c_client *client = st->client; 340 struct i2c_client *client = st->client;
341 341
@@ -367,7 +367,8 @@ static int max1363_read_single_chan(struct iio_dev *indio_dev,
367 ret = data; 367 ret = data;
368 goto error_ret; 368 goto error_ret;
369 } 369 }
370 data = (s32)(rxbuf[1]) | ((s32)(rxbuf[0] & 0x0F)) << 8; 370 data = (rxbuf[1] | rxbuf[0] << 8) &
371 ((1 << st->chip_info->bits) - 1);
371 } else { 372 } else {
372 /* Get reading */ 373 /* Get reading */
373 data = i2c_master_recv(client, rxbuf, 1); 374 data = i2c_master_recv(client, rxbuf, 1);
@@ -1496,6 +1497,7 @@ static int max1363_probe(struct i2c_client *client,
1496 goto error_out; 1497 goto error_out;
1497 } 1498 }
1498 1499
1500 indio_dev->dev.of_node = client->dev.of_node;
1499 ret = iio_map_array_register(indio_dev, client->dev.platform_data); 1501 ret = iio_map_array_register(indio_dev, client->dev.platform_data);
1500 if (ret < 0) 1502 if (ret < 0)
1501 goto error_free_device; 1503 goto error_free_device;
@@ -1529,8 +1531,6 @@ static int max1363_probe(struct i2c_client *client,
1529 indio_dev->num_channels = st->chip_info->num_channels; 1531 indio_dev->num_channels = st->chip_info->num_channels;
1530 indio_dev->info = st->chip_info->info; 1532 indio_dev->info = st->chip_info->info;
1531 indio_dev->modes = INDIO_DIRECT_MODE; 1533 indio_dev->modes = INDIO_DIRECT_MODE;
1532 indio_dev->channels = st->chip_info->channels;
1533 indio_dev->num_channels = st->chip_info->num_channels;
1534 ret = max1363_initial_setup(st); 1534 ret = max1363_initial_setup(st);
1535 if (ret < 0) 1535 if (ret < 0)
1536 goto error_free_available_scan_masks; 1536 goto error_free_available_scan_masks;
@@ -1569,7 +1569,7 @@ error_disable_reg:
1569error_put_reg: 1569error_put_reg:
1570 regulator_put(st->reg); 1570 regulator_put(st->reg);
1571error_unregister_map: 1571error_unregister_map:
1572 iio_map_array_unregister(indio_dev, client->dev.platform_data); 1572 iio_map_array_unregister(indio_dev);
1573error_free_device: 1573error_free_device:
1574 iio_device_free(indio_dev); 1574 iio_device_free(indio_dev);
1575error_out: 1575error_out:
@@ -1588,7 +1588,7 @@ static int max1363_remove(struct i2c_client *client)
1588 kfree(indio_dev->available_scan_masks); 1588 kfree(indio_dev->available_scan_masks);
1589 regulator_disable(st->reg); 1589 regulator_disable(st->reg);
1590 regulator_put(st->reg); 1590 regulator_put(st->reg);
1591 iio_map_array_unregister(indio_dev, client->dev.platform_data); 1591 iio_map_array_unregister(indio_dev);
1592 iio_device_free(indio_dev); 1592 iio_device_free(indio_dev);
1593 1593
1594 return 0; 1594 return 0;
diff --git a/drivers/iio/buffer_cb.c b/drivers/iio/buffer_cb.c
index 4d40e24f3721..9201022945e9 100644
--- a/drivers/iio/buffer_cb.c
+++ b/drivers/iio/buffer_cb.c
@@ -25,7 +25,7 @@ static struct iio_buffer_access_funcs iio_cb_access = {
25 .store_to = &iio_buffer_cb_store_to, 25 .store_to = &iio_buffer_cb_store_to,
26}; 26};
27 27
28struct iio_cb_buffer *iio_channel_get_all_cb(const char *name, 28struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
29 int (*cb)(u8 *data, 29 int (*cb)(u8 *data,
30 void *private), 30 void *private),
31 void *private) 31 void *private)
@@ -46,7 +46,7 @@ struct iio_cb_buffer *iio_channel_get_all_cb(const char *name,
46 cb_buff->buffer.access = &iio_cb_access; 46 cb_buff->buffer.access = &iio_cb_access;
47 INIT_LIST_HEAD(&cb_buff->buffer.demux_list); 47 INIT_LIST_HEAD(&cb_buff->buffer.demux_list);
48 48
49 cb_buff->channels = iio_channel_get_all(name); 49 cb_buff->channels = iio_channel_get_all(dev);
50 if (IS_ERR(cb_buff->channels)) { 50 if (IS_ERR(cb_buff->channels)) {
51 ret = PTR_ERR(cb_buff->channels); 51 ret = PTR_ERR(cb_buff->channels);
52 goto error_free_cb_buff; 52 goto error_free_cb_buff;
diff --git a/drivers/iio/common/Kconfig b/drivers/iio/common/Kconfig
index ed45ee54500c..0b6e97d18fa0 100644
--- a/drivers/iio/common/Kconfig
+++ b/drivers/iio/common/Kconfig
@@ -3,3 +3,4 @@
3# 3#
4 4
5source "drivers/iio/common/hid-sensors/Kconfig" 5source "drivers/iio/common/hid-sensors/Kconfig"
6source "drivers/iio/common/st_sensors/Kconfig"
diff --git a/drivers/iio/common/Makefile b/drivers/iio/common/Makefile
index 81584009b21b..c2352beb5d97 100644
--- a/drivers/iio/common/Makefile
+++ b/drivers/iio/common/Makefile
@@ -7,3 +7,4 @@
7# 7#
8 8
9obj-y += hid-sensors/ 9obj-y += hid-sensors/
10obj-y += st_sensors/
diff --git a/drivers/iio/common/st_sensors/Kconfig b/drivers/iio/common/st_sensors/Kconfig
new file mode 100644
index 000000000000..865f1ca33eb9
--- /dev/null
+++ b/drivers/iio/common/st_sensors/Kconfig
@@ -0,0 +1,14 @@
1#
2# STMicroelectronics sensors common library
3#
4
5config IIO_ST_SENSORS_I2C
6 tristate
7
8config IIO_ST_SENSORS_SPI
9 tristate
10
11config IIO_ST_SENSORS_CORE
12 tristate
13 select IIO_ST_SENSORS_I2C if I2C
14 select IIO_ST_SENSORS_SPI if SPI_MASTER
diff --git a/drivers/iio/common/st_sensors/Makefile b/drivers/iio/common/st_sensors/Makefile
new file mode 100644
index 000000000000..9f3e24f3024b
--- /dev/null
+++ b/drivers/iio/common/st_sensors/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for the STMicroelectronics sensor common modules.
3#
4
5obj-$(CONFIG_IIO_ST_SENSORS_I2C) += st_sensors_i2c.o
6obj-$(CONFIG_IIO_ST_SENSORS_SPI) += st_sensors_spi.o
7obj-$(CONFIG_IIO_ST_SENSORS_CORE) += st_sensors.o
8st_sensors-y := st_sensors_core.o
9st_sensors-$(CONFIG_IIO_BUFFER) += st_sensors_buffer.o
10st_sensors-$(CONFIG_IIO_TRIGGER) += st_sensors_trigger.o
diff --git a/drivers/iio/common/st_sensors/st_sensors_buffer.c b/drivers/iio/common/st_sensors/st_sensors_buffer.c
new file mode 100644
index 000000000000..09b236d6ee89
--- /dev/null
+++ b/drivers/iio/common/st_sensors/st_sensors_buffer.c
@@ -0,0 +1,116 @@
1/*
2 * STMicroelectronics sensors buffer library 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/iio/iio.h>
15#include <linux/iio/trigger.h>
16#include <linux/interrupt.h>
17#include <linux/iio/buffer.h>
18#include <linux/iio/trigger_consumer.h>
19#include <linux/iio/triggered_buffer.h>
20#include <linux/irqreturn.h>
21
22#include <linux/iio/common/st_sensors.h>
23
24
25int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf)
26{
27 int i, n = 0, len;
28 u8 addr[ST_SENSORS_NUMBER_DATA_CHANNELS];
29 struct st_sensor_data *sdata = iio_priv(indio_dev);
30
31 for (i = 0; i < ST_SENSORS_NUMBER_DATA_CHANNELS; i++) {
32 if (test_bit(i, indio_dev->active_scan_mask)) {
33 addr[n] = indio_dev->channels[i].address;
34 n++;
35 }
36 }
37 switch (n) {
38 case 1:
39 len = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
40 addr[0], ST_SENSORS_BYTE_FOR_CHANNEL, buf,
41 sdata->multiread_bit);
42 break;
43 case 2:
44 if ((addr[1] - addr[0]) == ST_SENSORS_BYTE_FOR_CHANNEL) {
45 len = sdata->tf->read_multiple_byte(&sdata->tb,
46 sdata->dev, addr[0],
47 ST_SENSORS_BYTE_FOR_CHANNEL*n,
48 buf, sdata->multiread_bit);
49 } else {
50 u8 rx_array[ST_SENSORS_BYTE_FOR_CHANNEL*
51 ST_SENSORS_NUMBER_DATA_CHANNELS];
52 len = sdata->tf->read_multiple_byte(&sdata->tb,
53 sdata->dev, addr[0],
54 ST_SENSORS_BYTE_FOR_CHANNEL*
55 ST_SENSORS_NUMBER_DATA_CHANNELS,
56 rx_array, sdata->multiread_bit);
57 if (len < 0)
58 goto read_data_channels_error;
59
60 for (i = 0; i < n * ST_SENSORS_NUMBER_DATA_CHANNELS;
61 i++) {
62 if (i < n)
63 buf[i] = rx_array[i];
64 else
65 buf[i] = rx_array[n + i];
66 }
67 len = ST_SENSORS_BYTE_FOR_CHANNEL*n;
68 }
69 break;
70 case 3:
71 len = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
72 addr[0], ST_SENSORS_BYTE_FOR_CHANNEL*
73 ST_SENSORS_NUMBER_DATA_CHANNELS,
74 buf, sdata->multiread_bit);
75 break;
76 default:
77 len = -EINVAL;
78 goto read_data_channels_error;
79 }
80 if (len != ST_SENSORS_BYTE_FOR_CHANNEL*n) {
81 len = -EIO;
82 goto read_data_channels_error;
83 }
84
85read_data_channels_error:
86 return len;
87}
88EXPORT_SYMBOL(st_sensors_get_buffer_element);
89
90irqreturn_t st_sensors_trigger_handler(int irq, void *p)
91{
92 int len;
93 struct iio_poll_func *pf = p;
94 struct iio_dev *indio_dev = pf->indio_dev;
95 struct st_sensor_data *sdata = iio_priv(indio_dev);
96
97 len = st_sensors_get_buffer_element(indio_dev, sdata->buffer_data);
98 if (len < 0)
99 goto st_sensors_get_buffer_element_error;
100
101 if (indio_dev->scan_timestamp)
102 *(s64 *)((u8 *)sdata->buffer_data +
103 ALIGN(len, sizeof(s64))) = pf->timestamp;
104
105 iio_push_to_buffers(indio_dev, sdata->buffer_data);
106
107st_sensors_get_buffer_element_error:
108 iio_trigger_notify_done(indio_dev->trig);
109
110 return IRQ_HANDLED;
111}
112EXPORT_SYMBOL(st_sensors_trigger_handler);
113
114MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
115MODULE_DESCRIPTION("STMicroelectronics ST-sensors buffer");
116MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
new file mode 100644
index 000000000000..0198324a8b0c
--- /dev/null
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -0,0 +1,446 @@
1/*
2 * STMicroelectronics sensors core library 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/delay.h>
15#include <linux/iio/iio.h>
16#include <asm/unaligned.h>
17
18#include <linux/iio/common/st_sensors.h>
19
20
21#define ST_SENSORS_WAI_ADDRESS 0x0f
22
23static int st_sensors_write_data_with_mask(struct iio_dev *indio_dev,
24 u8 reg_addr, u8 mask, u8 data)
25{
26 int err;
27 u8 new_data;
28 struct st_sensor_data *sdata = iio_priv(indio_dev);
29
30 err = sdata->tf->read_byte(&sdata->tb, sdata->dev, reg_addr, &new_data);
31 if (err < 0)
32 goto st_sensors_write_data_with_mask_error;
33
34 new_data = ((new_data & (~mask)) | ((data << __ffs(mask)) & mask));
35 err = sdata->tf->write_byte(&sdata->tb, sdata->dev, reg_addr, new_data);
36
37st_sensors_write_data_with_mask_error:
38 return err;
39}
40
41static int st_sensors_match_odr(struct st_sensors *sensor,
42 unsigned int odr, struct st_sensor_odr_avl *odr_out)
43{
44 int i, ret = -EINVAL;
45
46 for (i = 0; i < ST_SENSORS_ODR_LIST_MAX; i++) {
47 if (sensor->odr.odr_avl[i].hz == 0)
48 goto st_sensors_match_odr_error;
49
50 if (sensor->odr.odr_avl[i].hz == odr) {
51 odr_out->hz = sensor->odr.odr_avl[i].hz;
52 odr_out->value = sensor->odr.odr_avl[i].value;
53 ret = 0;
54 break;
55 }
56 }
57
58st_sensors_match_odr_error:
59 return ret;
60}
61
62int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr)
63{
64 int err;
65 struct st_sensor_odr_avl odr_out;
66 struct st_sensor_data *sdata = iio_priv(indio_dev);
67
68 err = st_sensors_match_odr(sdata->sensor, odr, &odr_out);
69 if (err < 0)
70 goto st_sensors_match_odr_error;
71
72 if ((sdata->sensor->odr.addr == sdata->sensor->pw.addr) &&
73 (sdata->sensor->odr.mask == sdata->sensor->pw.mask)) {
74 if (sdata->enabled == true) {
75 err = st_sensors_write_data_with_mask(indio_dev,
76 sdata->sensor->odr.addr,
77 sdata->sensor->odr.mask,
78 odr_out.value);
79 } else {
80 err = 0;
81 }
82 } else {
83 err = st_sensors_write_data_with_mask(indio_dev,
84 sdata->sensor->odr.addr, sdata->sensor->odr.mask,
85 odr_out.value);
86 }
87 if (err >= 0)
88 sdata->odr = odr_out.hz;
89
90st_sensors_match_odr_error:
91 return err;
92}
93EXPORT_SYMBOL(st_sensors_set_odr);
94
95static int st_sensors_match_fs(struct st_sensors *sensor,
96 unsigned int fs, int *index_fs_avl)
97{
98 int i, ret = -EINVAL;
99
100 for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
101 if (sensor->fs.fs_avl[i].num == 0)
102 goto st_sensors_match_odr_error;
103
104 if (sensor->fs.fs_avl[i].num == fs) {
105 *index_fs_avl = i;
106 ret = 0;
107 break;
108 }
109 }
110
111st_sensors_match_odr_error:
112 return ret;
113}
114
115static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs)
116{
117 int err, i;
118 struct st_sensor_data *sdata = iio_priv(indio_dev);
119
120 err = st_sensors_match_fs(sdata->sensor, fs, &i);
121 if (err < 0)
122 goto st_accel_set_fullscale_error;
123
124 err = st_sensors_write_data_with_mask(indio_dev,
125 sdata->sensor->fs.addr,
126 sdata->sensor->fs.mask,
127 sdata->sensor->fs.fs_avl[i].value);
128 if (err < 0)
129 goto st_accel_set_fullscale_error;
130
131 sdata->current_fullscale = (struct st_sensor_fullscale_avl *)
132 &sdata->sensor->fs.fs_avl[i];
133 return err;
134
135st_accel_set_fullscale_error:
136 dev_err(&indio_dev->dev, "failed to set new fullscale.\n");
137 return err;
138}
139
140int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable)
141{
142 bool found;
143 u8 tmp_value;
144 int err = -EINVAL;
145 struct st_sensor_odr_avl odr_out;
146 struct st_sensor_data *sdata = iio_priv(indio_dev);
147
148 if (enable) {
149 found = false;
150 tmp_value = sdata->sensor->pw.value_on;
151 if ((sdata->sensor->odr.addr == sdata->sensor->pw.addr) &&
152 (sdata->sensor->odr.mask == sdata->sensor->pw.mask)) {
153 err = st_sensors_match_odr(sdata->sensor,
154 sdata->odr, &odr_out);
155 if (err < 0)
156 goto set_enable_error;
157 tmp_value = odr_out.value;
158 found = true;
159 }
160 err = st_sensors_write_data_with_mask(indio_dev,
161 sdata->sensor->pw.addr,
162 sdata->sensor->pw.mask, tmp_value);
163 if (err < 0)
164 goto set_enable_error;
165
166 sdata->enabled = true;
167
168 if (found)
169 sdata->odr = odr_out.hz;
170 } else {
171 err = st_sensors_write_data_with_mask(indio_dev,
172 sdata->sensor->pw.addr,
173 sdata->sensor->pw.mask,
174 sdata->sensor->pw.value_off);
175 if (err < 0)
176 goto set_enable_error;
177
178 sdata->enabled = false;
179 }
180
181set_enable_error:
182 return err;
183}
184EXPORT_SYMBOL(st_sensors_set_enable);
185
186int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable)
187{
188 struct st_sensor_data *sdata = iio_priv(indio_dev);
189
190 return st_sensors_write_data_with_mask(indio_dev,
191 sdata->sensor->enable_axis.addr,
192 sdata->sensor->enable_axis.mask, axis_enable);
193}
194EXPORT_SYMBOL(st_sensors_set_axis_enable);
195
196int st_sensors_init_sensor(struct iio_dev *indio_dev)
197{
198 int err;
199 struct st_sensor_data *sdata = iio_priv(indio_dev);
200
201 mutex_init(&sdata->tb.buf_lock);
202
203 err = st_sensors_set_enable(indio_dev, false);
204 if (err < 0)
205 goto init_error;
206
207 err = st_sensors_set_fullscale(indio_dev,
208 sdata->current_fullscale->num);
209 if (err < 0)
210 goto init_error;
211
212 err = st_sensors_set_odr(indio_dev, sdata->odr);
213 if (err < 0)
214 goto init_error;
215
216 /* set BDU */
217 err = st_sensors_write_data_with_mask(indio_dev,
218 sdata->sensor->bdu.addr, sdata->sensor->bdu.mask, true);
219 if (err < 0)
220 goto init_error;
221
222 err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
223
224init_error:
225 return err;
226}
227EXPORT_SYMBOL(st_sensors_init_sensor);
228
229int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
230{
231 int err;
232 struct st_sensor_data *sdata = iio_priv(indio_dev);
233
234 /* Enable/Disable the interrupt generator 1. */
235 if (sdata->sensor->drdy_irq.ig1.en_addr > 0) {
236 err = st_sensors_write_data_with_mask(indio_dev,
237 sdata->sensor->drdy_irq.ig1.en_addr,
238 sdata->sensor->drdy_irq.ig1.en_mask, (int)enable);
239 if (err < 0)
240 goto st_accel_set_dataready_irq_error;
241 }
242
243 /* Enable/Disable the interrupt generator for data ready. */
244 err = st_sensors_write_data_with_mask(indio_dev,
245 sdata->sensor->drdy_irq.addr,
246 sdata->sensor->drdy_irq.mask, (int)enable);
247
248st_accel_set_dataready_irq_error:
249 return err;
250}
251EXPORT_SYMBOL(st_sensors_set_dataready_irq);
252
253int st_sensors_set_fullscale_by_gain(struct iio_dev *indio_dev, int scale)
254{
255 int err = -EINVAL, i;
256 struct st_sensor_data *sdata = iio_priv(indio_dev);
257
258 for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
259 if ((sdata->sensor->fs.fs_avl[i].gain == scale) &&
260 (sdata->sensor->fs.fs_avl[i].gain != 0)) {
261 err = 0;
262 break;
263 }
264 }
265 if (err < 0)
266 goto st_sensors_match_scale_error;
267
268 err = st_sensors_set_fullscale(indio_dev,
269 sdata->sensor->fs.fs_avl[i].num);
270
271st_sensors_match_scale_error:
272 return err;
273}
274EXPORT_SYMBOL(st_sensors_set_fullscale_by_gain);
275
276static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
277 u8 ch_addr, int *data)
278{
279 int err;
280 u8 outdata[ST_SENSORS_BYTE_FOR_CHANNEL];
281 struct st_sensor_data *sdata = iio_priv(indio_dev);
282
283 err = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
284 ch_addr, ST_SENSORS_BYTE_FOR_CHANNEL,
285 outdata, sdata->multiread_bit);
286 if (err < 0)
287 goto read_error;
288
289 *data = (s16)get_unaligned_le16(outdata);
290
291read_error:
292 return err;
293}
294
295int st_sensors_read_info_raw(struct iio_dev *indio_dev,
296 struct iio_chan_spec const *ch, int *val)
297{
298 int err;
299 struct st_sensor_data *sdata = iio_priv(indio_dev);
300
301 mutex_lock(&indio_dev->mlock);
302 if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
303 err = -EBUSY;
304 goto read_error;
305 } else {
306 err = st_sensors_set_enable(indio_dev, true);
307 if (err < 0)
308 goto read_error;
309
310 msleep((sdata->sensor->bootime * 1000) / sdata->odr);
311 err = st_sensors_read_axis_data(indio_dev, ch->address, val);
312 if (err < 0)
313 goto read_error;
314
315 *val = *val >> ch->scan_type.shift;
316 }
317 mutex_unlock(&indio_dev->mlock);
318
319 return err;
320
321read_error:
322 mutex_unlock(&indio_dev->mlock);
323 return err;
324}
325EXPORT_SYMBOL(st_sensors_read_info_raw);
326
327int st_sensors_check_device_support(struct iio_dev *indio_dev,
328 int num_sensors_list, const struct st_sensors *sensors)
329{
330 u8 wai;
331 int i, n, err;
332 struct st_sensor_data *sdata = iio_priv(indio_dev);
333
334 err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
335 ST_SENSORS_DEFAULT_WAI_ADDRESS, &wai);
336 if (err < 0) {
337 dev_err(&indio_dev->dev, "failed to read Who-Am-I register.\n");
338 goto read_wai_error;
339 }
340
341 for (i = 0; i < num_sensors_list; i++) {
342 if (sensors[i].wai == wai)
343 break;
344 }
345 if (i == num_sensors_list)
346 goto device_not_supported;
347
348 for (n = 0; n < ARRAY_SIZE(sensors[i].sensors_supported); n++) {
349 if (strcmp(indio_dev->name,
350 &sensors[i].sensors_supported[n][0]) == 0)
351 break;
352 }
353 if (n == ARRAY_SIZE(sensors[i].sensors_supported)) {
354 dev_err(&indio_dev->dev, "device name and WhoAmI mismatch.\n");
355 goto sensor_name_mismatch;
356 }
357
358 sdata->sensor = (struct st_sensors *)&sensors[i];
359
360 return i;
361
362device_not_supported:
363 dev_err(&indio_dev->dev, "device not supported: WhoAmI (0x%x).\n", wai);
364sensor_name_mismatch:
365 err = -ENODEV;
366read_wai_error:
367 return err;
368}
369EXPORT_SYMBOL(st_sensors_check_device_support);
370
371ssize_t st_sensors_sysfs_get_sampling_frequency(struct device *dev,
372 struct device_attribute *attr, char *buf)
373{
374 struct st_sensor_data *adata = iio_priv(dev_get_drvdata(dev));
375
376 return sprintf(buf, "%d\n", adata->odr);
377}
378EXPORT_SYMBOL(st_sensors_sysfs_get_sampling_frequency);
379
380ssize_t st_sensors_sysfs_set_sampling_frequency(struct device *dev,
381 struct device_attribute *attr, const char *buf, size_t size)
382{
383 int err;
384 unsigned int odr;
385 struct iio_dev *indio_dev = dev_get_drvdata(dev);
386
387 err = kstrtoint(buf, 10, &odr);
388 if (err < 0)
389 goto conversion_error;
390
391 mutex_lock(&indio_dev->mlock);
392 err = st_sensors_set_odr(indio_dev, odr);
393 mutex_unlock(&indio_dev->mlock);
394
395conversion_error:
396 return err < 0 ? err : size;
397}
398EXPORT_SYMBOL(st_sensors_sysfs_set_sampling_frequency);
399
400ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
401 struct device_attribute *attr, char *buf)
402{
403 int i, len = 0;
404 struct iio_dev *indio_dev = dev_get_drvdata(dev);
405 struct st_sensor_data *sdata = iio_priv(indio_dev);
406
407 mutex_lock(&indio_dev->mlock);
408 for (i = 0; i < ST_SENSORS_ODR_LIST_MAX; i++) {
409 if (sdata->sensor->odr.odr_avl[i].hz == 0)
410 break;
411
412 len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
413 sdata->sensor->odr.odr_avl[i].hz);
414 }
415 mutex_unlock(&indio_dev->mlock);
416 buf[len - 1] = '\n';
417
418 return len;
419}
420EXPORT_SYMBOL(st_sensors_sysfs_sampling_frequency_avail);
421
422ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
423 struct device_attribute *attr, char *buf)
424{
425 int i, len = 0;
426 struct iio_dev *indio_dev = dev_get_drvdata(dev);
427 struct st_sensor_data *sdata = iio_priv(indio_dev);
428
429 mutex_lock(&indio_dev->mlock);
430 for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
431 if (sdata->sensor->fs.fs_avl[i].num == 0)
432 break;
433
434 len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
435 sdata->sensor->fs.fs_avl[i].gain);
436 }
437 mutex_unlock(&indio_dev->mlock);
438 buf[len - 1] = '\n';
439
440 return len;
441}
442EXPORT_SYMBOL(st_sensors_sysfs_scale_avail);
443
444MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
445MODULE_DESCRIPTION("STMicroelectronics ST-sensors core");
446MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/common/st_sensors/st_sensors_i2c.c b/drivers/iio/common/st_sensors/st_sensors_i2c.c
new file mode 100644
index 000000000000..38af9440c103
--- /dev/null
+++ b/drivers/iio/common/st_sensors/st_sensors_i2c.c
@@ -0,0 +1,81 @@
1/*
2 * STMicroelectronics sensors i2c library 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/iio/iio.h>
15
16#include <linux/iio/common/st_sensors_i2c.h>
17
18
19#define ST_SENSORS_I2C_MULTIREAD 0x80
20
21static unsigned int st_sensors_i2c_get_irq(struct iio_dev *indio_dev)
22{
23 struct st_sensor_data *sdata = iio_priv(indio_dev);
24
25 return to_i2c_client(sdata->dev)->irq;
26}
27
28static int st_sensors_i2c_read_byte(struct st_sensor_transfer_buffer *tb,
29 struct device *dev, u8 reg_addr, u8 *res_byte)
30{
31 int err;
32
33 err = i2c_smbus_read_byte_data(to_i2c_client(dev), reg_addr);
34 if (err < 0)
35 goto st_accel_i2c_read_byte_error;
36
37 *res_byte = err & 0xff;
38
39st_accel_i2c_read_byte_error:
40 return err < 0 ? err : 0;
41}
42
43static int st_sensors_i2c_read_multiple_byte(
44 struct st_sensor_transfer_buffer *tb, struct device *dev,
45 u8 reg_addr, int len, u8 *data, bool multiread_bit)
46{
47 if (multiread_bit)
48 reg_addr |= ST_SENSORS_I2C_MULTIREAD;
49
50 return i2c_smbus_read_i2c_block_data(to_i2c_client(dev),
51 reg_addr, len, data);
52}
53
54static int st_sensors_i2c_write_byte(struct st_sensor_transfer_buffer *tb,
55 struct device *dev, u8 reg_addr, u8 data)
56{
57 return i2c_smbus_write_byte_data(to_i2c_client(dev), reg_addr, data);
58}
59
60static const struct st_sensor_transfer_function st_sensors_tf_i2c = {
61 .read_byte = st_sensors_i2c_read_byte,
62 .write_byte = st_sensors_i2c_write_byte,
63 .read_multiple_byte = st_sensors_i2c_read_multiple_byte,
64};
65
66void st_sensors_i2c_configure(struct iio_dev *indio_dev,
67 struct i2c_client *client, struct st_sensor_data *sdata)
68{
69 i2c_set_clientdata(client, indio_dev);
70
71 indio_dev->dev.parent = &client->dev;
72 indio_dev->name = client->name;
73
74 sdata->tf = &st_sensors_tf_i2c;
75 sdata->get_irq_data_ready = st_sensors_i2c_get_irq;
76}
77EXPORT_SYMBOL(st_sensors_i2c_configure);
78
79MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
80MODULE_DESCRIPTION("STMicroelectronics ST-sensors i2c driver");
81MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/common/st_sensors/st_sensors_spi.c b/drivers/iio/common/st_sensors/st_sensors_spi.c
new file mode 100644
index 000000000000..f0aa2f105222
--- /dev/null
+++ b/drivers/iio/common/st_sensors/st_sensors_spi.c
@@ -0,0 +1,128 @@
1/*
2 * STMicroelectronics sensors spi library 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/iio/iio.h>
15
16#include <linux/iio/common/st_sensors_spi.h>
17
18
19#define ST_SENSORS_SPI_MULTIREAD 0xc0
20#define ST_SENSORS_SPI_READ 0x80
21
22static unsigned int st_sensors_spi_get_irq(struct iio_dev *indio_dev)
23{
24 struct st_sensor_data *sdata = iio_priv(indio_dev);
25
26 return to_spi_device(sdata->dev)->irq;
27}
28
29static int st_sensors_spi_read(struct st_sensor_transfer_buffer *tb,
30 struct device *dev, u8 reg_addr, int len, u8 *data, bool multiread_bit)
31{
32 struct spi_message msg;
33 int err;
34
35 struct spi_transfer xfers[] = {
36 {
37 .tx_buf = tb->tx_buf,
38 .bits_per_word = 8,
39 .len = 1,
40 },
41 {
42 .rx_buf = tb->rx_buf,
43 .bits_per_word = 8,
44 .len = len,
45 }
46 };
47
48 mutex_lock(&tb->buf_lock);
49 if ((multiread_bit) && (len > 1))
50 tb->tx_buf[0] = reg_addr | ST_SENSORS_SPI_MULTIREAD;
51 else
52 tb->tx_buf[0] = reg_addr | ST_SENSORS_SPI_READ;
53
54 spi_message_init(&msg);
55 spi_message_add_tail(&xfers[0], &msg);
56 spi_message_add_tail(&xfers[1], &msg);
57 err = spi_sync(to_spi_device(dev), &msg);
58 if (err)
59 goto acc_spi_read_error;
60
61 memcpy(data, tb->rx_buf, len*sizeof(u8));
62 mutex_unlock(&tb->buf_lock);
63 return len;
64
65acc_spi_read_error:
66 mutex_unlock(&tb->buf_lock);
67 return err;
68}
69
70static int st_sensors_spi_read_byte(struct st_sensor_transfer_buffer *tb,
71 struct device *dev, u8 reg_addr, u8 *res_byte)
72{
73 return st_sensors_spi_read(tb, dev, reg_addr, 1, res_byte, false);
74}
75
76static int st_sensors_spi_read_multiple_byte(
77 struct st_sensor_transfer_buffer *tb, struct device *dev,
78 u8 reg_addr, int len, u8 *data, bool multiread_bit)
79{
80 return st_sensors_spi_read(tb, dev, reg_addr, len, data, multiread_bit);
81}
82
83static int st_sensors_spi_write_byte(struct st_sensor_transfer_buffer *tb,
84 struct device *dev, u8 reg_addr, u8 data)
85{
86 struct spi_message msg;
87 int err;
88
89 struct spi_transfer xfers = {
90 .tx_buf = tb->tx_buf,
91 .bits_per_word = 8,
92 .len = 2,
93 };
94
95 mutex_lock(&tb->buf_lock);
96 tb->tx_buf[0] = reg_addr;
97 tb->tx_buf[1] = data;
98
99 spi_message_init(&msg);
100 spi_message_add_tail(&xfers, &msg);
101 err = spi_sync(to_spi_device(dev), &msg);
102 mutex_unlock(&tb->buf_lock);
103
104 return err;
105}
106
107static const struct st_sensor_transfer_function st_sensors_tf_spi = {
108 .read_byte = st_sensors_spi_read_byte,
109 .write_byte = st_sensors_spi_write_byte,
110 .read_multiple_byte = st_sensors_spi_read_multiple_byte,
111};
112
113void st_sensors_spi_configure(struct iio_dev *indio_dev,
114 struct spi_device *spi, struct st_sensor_data *sdata)
115{
116 spi_set_drvdata(spi, indio_dev);
117
118 indio_dev->dev.parent = &spi->dev;
119 indio_dev->name = spi->modalias;
120
121 sdata->tf = &st_sensors_tf_spi;
122 sdata->get_irq_data_ready = st_sensors_spi_get_irq;
123}
124EXPORT_SYMBOL(st_sensors_spi_configure);
125
126MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
127MODULE_DESCRIPTION("STMicroelectronics ST-sensors spi driver");
128MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/common/st_sensors/st_sensors_trigger.c b/drivers/iio/common/st_sensors/st_sensors_trigger.c
new file mode 100644
index 000000000000..139ed030abb0
--- /dev/null
+++ b/drivers/iio/common/st_sensors/st_sensors_trigger.c
@@ -0,0 +1,77 @@
1/*
2 * STMicroelectronics sensors trigger library 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/iio/iio.h>
15#include <linux/iio/trigger.h>
16#include <linux/interrupt.h>
17
18#include <linux/iio/common/st_sensors.h>
19
20
21int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
22 const struct iio_trigger_ops *trigger_ops)
23{
24 int err;
25 struct st_sensor_data *sdata = iio_priv(indio_dev);
26
27 sdata->trig = iio_trigger_alloc("%s-trigger", indio_dev->name);
28 if (sdata->trig == NULL) {
29 err = -ENOMEM;
30 dev_err(&indio_dev->dev, "failed to allocate iio trigger.\n");
31 goto iio_trigger_alloc_error;
32 }
33
34 err = request_threaded_irq(sdata->get_irq_data_ready(indio_dev),
35 iio_trigger_generic_data_rdy_poll,
36 NULL,
37 IRQF_TRIGGER_RISING,
38 sdata->trig->name,
39 sdata->trig);
40 if (err)
41 goto request_irq_error;
42
43 sdata->trig->private_data = indio_dev;
44 sdata->trig->ops = trigger_ops;
45 sdata->trig->dev.parent = sdata->dev;
46
47 err = iio_trigger_register(sdata->trig);
48 if (err < 0) {
49 dev_err(&indio_dev->dev, "failed to register iio trigger.\n");
50 goto iio_trigger_register_error;
51 }
52 indio_dev->trig = sdata->trig;
53
54 return 0;
55
56iio_trigger_register_error:
57 free_irq(sdata->get_irq_data_ready(indio_dev), sdata->trig);
58request_irq_error:
59 iio_trigger_free(sdata->trig);
60iio_trigger_alloc_error:
61 return err;
62}
63EXPORT_SYMBOL(st_sensors_allocate_trigger);
64
65void st_sensors_deallocate_trigger(struct iio_dev *indio_dev)
66{
67 struct st_sensor_data *sdata = iio_priv(indio_dev);
68
69 iio_trigger_unregister(sdata->trig);
70 free_irq(sdata->get_irq_data_ready(indio_dev), sdata->trig);
71 iio_trigger_free(sdata->trig);
72}
73EXPORT_SYMBOL(st_sensors_deallocate_trigger);
74
75MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
76MODULE_DESCRIPTION("STMicroelectronics ST-sensors trigger");
77MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig
index 752ac8a3448b..6be4628faffe 100644
--- a/drivers/iio/gyro/Kconfig
+++ b/drivers/iio/gyro/Kconfig
@@ -19,6 +19,16 @@ config ADIS16136
19 Say yes here to build support for the Analog Devices ADIS16133, ADIS16135, 19 Say yes here to build support for the Analog Devices ADIS16133, ADIS16135,
20 ADIS16136 gyroscope devices. 20 ADIS16136 gyroscope devices.
21 21
22config ADXRS450
23 tristate "Analog Devices ADXRS450/3 Digital Output Gyroscope SPI driver"
24 depends on SPI
25 help
26 Say yes here to build support for Analog Devices ADXRS450 and ADXRS453
27 programmable digital output gyroscope.
28
29 This driver can also be built as a module. If so, the module
30 will be called adxrs450.
31
22config HID_SENSOR_GYRO_3D 32config HID_SENSOR_GYRO_3D
23 depends on HID_SENSOR_HUB 33 depends on HID_SENSOR_HUB
24 select IIO_BUFFER 34 select IIO_BUFFER
@@ -30,4 +40,42 @@ config HID_SENSOR_GYRO_3D
30 Say yes here to build support for the HID SENSOR 40 Say yes here to build support for the HID SENSOR
31 Gyroscope 3D. 41 Gyroscope 3D.
32 42
43config IIO_ST_GYRO_3AXIS
44 tristate "STMicroelectronics gyroscopes 3-Axis Driver"
45 depends on (I2C || SPI_MASTER) && SYSFS
46 select IIO_ST_SENSORS_CORE
47 select IIO_ST_GYRO_I2C_3AXIS if (I2C)
48 select IIO_ST_GYRO_SPI_3AXIS if (SPI_MASTER)
49 select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
50 select IIO_ST_GYRO_BUFFER if (IIO_TRIGGERED_BUFFER)
51 help
52 Say yes here to build support for STMicroelectronics gyroscopes:
53 L3G4200D, LSM330DL, L3GD20, L3GD20H, LSM330DLC, L3G4IS, LSM330.
54
55 This driver can also be built as a module. If so, will be created
56 these modules:
57 - st_gyro (core functions for the driver [it is mandatory]);
58 - st_gyro_i2c (necessary for the I2C devices [optional*]);
59 - st_gyro_spi (necessary for the SPI devices [optional*]);
60
61 (*) one of these is necessary to do something.
62
63config IIO_ST_GYRO_I2C_3AXIS
64 tristate
65 depends on IIO_ST_GYRO_3AXIS
66 depends on IIO_ST_SENSORS_I2C
67
68config IIO_ST_GYRO_SPI_3AXIS
69 tristate
70 depends on IIO_ST_GYRO_3AXIS
71 depends on IIO_ST_SENSORS_SPI
72
73config ITG3200
74 tristate "InvenSense ITG3200 Digital 3-Axis Gyroscope I2C driver"
75 depends on I2C
76 select IIO_TRIGGERED_BUFFER if IIO_BUFFER
77 help
78 Say yes here to add support for the InvenSense ITG3200 digital
79 3-axis gyroscope sensor.
80
33endmenu 81endmenu
diff --git a/drivers/iio/gyro/Makefile b/drivers/iio/gyro/Makefile
index 9b090ee084d3..225d289082e6 100644
--- a/drivers/iio/gyro/Makefile
+++ b/drivers/iio/gyro/Makefile
@@ -4,4 +4,17 @@
4 4
5obj-$(CONFIG_ADIS16080) += adis16080.o 5obj-$(CONFIG_ADIS16080) += adis16080.o
6obj-$(CONFIG_ADIS16136) += adis16136.o 6obj-$(CONFIG_ADIS16136) += adis16136.o
7obj-$(CONFIG_ADXRS450) += adxrs450.o
8
7obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o 9obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o
10
11itg3200-y := itg3200_core.o
12itg3200-$(CONFIG_IIO_BUFFER) += itg3200_buffer.o
13obj-$(CONFIG_ITG3200) += itg3200.o
14
15obj-$(CONFIG_IIO_ST_GYRO_3AXIS) += st_gyro.o
16st_gyro-y := st_gyro_core.o
17st_gyro-$(CONFIG_IIO_BUFFER) += st_gyro_buffer.o
18
19obj-$(CONFIG_IIO_ST_GYRO_I2C_3AXIS) += st_gyro_i2c.o
20obj-$(CONFIG_IIO_ST_GYRO_SPI_3AXIS) += st_gyro_spi.o
diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/iio/gyro/adxrs450.c
index f0ce81da8aca..d9d43831c380 100644
--- a/drivers/staging/iio/gyro/adxrs450_core.c
+++ b/drivers/iio/gyro/adxrs450.c
@@ -21,45 +21,110 @@
21#include <linux/iio/iio.h> 21#include <linux/iio/iio.h>
22#include <linux/iio/sysfs.h> 22#include <linux/iio/sysfs.h>
23 23
24#include "adxrs450.h" 24#define ADXRS450_STARTUP_DELAY 50 /* ms */
25
26/* The MSB for the spi commands */
27#define ADXRS450_SENSOR_DATA (0x20 << 24)
28#define ADXRS450_WRITE_DATA (0x40 << 24)
29#define ADXRS450_READ_DATA (0x80 << 24)
30
31#define ADXRS450_RATE1 0x00 /* Rate Registers */
32#define ADXRS450_TEMP1 0x02 /* Temperature Registers */
33#define ADXRS450_LOCST1 0x04 /* Low CST Memory Registers */
34#define ADXRS450_HICST1 0x06 /* High CST Memory Registers */
35#define ADXRS450_QUAD1 0x08 /* Quad Memory Registers */
36#define ADXRS450_FAULT1 0x0A /* Fault Registers */
37#define ADXRS450_PID1 0x0C /* Part ID Register 1 */
38#define ADXRS450_SNH 0x0E /* Serial Number Registers, 4 bytes */
39#define ADXRS450_SNL 0x10
40#define ADXRS450_DNC1 0x12 /* Dynamic Null Correction Registers */
41/* Check bits */
42#define ADXRS450_P 0x01
43#define ADXRS450_CHK 0x02
44#define ADXRS450_CST 0x04
45#define ADXRS450_PWR 0x08
46#define ADXRS450_POR 0x10
47#define ADXRS450_NVM 0x20
48#define ADXRS450_Q 0x40
49#define ADXRS450_PLL 0x80
50#define ADXRS450_UV 0x100
51#define ADXRS450_OV 0x200
52#define ADXRS450_AMP 0x400
53#define ADXRS450_FAIL 0x800
54
55#define ADXRS450_WRERR_MASK (0x7 << 29)
56
57#define ADXRS450_MAX_RX 4
58#define ADXRS450_MAX_TX 4
59
60#define ADXRS450_GET_ST(a) ((a >> 26) & 0x3)
61
62enum {
63 ID_ADXRS450,
64 ID_ADXRS453,
65};
66
67/**
68 * struct adxrs450_state - device instance specific data
69 * @us: actual spi_device
70 * @buf_lock: mutex to protect tx and rx
71 * @tx: transmit buffer
72 * @rx: receive buffer
73 **/
74struct adxrs450_state {
75 struct spi_device *us;
76 struct mutex buf_lock;
77 __be32 tx ____cacheline_aligned;
78 __be32 rx;
79
80};
25 81
26/** 82/**
27 * adxrs450_spi_read_reg_16() - read 2 bytes from a register pair 83 * adxrs450_spi_read_reg_16() - read 2 bytes from a register pair
28 * @dev: device associated with child of actual iio_dev 84 * @indio_dev: device associated with child of actual iio_dev
29 * @reg_address: the address of the lower of the two registers,which should be an even address, 85 * @reg_address: the address of the lower of the two registers, which should be
30 * Second register's address is reg_address + 1. 86 * an even address, the second register's address is reg_address + 1.
31 * @val: somewhere to pass back the value read 87 * @val: somewhere to pass back the value read
32 **/ 88 **/
33static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev, 89static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev,
34 u8 reg_address, 90 u8 reg_address,
35 u16 *val) 91 u16 *val)
36{ 92{
93 struct spi_message msg;
37 struct adxrs450_state *st = iio_priv(indio_dev); 94 struct adxrs450_state *st = iio_priv(indio_dev);
95 u32 tx;
38 int ret; 96 int ret;
97 struct spi_transfer xfers[] = {
98 {
99 .tx_buf = &st->tx,
100 .bits_per_word = 8,
101 .len = sizeof(st->tx),
102 .cs_change = 1,
103 }, {
104 .rx_buf = &st->rx,
105 .bits_per_word = 8,
106 .len = sizeof(st->rx),
107 },
108 };
39 109
40 mutex_lock(&st->buf_lock); 110 mutex_lock(&st->buf_lock);
41 st->tx[0] = ADXRS450_READ_DATA | (reg_address >> 7); 111 tx = ADXRS450_READ_DATA | (reg_address << 17);
42 st->tx[1] = reg_address << 1;
43 st->tx[2] = 0;
44 st->tx[3] = 0;
45 112
46 if (!(hweight32(be32_to_cpu(*(u32 *)st->tx)) & 1)) 113 if (!(hweight32(tx) & 1))
47 st->tx[3] |= ADXRS450_P; 114 tx |= ADXRS450_P;
48 115
49 ret = spi_write(st->us, st->tx, 4); 116 st->tx = cpu_to_be32(tx);
50 if (ret) { 117 spi_message_init(&msg);
51 dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n", 118 spi_message_add_tail(&xfers[0], &msg);
52 reg_address); 119 spi_message_add_tail(&xfers[1], &msg);
53 goto error_ret; 120 ret = spi_sync(st->us, &msg);
54 }
55 ret = spi_read(st->us, st->rx, 4);
56 if (ret) { 121 if (ret) {
57 dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n", 122 dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n",
58 reg_address); 123 reg_address);
59 goto error_ret; 124 goto error_ret;
60 } 125 }
61 126
62 *val = (be32_to_cpu(*(u32 *)st->rx) >> 5) & 0xFFFF; 127 *val = (be32_to_cpu(st->rx) >> 5) & 0xFFFF;
63 128
64error_ret: 129error_ret:
65 mutex_unlock(&st->buf_lock); 130 mutex_unlock(&st->buf_lock);
@@ -68,9 +133,9 @@ error_ret:
68 133
69/** 134/**
70 * adxrs450_spi_write_reg_16() - write 2 bytes data to a register pair 135 * adxrs450_spi_write_reg_16() - write 2 bytes data to a register pair
71 * @dev: device associated with child of actual actual iio_dev 136 * @indio_dev: device associated with child of actual actual iio_dev
72 * @reg_address: the address of the lower of the two registers,which should be an even address, 137 * @reg_address: the address of the lower of the two registers,which should be
73 * Second register's address is reg_address + 1. 138 * an even address, the second register's address is reg_address + 1.
74 * @val: value to be written. 139 * @val: value to be written.
75 **/ 140 **/
76static int adxrs450_spi_write_reg_16(struct iio_dev *indio_dev, 141static int adxrs450_spi_write_reg_16(struct iio_dev *indio_dev,
@@ -78,55 +143,61 @@ static int adxrs450_spi_write_reg_16(struct iio_dev *indio_dev,
78 u16 val) 143 u16 val)
79{ 144{
80 struct adxrs450_state *st = iio_priv(indio_dev); 145 struct adxrs450_state *st = iio_priv(indio_dev);
146 u32 tx;
81 int ret; 147 int ret;
82 148
83 mutex_lock(&st->buf_lock); 149 mutex_lock(&st->buf_lock);
84 st->tx[0] = ADXRS450_WRITE_DATA | reg_address >> 7; 150 tx = ADXRS450_WRITE_DATA | (reg_address << 17) | (val << 1);
85 st->tx[1] = reg_address << 1 | val >> 15;
86 st->tx[2] = val >> 7;
87 st->tx[3] = val << 1;
88 151
89 if (!(hweight32(be32_to_cpu(*(u32 *)st->tx)) & 1)) 152 if (!(hweight32(tx) & 1))
90 st->tx[3] |= ADXRS450_P; 153 tx |= ADXRS450_P;
91 154
92 ret = spi_write(st->us, st->tx, 4); 155 st->tx = cpu_to_be32(tx);
156 ret = spi_write(st->us, &st->tx, sizeof(st->tx));
93 if (ret) 157 if (ret)
94 dev_err(&st->us->dev, "problem while writing 16 bit register 0x%02x\n", 158 dev_err(&st->us->dev, "problem while writing 16 bit register 0x%02x\n",
95 reg_address); 159 reg_address);
96 msleep(1); /* enforce sequential transfer delay 0.1ms */ 160 usleep_range(100, 1000); /* enforce sequential transfer delay 0.1ms */
97 mutex_unlock(&st->buf_lock); 161 mutex_unlock(&st->buf_lock);
98 return ret; 162 return ret;
99} 163}
100 164
101/** 165/**
102 * adxrs450_spi_sensor_data() - read 2 bytes sensor data 166 * adxrs450_spi_sensor_data() - read 2 bytes sensor data
103 * @dev: device associated with child of actual iio_dev 167 * @indio_dev: device associated with child of actual iio_dev
104 * @val: somewhere to pass back the value read 168 * @val: somewhere to pass back the value read
105 **/ 169 **/
106static int adxrs450_spi_sensor_data(struct iio_dev *indio_dev, s16 *val) 170static int adxrs450_spi_sensor_data(struct iio_dev *indio_dev, s16 *val)
107{ 171{
172 struct spi_message msg;
108 struct adxrs450_state *st = iio_priv(indio_dev); 173 struct adxrs450_state *st = iio_priv(indio_dev);
109 int ret; 174 int ret;
175 struct spi_transfer xfers[] = {
176 {
177 .tx_buf = &st->tx,
178 .bits_per_word = 8,
179 .len = sizeof(st->tx),
180 .cs_change = 1,
181 }, {
182 .rx_buf = &st->rx,
183 .bits_per_word = 8,
184 .len = sizeof(st->rx),
185 },
186 };
110 187
111 mutex_lock(&st->buf_lock); 188 mutex_lock(&st->buf_lock);
112 st->tx[0] = ADXRS450_SENSOR_DATA; 189 st->tx = cpu_to_be32(ADXRS450_SENSOR_DATA);
113 st->tx[1] = 0;
114 st->tx[2] = 0;
115 st->tx[3] = 0;
116 190
117 ret = spi_write(st->us, st->tx, 4); 191 spi_message_init(&msg);
118 if (ret) { 192 spi_message_add_tail(&xfers[0], &msg);
119 dev_err(&st->us->dev, "Problem while reading sensor data\n"); 193 spi_message_add_tail(&xfers[1], &msg);
120 goto error_ret; 194 ret = spi_sync(st->us, &msg);
121 }
122
123 ret = spi_read(st->us, st->rx, 4);
124 if (ret) { 195 if (ret) {
125 dev_err(&st->us->dev, "Problem while reading sensor data\n"); 196 dev_err(&st->us->dev, "Problem while reading sensor data\n");
126 goto error_ret; 197 goto error_ret;
127 } 198 }
128 199
129 *val = (be32_to_cpu(*(u32 *)st->rx) >> 10) & 0xFFFF; 200 *val = (be32_to_cpu(st->rx) >> 10) & 0xFFFF;
130 201
131error_ret: 202error_ret:
132 mutex_unlock(&st->buf_lock); 203 mutex_unlock(&st->buf_lock);
@@ -137,26 +208,26 @@ error_ret:
137 * adxrs450_spi_initial() - use for initializing procedure. 208 * adxrs450_spi_initial() - use for initializing procedure.
138 * @st: device instance specific data 209 * @st: device instance specific data
139 * @val: somewhere to pass back the value read 210 * @val: somewhere to pass back the value read
211 * @chk: Whether to perform fault check
140 **/ 212 **/
141static int adxrs450_spi_initial(struct adxrs450_state *st, 213static int adxrs450_spi_initial(struct adxrs450_state *st,
142 u32 *val, char chk) 214 u32 *val, char chk)
143{ 215{
144 struct spi_message msg; 216 struct spi_message msg;
145 int ret; 217 int ret;
218 u32 tx;
146 struct spi_transfer xfers = { 219 struct spi_transfer xfers = {
147 .tx_buf = st->tx, 220 .tx_buf = &st->tx,
148 .rx_buf = st->rx, 221 .rx_buf = &st->rx,
149 .bits_per_word = 8, 222 .bits_per_word = 8,
150 .len = 4, 223 .len = sizeof(st->tx),
151 }; 224 };
152 225
153 mutex_lock(&st->buf_lock); 226 mutex_lock(&st->buf_lock);
154 st->tx[0] = ADXRS450_SENSOR_DATA; 227 tx = ADXRS450_SENSOR_DATA;
155 st->tx[1] = 0;
156 st->tx[2] = 0;
157 st->tx[3] = 0;
158 if (chk) 228 if (chk)
159 st->tx[3] |= (ADXRS450_CHK | ADXRS450_P); 229 tx |= (ADXRS450_CHK | ADXRS450_P);
230 st->tx = cpu_to_be32(tx);
160 spi_message_init(&msg); 231 spi_message_init(&msg);
161 spi_message_add_tail(&xfers, &msg); 232 spi_message_add_tail(&xfers, &msg);
162 ret = spi_sync(st->us, &msg); 233 ret = spi_sync(st->us, &msg);
@@ -165,7 +236,7 @@ static int adxrs450_spi_initial(struct adxrs450_state *st,
165 goto error_ret; 236 goto error_ret;
166 } 237 }
167 238
168 *val = be32_to_cpu(*(u32 *)st->rx); 239 *val = be32_to_cpu(st->rx);
169 240
170error_ret: 241error_ret:
171 mutex_unlock(&st->buf_lock); 242 mutex_unlock(&st->buf_lock);
@@ -185,8 +256,7 @@ static int adxrs450_initial_setup(struct iio_dev *indio_dev)
185 if (ret) 256 if (ret)
186 return ret; 257 return ret;
187 if (t != 0x01) 258 if (t != 0x01)
188 dev_warn(&st->us->dev, "The initial power on response " 259 dev_warn(&st->us->dev, "The initial power on response is not correct! Restart without reset?\n");
189 "is not correct! Restart without reset?\n");
190 260
191 msleep(ADXRS450_STARTUP_DELAY); 261 msleep(ADXRS450_STARTUP_DELAY);
192 ret = adxrs450_spi_initial(st, &t, 0); 262 ret = adxrs450_spi_initial(st, &t, 0);
@@ -217,20 +287,6 @@ static int adxrs450_initial_setup(struct iio_dev *indio_dev)
217 dev_err(&st->us->dev, "The device is not in normal status!\n"); 287 dev_err(&st->us->dev, "The device is not in normal status!\n");
218 return -EINVAL; 288 return -EINVAL;
219 } 289 }
220 ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_PID1, &data);
221 if (ret)
222 return ret;
223 dev_info(&st->us->dev, "The Part ID is 0x%x\n", data);
224
225 ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_SNL, &data);
226 if (ret)
227 return ret;
228 t = data;
229 ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_SNH, &data);
230 if (ret)
231 return ret;
232 t |= data << 16;
233 dev_info(&st->us->dev, "The Serial Number is 0x%x\n", t);
234 290
235 return 0; 291 return 0;
236} 292}
@@ -244,9 +300,10 @@ static int adxrs450_write_raw(struct iio_dev *indio_dev,
244 int ret; 300 int ret;
245 switch (mask) { 301 switch (mask) {
246 case IIO_CHAN_INFO_CALIBBIAS: 302 case IIO_CHAN_INFO_CALIBBIAS:
303 if (val < -0x400 || val >= 0x400)
304 return -EINVAL;
247 ret = adxrs450_spi_write_reg_16(indio_dev, 305 ret = adxrs450_spi_write_reg_16(indio_dev,
248 ADXRS450_DNC1, 306 ADXRS450_DNC1, val);
249 val & 0x3FF);
250 break; 307 break;
251 default: 308 default:
252 ret = -EINVAL; 309 ret = -EINVAL;
@@ -312,7 +369,7 @@ static int adxrs450_read_raw(struct iio_dev *indio_dev,
312 ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_DNC1, &t); 369 ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_DNC1, &t);
313 if (ret) 370 if (ret)
314 break; 371 break;
315 *val = t; 372 *val = sign_extend32(t, 9);
316 ret = IIO_VAL_INT; 373 ret = IIO_VAL_INT;
317 break; 374 break;
318 default: 375 default:
diff --git a/drivers/iio/gyro/itg3200_buffer.c b/drivers/iio/gyro/itg3200_buffer.c
new file mode 100644
index 000000000000..f667d2c8c00f
--- /dev/null
+++ b/drivers/iio/gyro/itg3200_buffer.c
@@ -0,0 +1,156 @@
1/*
2 * itg3200_buffer.c -- support InvenSense ITG3200
3 * Digital 3-Axis Gyroscope driver
4 *
5 * Copyright (c) 2011 Christian Strobel <christian.strobel@iis.fraunhofer.de>
6 * Copyright (c) 2011 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
7 * Copyright (c) 2012 Thorsten Nowak <thorsten.nowak@iis.fraunhofer.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/slab.h>
15#include <linux/i2c.h>
16#include <linux/interrupt.h>
17
18#include <linux/iio/iio.h>
19#include <linux/iio/buffer.h>
20#include <linux/iio/trigger.h>
21#include <linux/iio/trigger_consumer.h>
22#include <linux/iio/triggered_buffer.h>
23#include <linux/iio/gyro/itg3200.h>
24
25
26static int itg3200_read_all_channels(struct i2c_client *i2c, __be16 *buf)
27{
28 u8 tx = 0x80 | ITG3200_REG_TEMP_OUT_H;
29 struct i2c_msg msg[2] = {
30 {
31 .addr = i2c->addr,
32 .flags = i2c->flags,
33 .len = 1,
34 .buf = &tx,
35 },
36 {
37 .addr = i2c->addr,
38 .flags = i2c->flags | I2C_M_RD,
39 .len = ITG3200_SCAN_ELEMENTS * sizeof(s16),
40 .buf = (char *)&buf,
41 },
42 };
43
44 return i2c_transfer(i2c->adapter, msg, 2);
45}
46
47static irqreturn_t itg3200_trigger_handler(int irq, void *p)
48{
49 struct iio_poll_func *pf = p;
50 struct iio_dev *indio_dev = pf->indio_dev;
51 struct itg3200 *st = iio_priv(indio_dev);
52 __be16 buf[ITG3200_SCAN_ELEMENTS + sizeof(s64)/sizeof(u16)];
53
54 int ret = itg3200_read_all_channels(st->i2c, buf);
55 if (ret < 0)
56 goto error_ret;
57
58 if (indio_dev->scan_timestamp)
59 memcpy(buf + indio_dev->scan_bytes - sizeof(s64),
60 &pf->timestamp, sizeof(pf->timestamp));
61
62 iio_push_to_buffers(indio_dev, (u8 *)buf);
63 iio_trigger_notify_done(indio_dev->trig);
64
65error_ret:
66 return IRQ_HANDLED;
67}
68
69int itg3200_buffer_configure(struct iio_dev *indio_dev)
70{
71 return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
72 itg3200_trigger_handler, NULL);
73}
74
75void itg3200_buffer_unconfigure(struct iio_dev *indio_dev)
76{
77 iio_triggered_buffer_cleanup(indio_dev);
78}
79
80
81static int itg3200_data_rdy_trigger_set_state(struct iio_trigger *trig,
82 bool state)
83{
84 struct iio_dev *indio_dev = trig->private_data;
85 int ret;
86 u8 msc;
87
88 ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_IRQ_CONFIG, &msc);
89 if (ret)
90 goto error_ret;
91
92 if (state)
93 msc |= ITG3200_IRQ_DATA_RDY_ENABLE;
94 else
95 msc &= ~ITG3200_IRQ_DATA_RDY_ENABLE;
96
97 ret = itg3200_write_reg_8(indio_dev, ITG3200_REG_IRQ_CONFIG, msc);
98 if (ret)
99 goto error_ret;
100
101error_ret:
102 return ret;
103
104}
105
106static const struct iio_trigger_ops itg3200_trigger_ops = {
107 .owner = THIS_MODULE,
108 .set_trigger_state = &itg3200_data_rdy_trigger_set_state,
109};
110
111int itg3200_probe_trigger(struct iio_dev *indio_dev)
112{
113 int ret;
114 struct itg3200 *st = iio_priv(indio_dev);
115
116 st->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
117 indio_dev->id);
118 if (!st->trig)
119 return -ENOMEM;
120
121 ret = request_irq(st->i2c->irq,
122 &iio_trigger_generic_data_rdy_poll,
123 IRQF_TRIGGER_RISING,
124 "itg3200_data_rdy",
125 st->trig);
126 if (ret)
127 goto error_free_trig;
128
129
130 st->trig->dev.parent = &st->i2c->dev;
131 st->trig->ops = &itg3200_trigger_ops;
132 st->trig->private_data = indio_dev;
133 ret = iio_trigger_register(st->trig);
134 if (ret)
135 goto error_free_irq;
136
137 /* select default trigger */
138 indio_dev->trig = st->trig;
139
140 return 0;
141
142error_free_irq:
143 free_irq(st->i2c->irq, st->trig);
144error_free_trig:
145 iio_trigger_free(st->trig);
146 return ret;
147}
148
149void itg3200_remove_trigger(struct iio_dev *indio_dev)
150{
151 struct itg3200 *st = iio_priv(indio_dev);
152
153 iio_trigger_unregister(st->trig);
154 free_irq(st->i2c->irq, st->trig);
155 iio_trigger_free(st->trig);
156}
diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c
new file mode 100644
index 000000000000..df2e6aa5d73b
--- /dev/null
+++ b/drivers/iio/gyro/itg3200_core.c
@@ -0,0 +1,401 @@
1/*
2 * itg3200_core.c -- support InvenSense ITG3200
3 * Digital 3-Axis Gyroscope driver
4 *
5 * Copyright (c) 2011 Christian Strobel <christian.strobel@iis.fraunhofer.de>
6 * Copyright (c) 2011 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
7 * Copyright (c) 2012 Thorsten Nowak <thorsten.nowak@iis.fraunhofer.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * TODO:
14 * - Support digital low pass filter
15 * - Support power management
16 */
17
18#include <linux/interrupt.h>
19#include <linux/irq.h>
20#include <linux/i2c.h>
21#include <linux/gpio.h>
22#include <linux/slab.h>
23#include <linux/stat.h>
24#include <linux/module.h>
25#include <linux/delay.h>
26
27#include <linux/iio/iio.h>
28#include <linux/iio/sysfs.h>
29#include <linux/iio/events.h>
30#include <linux/iio/buffer.h>
31
32#include <linux/iio/gyro/itg3200.h>
33
34
35int itg3200_write_reg_8(struct iio_dev *indio_dev,
36 u8 reg_address, u8 val)
37{
38 struct itg3200 *st = iio_priv(indio_dev);
39
40 return i2c_smbus_write_byte_data(st->i2c, 0x80 | reg_address, val);
41}
42
43int itg3200_read_reg_8(struct iio_dev *indio_dev,
44 u8 reg_address, u8 *val)
45{
46 struct itg3200 *st = iio_priv(indio_dev);
47 int ret;
48
49 ret = i2c_smbus_read_byte_data(st->i2c, reg_address);
50 if (ret < 0)
51 return ret;
52 *val = ret;
53 return 0;
54}
55
56static int itg3200_read_reg_s16(struct iio_dev *indio_dev, u8 lower_reg_address,
57 int *val)
58{
59 struct itg3200 *st = iio_priv(indio_dev);
60 struct i2c_client *client = st->i2c;
61 int ret;
62 s16 out;
63
64 struct i2c_msg msg[2] = {
65 {
66 .addr = client->addr,
67 .flags = client->flags,
68 .len = 1,
69 .buf = (char *)&lower_reg_address,
70 },
71 {
72 .addr = client->addr,
73 .flags = client->flags | I2C_M_RD,
74 .len = 2,
75 .buf = (char *)&out,
76 },
77 };
78
79 lower_reg_address |= 0x80;
80 ret = i2c_transfer(client->adapter, msg, 2);
81 be16_to_cpus(&out);
82 *val = out;
83
84 return (ret == 2) ? 0 : ret;
85}
86
87static int itg3200_read_raw(struct iio_dev *indio_dev,
88 const struct iio_chan_spec *chan,
89 int *val, int *val2, long info)
90{
91 int ret = 0;
92 u8 reg;
93
94 switch (info) {
95 case IIO_CHAN_INFO_RAW:
96 reg = (u8)chan->address;
97 ret = itg3200_read_reg_s16(indio_dev, reg, val);
98 return IIO_VAL_INT;
99 case IIO_CHAN_INFO_SCALE:
100 *val = 0;
101 if (chan->type == IIO_TEMP)
102 *val2 = 1000000000/280;
103 else
104 *val2 = 1214142; /* (1 / 14,375) * (PI / 180) */
105 return IIO_VAL_INT_PLUS_NANO;
106 case IIO_CHAN_INFO_OFFSET:
107 /* Only the temperature channel has an offset */
108 *val = 23000;
109 return IIO_VAL_INT;
110 default:
111 return -EINVAL;
112 }
113
114 return ret;
115}
116
117static ssize_t itg3200_read_frequency(struct device *dev,
118 struct device_attribute *attr, char *buf)
119{
120 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
121 int ret, sps;
122 u8 val;
123
124 ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &val);
125 if (ret)
126 return ret;
127
128 sps = (val & ITG3200_DLPF_CFG_MASK) ? 1000 : 8000;
129
130 ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_SAMPLE_RATE_DIV, &val);
131 if (ret)
132 return ret;
133
134 sps /= val + 1;
135
136 return sprintf(buf, "%d\n", sps);
137}
138
139static ssize_t itg3200_write_frequency(struct device *dev,
140 struct device_attribute *attr,
141 const char *buf,
142 size_t len)
143{
144 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
145 unsigned val;
146 int ret;
147 u8 t;
148
149 ret = kstrtouint(buf, 10, &val);
150 if (ret)
151 return ret;
152
153 mutex_lock(&indio_dev->mlock);
154
155 ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &t);
156 if (ret)
157 goto err_ret;
158
159 if (val == 0) {
160 ret = -EINVAL;
161 goto err_ret;
162 }
163 t = ((t & ITG3200_DLPF_CFG_MASK) ? 1000u : 8000u) / val - 1;
164
165 ret = itg3200_write_reg_8(indio_dev, ITG3200_REG_SAMPLE_RATE_DIV, t);
166
167err_ret:
168 mutex_unlock(&indio_dev->mlock);
169
170 return ret ? ret : len;
171}
172
173/*
174 * Reset device and internal registers to the power-up-default settings
175 * Use the gyro clock as reference, as suggested by the datasheet
176 */
177static int itg3200_reset(struct iio_dev *indio_dev)
178{
179 struct itg3200 *st = iio_priv(indio_dev);
180 int ret;
181
182 dev_dbg(&st->i2c->dev, "reset device");
183
184 ret = itg3200_write_reg_8(indio_dev,
185 ITG3200_REG_POWER_MANAGEMENT,
186 ITG3200_RESET);
187 if (ret) {
188 dev_err(&st->i2c->dev, "error resetting device");
189 goto error_ret;
190 }
191
192 /* Wait for PLL (1ms according to datasheet) */
193 udelay(1500);
194
195 ret = itg3200_write_reg_8(indio_dev,
196 ITG3200_REG_IRQ_CONFIG,
197 ITG3200_IRQ_ACTIVE_HIGH |
198 ITG3200_IRQ_PUSH_PULL |
199 ITG3200_IRQ_LATCH_50US_PULSE |
200 ITG3200_IRQ_LATCH_CLEAR_ANY);
201
202 if (ret)
203 dev_err(&st->i2c->dev, "error init device");
204
205error_ret:
206 return ret;
207}
208
209/* itg3200_enable_full_scale() - Disables the digital low pass filter */
210static int itg3200_enable_full_scale(struct iio_dev *indio_dev)
211{
212 u8 val;
213 int ret;
214
215 ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &val);
216 if (ret)
217 goto err_ret;
218
219 val |= ITG3200_DLPF_FS_SEL_2000;
220 return itg3200_write_reg_8(indio_dev, ITG3200_REG_DLPF, val);
221
222err_ret:
223 return ret;
224}
225
226static int itg3200_initial_setup(struct iio_dev *indio_dev)
227{
228 struct itg3200 *st = iio_priv(indio_dev);
229 int ret;
230 u8 val;
231
232 ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_ADDRESS, &val);
233 if (ret)
234 goto err_ret;
235
236 if (((val >> 1) & 0x3f) != 0x34) {
237 dev_err(&st->i2c->dev, "invalid reg value 0x%02x", val);
238 ret = -ENXIO;
239 goto err_ret;
240 }
241
242 ret = itg3200_reset(indio_dev);
243 if (ret)
244 goto err_ret;
245
246 ret = itg3200_enable_full_scale(indio_dev);
247err_ret:
248 return ret;
249}
250
251#define ITG3200_TEMP_INFO_MASK (IIO_CHAN_INFO_OFFSET_SHARED_BIT | \
252 IIO_CHAN_INFO_SCALE_SHARED_BIT | \
253 IIO_CHAN_INFO_RAW_SEPARATE_BIT)
254#define ITG3200_GYRO_INFO_MASK (IIO_CHAN_INFO_SCALE_SHARED_BIT | \
255 IIO_CHAN_INFO_RAW_SEPARATE_BIT)
256
257#define ITG3200_ST \
258 { .sign = 's', .realbits = 16, .storagebits = 16, .endianness = IIO_BE }
259
260#define ITG3200_GYRO_CHAN(_mod) { \
261 .type = IIO_ANGL_VEL, \
262 .modified = 1, \
263 .channel2 = IIO_MOD_ ## _mod, \
264 .info_mask = ITG3200_GYRO_INFO_MASK, \
265 .address = ITG3200_REG_GYRO_ ## _mod ## OUT_H, \
266 .scan_index = ITG3200_SCAN_GYRO_ ## _mod, \
267 .scan_type = ITG3200_ST, \
268}
269
270static const struct iio_chan_spec itg3200_channels[] = {
271 {
272 .type = IIO_TEMP,
273 .channel2 = IIO_NO_MOD,
274 .info_mask = ITG3200_TEMP_INFO_MASK,
275 .address = ITG3200_REG_TEMP_OUT_H,
276 .scan_index = ITG3200_SCAN_TEMP,
277 .scan_type = ITG3200_ST,
278 },
279 ITG3200_GYRO_CHAN(X),
280 ITG3200_GYRO_CHAN(Y),
281 ITG3200_GYRO_CHAN(Z),
282 IIO_CHAN_SOFT_TIMESTAMP(ITG3200_SCAN_ELEMENTS),
283};
284
285/* IIO device attributes */
286static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, itg3200_read_frequency,
287 itg3200_write_frequency);
288
289static struct attribute *itg3200_attributes[] = {
290 &iio_dev_attr_sampling_frequency.dev_attr.attr,
291 NULL
292};
293
294static const struct attribute_group itg3200_attribute_group = {
295 .attrs = itg3200_attributes,
296};
297
298static const struct iio_info itg3200_info = {
299 .attrs = &itg3200_attribute_group,
300 .read_raw = &itg3200_read_raw,
301 .driver_module = THIS_MODULE,
302};
303
304static const unsigned long itg3200_available_scan_masks[] = { 0xffffffff, 0x0 };
305
306static int itg3200_probe(struct i2c_client *client,
307 const struct i2c_device_id *id)
308{
309 int ret;
310 struct itg3200 *st;
311 struct iio_dev *indio_dev;
312
313 dev_dbg(&client->dev, "probe I2C dev with IRQ %i", client->irq);
314
315 indio_dev = iio_device_alloc(sizeof(*st));
316 if (indio_dev == NULL) {
317 ret = -ENOMEM;
318 goto error_ret;
319 }
320
321 st = iio_priv(indio_dev);
322
323 i2c_set_clientdata(client, indio_dev);
324 st->i2c = client;
325
326 indio_dev->dev.parent = &client->dev;
327 indio_dev->name = client->dev.driver->name;
328 indio_dev->channels = itg3200_channels;
329 indio_dev->num_channels = ARRAY_SIZE(itg3200_channels);
330 indio_dev->available_scan_masks = itg3200_available_scan_masks;
331 indio_dev->info = &itg3200_info;
332 indio_dev->modes = INDIO_DIRECT_MODE;
333
334 ret = itg3200_buffer_configure(indio_dev);
335 if (ret)
336 goto error_free_dev;
337
338 if (client->irq) {
339 ret = itg3200_probe_trigger(indio_dev);
340 if (ret)
341 goto error_unconfigure_buffer;
342 }
343
344 ret = itg3200_initial_setup(indio_dev);
345 if (ret)
346 goto error_remove_trigger;
347
348 ret = iio_device_register(indio_dev);
349 if (ret)
350 goto error_remove_trigger;
351
352 return 0;
353
354error_remove_trigger:
355 if (client->irq)
356 itg3200_remove_trigger(indio_dev);
357error_unconfigure_buffer:
358 itg3200_buffer_unconfigure(indio_dev);
359error_free_dev:
360 iio_device_free(indio_dev);
361error_ret:
362 return ret;
363}
364
365static int itg3200_remove(struct i2c_client *client)
366{
367 struct iio_dev *indio_dev = i2c_get_clientdata(client);
368
369 iio_device_unregister(indio_dev);
370
371 if (client->irq)
372 itg3200_remove_trigger(indio_dev);
373
374 itg3200_buffer_unconfigure(indio_dev);
375
376 iio_device_free(indio_dev);
377
378 return 0;
379}
380
381static const struct i2c_device_id itg3200_id[] = {
382 { "itg3200", 0 },
383 { }
384};
385MODULE_DEVICE_TABLE(i2c, itg3200_id);
386
387static struct i2c_driver itg3200_driver = {
388 .driver = {
389 .owner = THIS_MODULE,
390 .name = "itg3200",
391 },
392 .id_table = itg3200_id,
393 .probe = itg3200_probe,
394 .remove = itg3200_remove,
395};
396
397module_i2c_driver(itg3200_driver);
398
399MODULE_AUTHOR("Christian Strobel <christian.strobel@iis.fraunhofer.de>");
400MODULE_DESCRIPTION("ITG3200 Gyroscope I2C driver");
401MODULE_LICENSE("GPL v2");
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");
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index d55e98fb300e..c42aba6817e8 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -54,39 +54,25 @@ error_ret:
54EXPORT_SYMBOL_GPL(iio_map_array_register); 54EXPORT_SYMBOL_GPL(iio_map_array_register);
55 55
56 56
57/* Assumes the exact same array (e.g. memory locations) 57/*
58 * used at unregistration as used at registration rather than 58 * Remove all map entries associated with the given iio device
59 * more complex checking of contents.
60 */ 59 */
61int iio_map_array_unregister(struct iio_dev *indio_dev, 60int iio_map_array_unregister(struct iio_dev *indio_dev)
62 struct iio_map *maps)
63{ 61{
64 int i = 0, ret = 0; 62 int ret = -ENODEV;
65 bool found_it;
66 struct iio_map_internal *mapi; 63 struct iio_map_internal *mapi;
67 64 struct list_head *pos, *tmp;
68 if (maps == NULL)
69 return 0;
70 65
71 mutex_lock(&iio_map_list_lock); 66 mutex_lock(&iio_map_list_lock);
72 while (maps[i].consumer_dev_name != NULL) { 67 list_for_each_safe(pos, tmp, &iio_map_list) {
73 found_it = false; 68 mapi = list_entry(pos, struct iio_map_internal, l);
74 list_for_each_entry(mapi, &iio_map_list, l) 69 if (indio_dev == mapi->indio_dev) {
75 if (&maps[i] == mapi->map) { 70 list_del(&mapi->l);
76 list_del(&mapi->l); 71 kfree(mapi);
77 kfree(mapi); 72 ret = 0;
78 found_it = true;
79 break;
80 }
81 if (!found_it) {
82 ret = -ENODEV;
83 goto error_ret;
84 } 73 }
85 i++;
86 } 74 }
87error_ret:
88 mutex_unlock(&iio_map_list_lock); 75 mutex_unlock(&iio_map_list_lock);
89
90 return ret; 76 return ret;
91} 77}
92EXPORT_SYMBOL_GPL(iio_map_array_unregister); 78EXPORT_SYMBOL_GPL(iio_map_array_unregister);
@@ -167,16 +153,18 @@ void iio_channel_release(struct iio_channel *channel)
167} 153}
168EXPORT_SYMBOL_GPL(iio_channel_release); 154EXPORT_SYMBOL_GPL(iio_channel_release);
169 155
170struct iio_channel *iio_channel_get_all(const char *name) 156struct iio_channel *iio_channel_get_all(struct device *dev)
171{ 157{
158 const char *name;
172 struct iio_channel *chans; 159 struct iio_channel *chans;
173 struct iio_map_internal *c = NULL; 160 struct iio_map_internal *c = NULL;
174 int nummaps = 0; 161 int nummaps = 0;
175 int mapind = 0; 162 int mapind = 0;
176 int i, ret; 163 int i, ret;
177 164
178 if (name == NULL) 165 if (dev == NULL)
179 return ERR_PTR(-EINVAL); 166 return ERR_PTR(-EINVAL);
167 name = dev_name(dev);
180 168
181 mutex_lock(&iio_map_list_lock); 169 mutex_lock(&iio_map_list_lock);
182 /* first count the matching maps */ 170 /* first count the matching maps */
diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c
index 5bc5c860e9ca..a923c78d5cb4 100644
--- a/drivers/iio/kfifo_buf.c
+++ b/drivers/iio/kfifo_buf.c
@@ -22,7 +22,6 @@ static inline int __iio_allocate_kfifo(struct iio_kfifo *buf,
22 if ((length == 0) || (bytes_per_datum == 0)) 22 if ((length == 0) || (bytes_per_datum == 0))
23 return -EINVAL; 23 return -EINVAL;
24 24
25 __iio_update_buffer(&buf->buffer, bytes_per_datum, length);
26 return __kfifo_alloc((struct __kfifo *)&buf->kf, length, 25 return __kfifo_alloc((struct __kfifo *)&buf->kf, length,
27 bytes_per_datum, GFP_KERNEL); 26 bytes_per_datum, GFP_KERNEL);
28} 27}
diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig
index ff11d68225cf..cd29be54f643 100644
--- a/drivers/iio/magnetometer/Kconfig
+++ b/drivers/iio/magnetometer/Kconfig
@@ -14,4 +14,34 @@ config HID_SENSOR_MAGNETOMETER_3D
14 Say yes here to build support for the HID SENSOR 14 Say yes here to build support for the HID SENSOR
15 Magnetometer 3D. 15 Magnetometer 3D.
16 16
17config IIO_ST_MAGN_3AXIS
18 tristate "STMicroelectronics magnetometers 3-Axis Driver"
19 depends on (I2C || SPI_MASTER) && SYSFS
20 select IIO_ST_SENSORS_CORE
21 select IIO_ST_MAGN_I2C_3AXIS if (I2C)
22 select IIO_ST_MAGN_SPI_3AXIS if (SPI_MASTER)
23 select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
24 select IIO_ST_MAGN_BUFFER if (IIO_TRIGGERED_BUFFER)
25 help
26 Say yes here to build support for STMicroelectronics magnetometers:
27 LSM303DLHC, LSM303DLM, LIS3MDL.
28
29 This driver can also be built as a module. If so, will be created
30 these modules:
31 - st_magn (core functions for the driver [it is mandatory]);
32 - st_magn_i2c (necessary for the I2C devices [optional*]);
33 - st_magn_spi (necessary for the SPI devices [optional*]);
34
35 (*) one of these is necessary to do something.
36
37config IIO_ST_MAGN_I2C_3AXIS
38 tristate
39 depends on IIO_ST_MAGN_3AXIS
40 depends on IIO_ST_SENSORS_I2C
41
42config IIO_ST_MAGN_SPI_3AXIS
43 tristate
44 depends on IIO_ST_MAGN_3AXIS
45 depends on IIO_ST_SENSORS_SPI
46
17endmenu 47endmenu
diff --git a/drivers/iio/magnetometer/Makefile b/drivers/iio/magnetometer/Makefile
index 60dc4f2b1963..e78672876dc2 100644
--- a/drivers/iio/magnetometer/Makefile
+++ b/drivers/iio/magnetometer/Makefile
@@ -3,3 +3,10 @@
3# 3#
4 4
5obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o 5obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o
6
7obj-$(CONFIG_IIO_ST_MAGN_3AXIS) += st_magn.o
8st_magn-y := st_magn_core.o
9st_magn-$(CONFIG_IIO_BUFFER) += st_magn_buffer.o
10
11obj-$(CONFIG_IIO_ST_MAGN_I2C_3AXIS) += st_magn_i2c.o
12obj-$(CONFIG_IIO_ST_MAGN_SPI_3AXIS) += st_magn_spi.o
diff --git a/drivers/iio/magnetometer/st_magn.h b/drivers/iio/magnetometer/st_magn.h
new file mode 100644
index 000000000000..7e81d00ef0c3
--- /dev/null
+++ b/drivers/iio/magnetometer/st_magn.h
@@ -0,0 +1,45 @@
1/*
2 * STMicroelectronics magnetometers 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_MAGN_H
12#define ST_MAGN_H
13
14#include <linux/types.h>
15#include <linux/iio/common/st_sensors.h>
16
17#define LSM303DLHC_MAGN_DEV_NAME "lsm303dlhc_magn"
18#define LSM303DLM_MAGN_DEV_NAME "lsm303dlm_magn"
19#define LIS3MDL_MAGN_DEV_NAME "lis3mdl"
20
21int st_magn_common_probe(struct iio_dev *indio_dev);
22void st_magn_common_remove(struct iio_dev *indio_dev);
23
24#ifdef CONFIG_IIO_BUFFER
25int st_magn_allocate_ring(struct iio_dev *indio_dev);
26void st_magn_deallocate_ring(struct iio_dev *indio_dev);
27#else /* CONFIG_IIO_BUFFER */
28static inline int st_magn_probe_trigger(struct iio_dev *indio_dev, int irq)
29{
30 return 0;
31}
32static inline void st_magn_remove_trigger(struct iio_dev *indio_dev, int irq)
33{
34 return;
35}
36static inline int st_magn_allocate_ring(struct iio_dev *indio_dev)
37{
38 return 0;
39}
40static inline void st_magn_deallocate_ring(struct iio_dev *indio_dev)
41{
42}
43#endif /* CONFIG_IIO_BUFFER */
44
45#endif /* ST_MAGN_H */
diff --git a/drivers/iio/magnetometer/st_magn_buffer.c b/drivers/iio/magnetometer/st_magn_buffer.c
new file mode 100644
index 000000000000..708857bdb47d
--- /dev/null
+++ b/drivers/iio/magnetometer/st_magn_buffer.c
@@ -0,0 +1,98 @@
1/*
2 * STMicroelectronics magnetometers 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_magn.h"
25
26static int st_magn_buffer_preenable(struct iio_dev *indio_dev)
27{
28 int err;
29
30 err = st_sensors_set_enable(indio_dev, true);
31 if (err < 0)
32 goto st_magn_set_enable_error;
33
34 err = iio_sw_buffer_preenable(indio_dev);
35
36st_magn_set_enable_error:
37 return err;
38}
39
40static int st_magn_buffer_postenable(struct iio_dev *indio_dev)
41{
42 int err;
43 struct st_sensor_data *mdata = iio_priv(indio_dev);
44
45 mdata->buffer_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
46 if (mdata->buffer_data == NULL) {
47 err = -ENOMEM;
48 goto allocate_memory_error;
49 }
50
51 err = iio_triggered_buffer_postenable(indio_dev);
52 if (err < 0)
53 goto st_magn_buffer_postenable_error;
54
55 return err;
56
57st_magn_buffer_postenable_error:
58 kfree(mdata->buffer_data);
59allocate_memory_error:
60 return err;
61}
62
63static int st_magn_buffer_predisable(struct iio_dev *indio_dev)
64{
65 int err;
66 struct st_sensor_data *mdata = iio_priv(indio_dev);
67
68 err = iio_triggered_buffer_predisable(indio_dev);
69 if (err < 0)
70 goto st_magn_buffer_predisable_error;
71
72 err = st_sensors_set_enable(indio_dev, false);
73
74st_magn_buffer_predisable_error:
75 kfree(mdata->buffer_data);
76 return err;
77}
78
79static const struct iio_buffer_setup_ops st_magn_buffer_setup_ops = {
80 .preenable = &st_magn_buffer_preenable,
81 .postenable = &st_magn_buffer_postenable,
82 .predisable = &st_magn_buffer_predisable,
83};
84
85int st_magn_allocate_ring(struct iio_dev *indio_dev)
86{
87 return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
88 &st_sensors_trigger_handler, &st_magn_buffer_setup_ops);
89}
90
91void st_magn_deallocate_ring(struct iio_dev *indio_dev)
92{
93 iio_triggered_buffer_cleanup(indio_dev);
94}
95
96MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
97MODULE_DESCRIPTION("STMicroelectronics magnetometers buffer");
98MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c
new file mode 100644
index 000000000000..a69fbe19fc8e
--- /dev/null
+++ b/drivers/iio/magnetometer/st_magn_core.c
@@ -0,0 +1,401 @@
1/*
2 * STMicroelectronics magnetometers 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_magn.h"
29
30/* DEFAULT VALUE FOR SENSORS */
31#define ST_MAGN_DEFAULT_OUT_X_L_ADDR 0X04
32#define ST_MAGN_DEFAULT_OUT_Y_L_ADDR 0X08
33#define ST_MAGN_DEFAULT_OUT_Z_L_ADDR 0X06
34
35/* FULLSCALE */
36#define ST_MAGN_FS_AVL_1300MG 1300
37#define ST_MAGN_FS_AVL_1900MG 1900
38#define ST_MAGN_FS_AVL_2500MG 2500
39#define ST_MAGN_FS_AVL_4000MG 4000
40#define ST_MAGN_FS_AVL_4700MG 4700
41#define ST_MAGN_FS_AVL_5600MG 5600
42#define ST_MAGN_FS_AVL_8000MG 8000
43#define ST_MAGN_FS_AVL_8100MG 8100
44#define ST_MAGN_FS_AVL_10000MG 10000
45
46/* CUSTOM VALUES FOR SENSOR 1 */
47#define ST_MAGN_1_WAI_EXP 0x3c
48#define ST_MAGN_1_ODR_ADDR 0x00
49#define ST_MAGN_1_ODR_MASK 0x1c
50#define ST_MAGN_1_ODR_AVL_1HZ_VAL 0x00
51#define ST_MAGN_1_ODR_AVL_2HZ_VAL 0x01
52#define ST_MAGN_1_ODR_AVL_3HZ_VAL 0x02
53#define ST_MAGN_1_ODR_AVL_8HZ_VAL 0x03
54#define ST_MAGN_1_ODR_AVL_15HZ_VAL 0x04
55#define ST_MAGN_1_ODR_AVL_30HZ_VAL 0x05
56#define ST_MAGN_1_ODR_AVL_75HZ_VAL 0x06
57#define ST_MAGN_1_ODR_AVL_220HZ_VAL 0x07
58#define ST_MAGN_1_PW_ADDR 0x02
59#define ST_MAGN_1_PW_MASK 0x03
60#define ST_MAGN_1_PW_ON 0x00
61#define ST_MAGN_1_PW_OFF 0x03
62#define ST_MAGN_1_FS_ADDR 0x01
63#define ST_MAGN_1_FS_MASK 0xe0
64#define ST_MAGN_1_FS_AVL_1300_VAL 0x01
65#define ST_MAGN_1_FS_AVL_1900_VAL 0x02
66#define ST_MAGN_1_FS_AVL_2500_VAL 0x03
67#define ST_MAGN_1_FS_AVL_4000_VAL 0x04
68#define ST_MAGN_1_FS_AVL_4700_VAL 0x05
69#define ST_MAGN_1_FS_AVL_5600_VAL 0x06
70#define ST_MAGN_1_FS_AVL_8100_VAL 0x07
71#define ST_MAGN_1_FS_AVL_1300_GAIN_XY 1100
72#define ST_MAGN_1_FS_AVL_1900_GAIN_XY 855
73#define ST_MAGN_1_FS_AVL_2500_GAIN_XY 670
74#define ST_MAGN_1_FS_AVL_4000_GAIN_XY 450
75#define ST_MAGN_1_FS_AVL_4700_GAIN_XY 400
76#define ST_MAGN_1_FS_AVL_5600_GAIN_XY 330
77#define ST_MAGN_1_FS_AVL_8100_GAIN_XY 230
78#define ST_MAGN_1_FS_AVL_1300_GAIN_Z 980
79#define ST_MAGN_1_FS_AVL_1900_GAIN_Z 760
80#define ST_MAGN_1_FS_AVL_2500_GAIN_Z 600
81#define ST_MAGN_1_FS_AVL_4000_GAIN_Z 400
82#define ST_MAGN_1_FS_AVL_4700_GAIN_Z 355
83#define ST_MAGN_1_FS_AVL_5600_GAIN_Z 295
84#define ST_MAGN_1_FS_AVL_8100_GAIN_Z 205
85#define ST_MAGN_1_MULTIREAD_BIT false
86
87/* CUSTOM VALUES FOR SENSOR 2 */
88#define ST_MAGN_2_WAI_EXP 0x3d
89#define ST_MAGN_2_ODR_ADDR 0x20
90#define ST_MAGN_2_ODR_MASK 0x1c
91#define ST_MAGN_2_ODR_AVL_1HZ_VAL 0x00
92#define ST_MAGN_2_ODR_AVL_2HZ_VAL 0x01
93#define ST_MAGN_2_ODR_AVL_3HZ_VAL 0x02
94#define ST_MAGN_2_ODR_AVL_5HZ_VAL 0x03
95#define ST_MAGN_2_ODR_AVL_10HZ_VAL 0x04
96#define ST_MAGN_2_ODR_AVL_20HZ_VAL 0x05
97#define ST_MAGN_2_ODR_AVL_40HZ_VAL 0x06
98#define ST_MAGN_2_ODR_AVL_80HZ_VAL 0x07
99#define ST_MAGN_2_PW_ADDR 0x22
100#define ST_MAGN_2_PW_MASK 0x03
101#define ST_MAGN_2_PW_ON 0x00
102#define ST_MAGN_2_PW_OFF 0x03
103#define ST_MAGN_2_FS_ADDR 0x21
104#define ST_MAGN_2_FS_MASK 0x60
105#define ST_MAGN_2_FS_AVL_4000_VAL 0x00
106#define ST_MAGN_2_FS_AVL_8000_VAL 0x01
107#define ST_MAGN_2_FS_AVL_10000_VAL 0x02
108#define ST_MAGN_2_FS_AVL_4000_GAIN 430
109#define ST_MAGN_2_FS_AVL_8000_GAIN 230
110#define ST_MAGN_2_FS_AVL_10000_GAIN 230
111#define ST_MAGN_2_MULTIREAD_BIT false
112#define ST_MAGN_2_OUT_X_L_ADDR 0x28
113#define ST_MAGN_2_OUT_Y_L_ADDR 0x2a
114#define ST_MAGN_2_OUT_Z_L_ADDR 0x2c
115
116static const struct iio_chan_spec st_magn_16bit_channels[] = {
117 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE,
118 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_X_L_ADDR),
119 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE,
120 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_Y_L_ADDR),
121 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE,
122 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_Z_L_ADDR),
123 IIO_CHAN_SOFT_TIMESTAMP(3)
124};
125
126static const struct iio_chan_spec st_magn_2_16bit_channels[] = {
127 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE,
128 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_X_L_ADDR),
129 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE,
130 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_Y_L_ADDR),
131 ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE,
132 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_Z_L_ADDR),
133 IIO_CHAN_SOFT_TIMESTAMP(3)
134};
135
136static const struct st_sensors st_magn_sensors[] = {
137 {
138 .wai = ST_MAGN_1_WAI_EXP,
139 .sensors_supported = {
140 [0] = LSM303DLHC_MAGN_DEV_NAME,
141 [1] = LSM303DLM_MAGN_DEV_NAME,
142 },
143 .ch = (struct iio_chan_spec *)st_magn_16bit_channels,
144 .odr = {
145 .addr = ST_MAGN_1_ODR_ADDR,
146 .mask = ST_MAGN_1_ODR_MASK,
147 .odr_avl = {
148 { 1, ST_MAGN_1_ODR_AVL_1HZ_VAL, },
149 { 2, ST_MAGN_1_ODR_AVL_2HZ_VAL, },
150 { 3, ST_MAGN_1_ODR_AVL_3HZ_VAL, },
151 { 8, ST_MAGN_1_ODR_AVL_8HZ_VAL, },
152 { 15, ST_MAGN_1_ODR_AVL_15HZ_VAL, },
153 { 30, ST_MAGN_1_ODR_AVL_30HZ_VAL, },
154 { 75, ST_MAGN_1_ODR_AVL_75HZ_VAL, },
155 { 220, ST_MAGN_1_ODR_AVL_220HZ_VAL, },
156 },
157 },
158 .pw = {
159 .addr = ST_MAGN_1_PW_ADDR,
160 .mask = ST_MAGN_1_PW_MASK,
161 .value_on = ST_MAGN_1_PW_ON,
162 .value_off = ST_MAGN_1_PW_OFF,
163 },
164 .fs = {
165 .addr = ST_MAGN_1_FS_ADDR,
166 .mask = ST_MAGN_1_FS_MASK,
167 .fs_avl = {
168 [0] = {
169 .num = ST_MAGN_FS_AVL_1300MG,
170 .value = ST_MAGN_1_FS_AVL_1300_VAL,
171 .gain = ST_MAGN_1_FS_AVL_1300_GAIN_XY,
172 .gain2 = ST_MAGN_1_FS_AVL_1300_GAIN_Z,
173 },
174 [1] = {
175 .num = ST_MAGN_FS_AVL_1900MG,
176 .value = ST_MAGN_1_FS_AVL_1900_VAL,
177 .gain = ST_MAGN_1_FS_AVL_1900_GAIN_XY,
178 .gain2 = ST_MAGN_1_FS_AVL_1900_GAIN_Z,
179 },
180 [2] = {
181 .num = ST_MAGN_FS_AVL_2500MG,
182 .value = ST_MAGN_1_FS_AVL_2500_VAL,
183 .gain = ST_MAGN_1_FS_AVL_2500_GAIN_XY,
184 .gain2 = ST_MAGN_1_FS_AVL_2500_GAIN_Z,
185 },
186 [3] = {
187 .num = ST_MAGN_FS_AVL_4000MG,
188 .value = ST_MAGN_1_FS_AVL_4000_VAL,
189 .gain = ST_MAGN_1_FS_AVL_4000_GAIN_XY,
190 .gain2 = ST_MAGN_1_FS_AVL_4000_GAIN_Z,
191 },
192 [4] = {
193 .num = ST_MAGN_FS_AVL_4700MG,
194 .value = ST_MAGN_1_FS_AVL_4700_VAL,
195 .gain = ST_MAGN_1_FS_AVL_4700_GAIN_XY,
196 .gain2 = ST_MAGN_1_FS_AVL_4700_GAIN_Z,
197 },
198 [5] = {
199 .num = ST_MAGN_FS_AVL_5600MG,
200 .value = ST_MAGN_1_FS_AVL_5600_VAL,
201 .gain = ST_MAGN_1_FS_AVL_5600_GAIN_XY,
202 .gain2 = ST_MAGN_1_FS_AVL_5600_GAIN_Z,
203 },
204 [6] = {
205 .num = ST_MAGN_FS_AVL_8100MG,
206 .value = ST_MAGN_1_FS_AVL_8100_VAL,
207 .gain = ST_MAGN_1_FS_AVL_8100_GAIN_XY,
208 .gain2 = ST_MAGN_1_FS_AVL_8100_GAIN_Z,
209 },
210 },
211 },
212 .multi_read_bit = ST_MAGN_1_MULTIREAD_BIT,
213 .bootime = 2,
214 },
215 {
216 .wai = ST_MAGN_2_WAI_EXP,
217 .sensors_supported = {
218 [0] = LIS3MDL_MAGN_DEV_NAME,
219 },
220 .ch = (struct iio_chan_spec *)st_magn_2_16bit_channels,
221 .odr = {
222 .addr = ST_MAGN_2_ODR_ADDR,
223 .mask = ST_MAGN_2_ODR_MASK,
224 .odr_avl = {
225 { 1, ST_MAGN_2_ODR_AVL_1HZ_VAL, },
226 { 2, ST_MAGN_2_ODR_AVL_2HZ_VAL, },
227 { 3, ST_MAGN_2_ODR_AVL_3HZ_VAL, },
228 { 5, ST_MAGN_2_ODR_AVL_5HZ_VAL, },
229 { 10, ST_MAGN_2_ODR_AVL_10HZ_VAL, },
230 { 20, ST_MAGN_2_ODR_AVL_20HZ_VAL, },
231 { 40, ST_MAGN_2_ODR_AVL_40HZ_VAL, },
232 { 80, ST_MAGN_2_ODR_AVL_80HZ_VAL, },
233 },
234 },
235 .pw = {
236 .addr = ST_MAGN_2_PW_ADDR,
237 .mask = ST_MAGN_2_PW_MASK,
238 .value_on = ST_MAGN_2_PW_ON,
239 .value_off = ST_MAGN_2_PW_OFF,
240 },
241 .fs = {
242 .addr = ST_MAGN_2_FS_ADDR,
243 .mask = ST_MAGN_2_FS_MASK,
244 .fs_avl = {
245 [0] = {
246 .num = ST_MAGN_FS_AVL_4000MG,
247 .value = ST_MAGN_2_FS_AVL_4000_VAL,
248 .gain = ST_MAGN_2_FS_AVL_4000_GAIN,
249 },
250 [1] = {
251 .num = ST_MAGN_FS_AVL_8000MG,
252 .value = ST_MAGN_2_FS_AVL_8000_VAL,
253 .gain = ST_MAGN_2_FS_AVL_8000_GAIN,
254 },
255 [2] = {
256 .num = ST_MAGN_FS_AVL_10000MG,
257 .value = ST_MAGN_2_FS_AVL_10000_VAL,
258 .gain = ST_MAGN_2_FS_AVL_10000_GAIN,
259 },
260 },
261 },
262 .multi_read_bit = ST_MAGN_2_MULTIREAD_BIT,
263 .bootime = 2,
264 },
265};
266
267static int st_magn_read_raw(struct iio_dev *indio_dev,
268 struct iio_chan_spec const *ch, int *val,
269 int *val2, long mask)
270{
271 int err;
272 struct st_sensor_data *mdata = iio_priv(indio_dev);
273
274 switch (mask) {
275 case IIO_CHAN_INFO_RAW:
276 err = st_sensors_read_info_raw(indio_dev, ch, val);
277 if (err < 0)
278 goto read_error;
279
280 return IIO_VAL_INT;
281 case IIO_CHAN_INFO_SCALE:
282 *val = 0;
283 if ((ch->scan_index == ST_SENSORS_SCAN_Z) &&
284 (mdata->current_fullscale->gain2 != 0))
285 *val2 = mdata->current_fullscale->gain2;
286 else
287 *val2 = mdata->current_fullscale->gain;
288 return IIO_VAL_INT_PLUS_MICRO;
289 default:
290 return -EINVAL;
291 }
292
293read_error:
294 return err;
295}
296
297static int st_magn_write_raw(struct iio_dev *indio_dev,
298 struct iio_chan_spec const *chan, int val, int val2, long mask)
299{
300 int err;
301
302 switch (mask) {
303 case IIO_CHAN_INFO_SCALE:
304 err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
305 break;
306 default:
307 err = -EINVAL;
308 }
309
310 return err;
311}
312
313static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
314static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
315static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_magn_scale_available);
316
317static struct attribute *st_magn_attributes[] = {
318 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
319 &iio_dev_attr_in_magn_scale_available.dev_attr.attr,
320 &iio_dev_attr_sampling_frequency.dev_attr.attr,
321 NULL,
322};
323
324static const struct attribute_group st_magn_attribute_group = {
325 .attrs = st_magn_attributes,
326};
327
328static const struct iio_info magn_info = {
329 .driver_module = THIS_MODULE,
330 .attrs = &st_magn_attribute_group,
331 .read_raw = &st_magn_read_raw,
332 .write_raw = &st_magn_write_raw,
333};
334
335int st_magn_common_probe(struct iio_dev *indio_dev)
336{
337 int err;
338 struct st_sensor_data *mdata = iio_priv(indio_dev);
339
340 indio_dev->modes = INDIO_DIRECT_MODE;
341 indio_dev->info = &magn_info;
342
343 err = st_sensors_check_device_support(indio_dev,
344 ARRAY_SIZE(st_magn_sensors), st_magn_sensors);
345 if (err < 0)
346 goto st_magn_common_probe_error;
347
348 mdata->multiread_bit = mdata->sensor->multi_read_bit;
349 indio_dev->channels = mdata->sensor->ch;
350 indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
351
352 mdata->current_fullscale = (struct st_sensor_fullscale_avl *)
353 &mdata->sensor->fs.fs_avl[0];
354 mdata->odr = mdata->sensor->odr.odr_avl[0].hz;
355
356 err = st_sensors_init_sensor(indio_dev);
357 if (err < 0)
358 goto st_magn_common_probe_error;
359
360 if (mdata->get_irq_data_ready(indio_dev) > 0) {
361 err = st_magn_allocate_ring(indio_dev);
362 if (err < 0)
363 goto st_magn_common_probe_error;
364 err = st_sensors_allocate_trigger(indio_dev, NULL);
365 if (err < 0)
366 goto st_magn_probe_trigger_error;
367 }
368
369 err = iio_device_register(indio_dev);
370 if (err)
371 goto st_magn_device_register_error;
372
373 return err;
374
375st_magn_device_register_error:
376 if (mdata->get_irq_data_ready(indio_dev) > 0)
377 st_sensors_deallocate_trigger(indio_dev);
378st_magn_probe_trigger_error:
379 if (mdata->get_irq_data_ready(indio_dev) > 0)
380 st_magn_deallocate_ring(indio_dev);
381st_magn_common_probe_error:
382 return err;
383}
384EXPORT_SYMBOL(st_magn_common_probe);
385
386void st_magn_common_remove(struct iio_dev *indio_dev)
387{
388 struct st_sensor_data *mdata = iio_priv(indio_dev);
389
390 iio_device_unregister(indio_dev);
391 if (mdata->get_irq_data_ready(indio_dev) > 0) {
392 st_sensors_deallocate_trigger(indio_dev);
393 st_magn_deallocate_ring(indio_dev);
394 }
395 iio_device_free(indio_dev);
396}
397EXPORT_SYMBOL(st_magn_common_remove);
398
399MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
400MODULE_DESCRIPTION("STMicroelectronics magnetometers driver");
401MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c
new file mode 100644
index 000000000000..710b256a5a0e
--- /dev/null
+++ b/drivers/iio/magnetometer/st_magn_i2c.c
@@ -0,0 +1,81 @@
1/*
2 * STMicroelectronics magnetometers 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_magn.h"
21
22static int st_magn_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 *mdata;
27 int err;
28
29 indio_dev = iio_device_alloc(sizeof(*mdata));
30 if (indio_dev == NULL) {
31 err = -ENOMEM;
32 goto iio_device_alloc_error;
33 }
34
35 mdata = iio_priv(indio_dev);
36 mdata->dev = &client->dev;
37
38 st_sensors_i2c_configure(indio_dev, client, mdata);
39
40 err = st_magn_common_probe(indio_dev);
41 if (err < 0)
42 goto st_magn_common_probe_error;
43
44 return 0;
45
46st_magn_common_probe_error:
47 iio_device_free(indio_dev);
48iio_device_alloc_error:
49 return err;
50}
51
52static int st_magn_i2c_remove(struct i2c_client *client)
53{
54 struct iio_dev *indio_dev = i2c_get_clientdata(client);
55 st_magn_common_remove(indio_dev);
56
57 return 0;
58}
59
60static const struct i2c_device_id st_magn_id_table[] = {
61 { LSM303DLHC_MAGN_DEV_NAME },
62 { LSM303DLM_MAGN_DEV_NAME },
63 { LIS3MDL_MAGN_DEV_NAME },
64 {},
65};
66MODULE_DEVICE_TABLE(i2c, st_magn_id_table);
67
68static struct i2c_driver st_magn_driver = {
69 .driver = {
70 .owner = THIS_MODULE,
71 .name = "st-magn-i2c",
72 },
73 .probe = st_magn_i2c_probe,
74 .remove = st_magn_i2c_remove,
75 .id_table = st_magn_id_table,
76};
77module_i2c_driver(st_magn_driver);
78
79MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
80MODULE_DESCRIPTION("STMicroelectronics magnetometers i2c driver");
81MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c
new file mode 100644
index 000000000000..94547e7d6580
--- /dev/null
+++ b/drivers/iio/magnetometer/st_magn_spi.c
@@ -0,0 +1,80 @@
1/*
2 * STMicroelectronics magnetometers 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_magn.h"
21
22static int st_magn_spi_probe(struct spi_device *spi)
23{
24 struct iio_dev *indio_dev;
25 struct st_sensor_data *mdata;
26 int err;
27
28 indio_dev = iio_device_alloc(sizeof(*mdata));
29 if (indio_dev == NULL) {
30 err = -ENOMEM;
31 goto iio_device_alloc_error;
32 }
33
34 mdata = iio_priv(indio_dev);
35 mdata->dev = &spi->dev;
36
37 st_sensors_spi_configure(indio_dev, spi, mdata);
38
39 err = st_magn_common_probe(indio_dev);
40 if (err < 0)
41 goto st_magn_common_probe_error;
42
43 return 0;
44
45st_magn_common_probe_error:
46 iio_device_free(indio_dev);
47iio_device_alloc_error:
48 return err;
49}
50
51static int st_magn_spi_remove(struct spi_device *spi)
52{
53 struct iio_dev *indio_dev = spi_get_drvdata(spi);
54 st_magn_common_remove(indio_dev);
55
56 return 0;
57}
58
59static const struct spi_device_id st_magn_id_table[] = {
60 { LSM303DLHC_MAGN_DEV_NAME },
61 { LSM303DLM_MAGN_DEV_NAME },
62 { LIS3MDL_MAGN_DEV_NAME },
63 {},
64};
65MODULE_DEVICE_TABLE(spi, st_magn_id_table);
66
67static struct spi_driver st_magn_driver = {
68 .driver = {
69 .owner = THIS_MODULE,
70 .name = "st-magn-spi",
71 },
72 .probe = st_magn_spi_probe,
73 .remove = st_magn_spi_remove,
74 .id_table = st_magn_id_table,
75};
76module_spi_driver(st_magn_driver);
77
78MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
79MODULE_DESCRIPTION("STMicroelectronics magnetometers spi driver");
80MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig
index 658b3673d056..836066287192 100644
--- a/drivers/staging/iio/gyro/Kconfig
+++ b/drivers/staging/iio/gyro/Kconfig
@@ -29,14 +29,4 @@ config ADIS16260
29 This driver can also be built as a module. If so, the module 29 This driver can also be built as a module. If so, the module
30 will be called adis16260. 30 will be called adis16260.
31 31
32config ADXRS450
33 tristate "Analog Devices ADXRS450/3 Digital Output Gyroscope SPI driver"
34 depends on SPI
35 help
36 Say yes here to build support for Analog Devices ADXRS450 and ADXRS453
37 programmable digital output gyroscope.
38
39 This driver can also be built as a module. If so, the module
40 will be called adxrs450.
41
42endmenu 32endmenu
diff --git a/drivers/staging/iio/gyro/Makefile b/drivers/staging/iio/gyro/Makefile
index ef3316171299..98e650061a3a 100644
--- a/drivers/staging/iio/gyro/Makefile
+++ b/drivers/staging/iio/gyro/Makefile
@@ -10,6 +10,3 @@ obj-$(CONFIG_ADIS16130) += adis16130.o
10 10
11adis16260-y := adis16260_core.o 11adis16260-y := adis16260_core.o
12obj-$(CONFIG_ADIS16260) += adis16260.o 12obj-$(CONFIG_ADIS16260) += adis16260.o
13
14adxrs450-y := adxrs450_core.o
15obj-$(CONFIG_ADXRS450) += adxrs450.o
diff --git a/drivers/staging/iio/gyro/adxrs450.h b/drivers/staging/iio/gyro/adxrs450.h
deleted file mode 100644
index f8cf21f02943..000000000000
--- a/drivers/staging/iio/gyro/adxrs450.h
+++ /dev/null
@@ -1,62 +0,0 @@
1#ifndef SPI_ADXRS450_H_
2#define SPI_ADXRS450_H_
3
4#define ADXRS450_STARTUP_DELAY 50 /* ms */
5
6/* The MSB for the spi commands */
7#define ADXRS450_SENSOR_DATA 0x20
8#define ADXRS450_WRITE_DATA 0x40
9#define ADXRS450_READ_DATA 0x80
10
11#define ADXRS450_RATE1 0x00 /* Rate Registers */
12#define ADXRS450_TEMP1 0x02 /* Temperature Registers */
13#define ADXRS450_LOCST1 0x04 /* Low CST Memory Registers */
14#define ADXRS450_HICST1 0x06 /* High CST Memory Registers */
15#define ADXRS450_QUAD1 0x08 /* Quad Memory Registers */
16#define ADXRS450_FAULT1 0x0A /* Fault Registers */
17#define ADXRS450_PID1 0x0C /* Part ID Register 1 */
18#define ADXRS450_SNH 0x0E /* Serial Number Registers, 4 bytes */
19#define ADXRS450_SNL 0x10
20#define ADXRS450_DNC1 0x12 /* Dynamic Null Correction Registers */
21/* Check bits */
22#define ADXRS450_P 0x01
23#define ADXRS450_CHK 0x02
24#define ADXRS450_CST 0x04
25#define ADXRS450_PWR 0x08
26#define ADXRS450_POR 0x10
27#define ADXRS450_NVM 0x20
28#define ADXRS450_Q 0x40
29#define ADXRS450_PLL 0x80
30#define ADXRS450_UV 0x100
31#define ADXRS450_OV 0x200
32#define ADXRS450_AMP 0x400
33#define ADXRS450_FAIL 0x800
34
35#define ADXRS450_WRERR_MASK (0x7 << 29)
36
37#define ADXRS450_MAX_RX 4
38#define ADXRS450_MAX_TX 4
39
40#define ADXRS450_GET_ST(a) ((a >> 26) & 0x3)
41
42enum {
43 ID_ADXRS450,
44 ID_ADXRS453,
45};
46
47/**
48 * struct adxrs450_state - device instance specific data
49 * @us: actual spi_device
50 * @buf_lock: mutex to protect tx and rx
51 * @tx: transmit buffer
52 * @rx: receive buffer
53 **/
54struct adxrs450_state {
55 struct spi_device *us;
56 struct mutex buf_lock;
57 u8 tx[ADXRS450_MAX_RX] ____cacheline_aligned;
58 u8 rx[ADXRS450_MAX_TX];
59
60};
61
62#endif /* SPI_ADXRS450_H_ */
diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c
index 97ad645bb15a..93af756ba48c 100644
--- a/drivers/staging/iio/iio_hwmon.c
+++ b/drivers/staging/iio/iio_hwmon.c
@@ -55,63 +55,58 @@ static ssize_t iio_hwmon_read_val(struct device *dev,
55 return sprintf(buf, "%d\n", result); 55 return sprintf(buf, "%d\n", result);
56} 56}
57 57
58static void iio_hwmon_free_attrs(struct iio_hwmon_state *st) 58static ssize_t show_name(struct device *dev, struct device_attribute *attr,
59 char *buf)
59{ 60{
60 int i; 61 return sprintf(buf, "iio_hwmon\n");
61 struct sensor_device_attribute *a;
62 for (i = 0; i < st->num_channels; i++)
63 if (st->attrs[i]) {
64 a = to_sensor_dev_attr(
65 container_of(st->attrs[i],
66 struct device_attribute,
67 attr));
68 kfree(a);
69 }
70} 62}
71 63
64static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
65
72static int iio_hwmon_probe(struct platform_device *pdev) 66static int iio_hwmon_probe(struct platform_device *pdev)
73{ 67{
68 struct device *dev = &pdev->dev;
74 struct iio_hwmon_state *st; 69 struct iio_hwmon_state *st;
75 struct sensor_device_attribute *a; 70 struct sensor_device_attribute *a;
76 int ret, i; 71 int ret, i;
77 int in_i = 1, temp_i = 1, curr_i = 1; 72 int in_i = 1, temp_i = 1, curr_i = 1;
78 enum iio_chan_type type; 73 enum iio_chan_type type;
74 struct iio_channel *channels;
79 75
80 st = kzalloc(sizeof(*st), GFP_KERNEL); 76 channels = iio_channel_get_all(dev);
81 if (st == NULL) { 77 if (IS_ERR(channels))
82 ret = -ENOMEM; 78 return PTR_ERR(channels);
83 goto error_ret;
84 }
85 79
86 st->channels = iio_channel_get_all(dev_name(&pdev->dev)); 80 st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
87 if (IS_ERR(st->channels)) { 81 if (st == NULL)
88 ret = PTR_ERR(st->channels); 82 return -ENOMEM;
89 goto error_free_state; 83
90 } 84 st->channels = channels;
91 85
92 /* count how many attributes we have */ 86 /* count how many attributes we have */
93 while (st->channels[st->num_channels].indio_dev) 87 while (st->channels[st->num_channels].indio_dev)
94 st->num_channels++; 88 st->num_channels++;
95 89
96 st->attrs = kzalloc(sizeof(*st->attrs) * (st->num_channels + 1), 90 st->attrs = devm_kzalloc(dev,
97 GFP_KERNEL); 91 sizeof(*st->attrs) * (st->num_channels + 2),
92 GFP_KERNEL);
98 if (st->attrs == NULL) { 93 if (st->attrs == NULL) {
99 ret = -ENOMEM; 94 ret = -ENOMEM;
100 goto error_release_channels; 95 goto error_release_channels;
101 } 96 }
97
102 for (i = 0; i < st->num_channels; i++) { 98 for (i = 0; i < st->num_channels; i++) {
103 a = kzalloc(sizeof(*a), GFP_KERNEL); 99 a = devm_kzalloc(dev, sizeof(*a), GFP_KERNEL);
104 if (a == NULL) { 100 if (a == NULL) {
105 ret = -ENOMEM; 101 ret = -ENOMEM;
106 goto error_free_attrs; 102 goto error_release_channels;
107 } 103 }
108 104
109 sysfs_attr_init(&a->dev_attr.attr); 105 sysfs_attr_init(&a->dev_attr.attr);
110 ret = iio_get_channel_type(&st->channels[i], &type); 106 ret = iio_get_channel_type(&st->channels[i], &type);
111 if (ret < 0) { 107 if (ret < 0)
112 kfree(a); 108 goto error_release_channels;
113 goto error_free_attrs; 109
114 }
115 switch (type) { 110 switch (type) {
116 case IIO_VOLTAGE: 111 case IIO_VOLTAGE:
117 a->dev_attr.attr.name = kasprintf(GFP_KERNEL, 112 a->dev_attr.attr.name = kasprintf(GFP_KERNEL,
@@ -130,27 +125,25 @@ static int iio_hwmon_probe(struct platform_device *pdev)
130 break; 125 break;
131 default: 126 default:
132 ret = -EINVAL; 127 ret = -EINVAL;
133 kfree(a); 128 goto error_release_channels;
134 goto error_free_attrs;
135 } 129 }
136 if (a->dev_attr.attr.name == NULL) { 130 if (a->dev_attr.attr.name == NULL) {
137 kfree(a);
138 ret = -ENOMEM; 131 ret = -ENOMEM;
139 goto error_free_attrs; 132 goto error_release_channels;
140 } 133 }
141 a->dev_attr.show = iio_hwmon_read_val; 134 a->dev_attr.show = iio_hwmon_read_val;
142 a->dev_attr.attr.mode = S_IRUGO; 135 a->dev_attr.attr.mode = S_IRUGO;
143 a->index = i; 136 a->index = i;
144 st->attrs[i] = &a->dev_attr.attr; 137 st->attrs[i] = &a->dev_attr.attr;
145 } 138 }
146 139 st->attrs[st->num_channels] = &dev_attr_name.attr;
147 st->attr_group.attrs = st->attrs; 140 st->attr_group.attrs = st->attrs;
148 platform_set_drvdata(pdev, st); 141 platform_set_drvdata(pdev, st);
149 ret = sysfs_create_group(&pdev->dev.kobj, &st->attr_group); 142 ret = sysfs_create_group(&dev->kobj, &st->attr_group);
150 if (ret < 0) 143 if (ret < 0)
151 goto error_free_attrs; 144 goto error_release_channels;
152 145
153 st->hwmon_dev = hwmon_device_register(&pdev->dev); 146 st->hwmon_dev = hwmon_device_register(dev);
154 if (IS_ERR(st->hwmon_dev)) { 147 if (IS_ERR(st->hwmon_dev)) {
155 ret = PTR_ERR(st->hwmon_dev); 148 ret = PTR_ERR(st->hwmon_dev);
156 goto error_remove_group; 149 goto error_remove_group;
@@ -158,15 +151,9 @@ static int iio_hwmon_probe(struct platform_device *pdev)
158 return 0; 151 return 0;
159 152
160error_remove_group: 153error_remove_group:
161 sysfs_remove_group(&pdev->dev.kobj, &st->attr_group); 154 sysfs_remove_group(&dev->kobj, &st->attr_group);
162error_free_attrs:
163 iio_hwmon_free_attrs(st);
164 kfree(st->attrs);
165error_release_channels: 155error_release_channels:
166 iio_channel_release_all(st->channels); 156 iio_channel_release_all(st->channels);
167error_free_state:
168 kfree(st);
169error_ret:
170 return ret; 157 return ret;
171} 158}
172 159
@@ -176,17 +163,21 @@ static int iio_hwmon_remove(struct platform_device *pdev)
176 163
177 hwmon_device_unregister(st->hwmon_dev); 164 hwmon_device_unregister(st->hwmon_dev);
178 sysfs_remove_group(&pdev->dev.kobj, &st->attr_group); 165 sysfs_remove_group(&pdev->dev.kobj, &st->attr_group);
179 iio_hwmon_free_attrs(st);
180 kfree(st->attrs);
181 iio_channel_release_all(st->channels); 166 iio_channel_release_all(st->channels);
182 167
183 return 0; 168 return 0;
184} 169}
185 170
171static struct of_device_id iio_hwmon_of_match[] = {
172 { .compatible = "iio-hwmon", },
173 { }
174};
175
186static struct platform_driver __refdata iio_hwmon_driver = { 176static struct platform_driver __refdata iio_hwmon_driver = {
187 .driver = { 177 .driver = {
188 .name = "iio_hwmon", 178 .name = "iio_hwmon",
189 .owner = THIS_MODULE, 179 .owner = THIS_MODULE,
180 .of_match_table = iio_hwmon_of_match,
190 }, 181 },
191 .probe = iio_hwmon_probe, 182 .probe = iio_hwmon_probe,
192 .remove = iio_hwmon_remove, 183 .remove = iio_hwmon_remove,
diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h
index f3eea18fdf46..2bac0eb8948d 100644
--- a/include/linux/iio/buffer.h
+++ b/include/linux/iio/buffer.h
@@ -103,19 +103,6 @@ int iio_update_buffers(struct iio_dev *indio_dev,
103 **/ 103 **/
104void iio_buffer_init(struct iio_buffer *buffer); 104void iio_buffer_init(struct iio_buffer *buffer);
105 105
106/**
107 * __iio_update_buffer() - update common elements of buffers
108 * @buffer: buffer that is the event source
109 * @bytes_per_datum: size of individual datum including timestamp
110 * @length: number of datums in buffer
111 **/
112static inline void __iio_update_buffer(struct iio_buffer *buffer,
113 int bytes_per_datum, int length)
114{
115 buffer->bytes_per_datum = bytes_per_datum;
116 buffer->length = length;
117}
118
119int iio_scan_mask_query(struct iio_dev *indio_dev, 106int iio_scan_mask_query(struct iio_dev *indio_dev,
120 struct iio_buffer *buffer, int bit); 107 struct iio_buffer *buffer, int bit);
121 108
diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
new file mode 100644
index 000000000000..c40fdf537f69
--- /dev/null
+++ b/include/linux/iio/common/st_sensors.h
@@ -0,0 +1,270 @@
1/*
2 * STMicroelectronics sensors library 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#ifndef ST_SENSORS_H
12#define ST_SENSORS_H
13
14#include <linux/i2c.h>
15#include <linux/spi/spi.h>
16#include <linux/irqreturn.h>
17#include <linux/iio/trigger.h>
18
19#define ST_SENSORS_TX_MAX_LENGTH 2
20#define ST_SENSORS_RX_MAX_LENGTH 6
21
22#define ST_SENSORS_ODR_LIST_MAX 10
23#define ST_SENSORS_FULLSCALE_AVL_MAX 10
24
25#define ST_SENSORS_NUMBER_ALL_CHANNELS 4
26#define ST_SENSORS_NUMBER_DATA_CHANNELS 3
27#define ST_SENSORS_ENABLE_ALL_AXIS 0x07
28#define ST_SENSORS_BYTE_FOR_CHANNEL 2
29#define ST_SENSORS_SCAN_X 0
30#define ST_SENSORS_SCAN_Y 1
31#define ST_SENSORS_SCAN_Z 2
32#define ST_SENSORS_DEFAULT_12_REALBITS 12
33#define ST_SENSORS_DEFAULT_16_REALBITS 16
34#define ST_SENSORS_DEFAULT_POWER_ON_VALUE 0x01
35#define ST_SENSORS_DEFAULT_POWER_OFF_VALUE 0x00
36#define ST_SENSORS_DEFAULT_WAI_ADDRESS 0x0f
37#define ST_SENSORS_DEFAULT_AXIS_ADDR 0x20
38#define ST_SENSORS_DEFAULT_AXIS_MASK 0x07
39#define ST_SENSORS_DEFAULT_AXIS_N_BIT 3
40
41#define ST_SENSORS_MAX_NAME 17
42#define ST_SENSORS_MAX_4WAI 7
43
44#define ST_SENSORS_LSM_CHANNELS(device_type, index, mod, endian, bits, addr) \
45{ \
46 .type = device_type, \
47 .modified = 1, \
48 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
49 IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
50 .scan_index = index, \
51 .channel2 = mod, \
52 .address = addr, \
53 .scan_type = { \
54 .sign = 's', \
55 .realbits = bits, \
56 .shift = 16 - bits, \
57 .storagebits = 16, \
58 .endianness = endian, \
59 }, \
60}
61
62#define ST_SENSOR_DEV_ATTR_SAMP_FREQ() \
63 IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, \
64 st_sensors_sysfs_get_sampling_frequency, \
65 st_sensors_sysfs_set_sampling_frequency)
66
67#define ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL() \
68 IIO_DEV_ATTR_SAMP_FREQ_AVAIL( \
69 st_sensors_sysfs_sampling_frequency_avail)
70
71#define ST_SENSORS_DEV_ATTR_SCALE_AVAIL(name) \
72 IIO_DEVICE_ATTR(name, S_IRUGO, \
73 st_sensors_sysfs_scale_avail, NULL , 0);
74
75struct st_sensor_odr_avl {
76 unsigned int hz;
77 u8 value;
78};
79
80struct st_sensor_odr {
81 u8 addr;
82 u8 mask;
83 struct st_sensor_odr_avl odr_avl[ST_SENSORS_ODR_LIST_MAX];
84};
85
86struct st_sensor_power {
87 u8 addr;
88 u8 mask;
89 u8 value_off;
90 u8 value_on;
91};
92
93struct st_sensor_axis {
94 u8 addr;
95 u8 mask;
96};
97
98struct st_sensor_fullscale_avl {
99 unsigned int num;
100 u8 value;
101 unsigned int gain;
102 unsigned int gain2;
103};
104
105struct st_sensor_fullscale {
106 u8 addr;
107 u8 mask;
108 struct st_sensor_fullscale_avl fs_avl[ST_SENSORS_FULLSCALE_AVL_MAX];
109};
110
111/**
112 * struct st_sensor_bdu - ST sensor device block data update
113 * @addr: address of the register.
114 * @mask: mask to write the block data update flag.
115 */
116struct st_sensor_bdu {
117 u8 addr;
118 u8 mask;
119};
120
121/**
122 * struct st_sensor_data_ready_irq - ST sensor device data-ready interrupt
123 * @addr: address of the register.
124 * @mask: mask to write the on/off value.
125 * struct ig1 - represents the Interrupt Generator 1 of sensors.
126 * @en_addr: address of the enable ig1 register.
127 * @en_mask: mask to write the on/off value for enable.
128 */
129struct st_sensor_data_ready_irq {
130 u8 addr;
131 u8 mask;
132 struct {
133 u8 en_addr;
134 u8 en_mask;
135 } ig1;
136};
137
138/**
139 * struct st_sensor_transfer_buffer - ST sensor device I/O buffer
140 * @buf_lock: Mutex to protect rx and tx buffers.
141 * @tx_buf: Buffer used by SPI transfer function to send data to the sensors.
142 * This buffer is used to avoid DMA not-aligned issue.
143 * @rx_buf: Buffer used by SPI transfer to receive data from sensors.
144 * This buffer is used to avoid DMA not-aligned issue.
145 */
146struct st_sensor_transfer_buffer {
147 struct mutex buf_lock;
148 u8 rx_buf[ST_SENSORS_RX_MAX_LENGTH];
149 u8 tx_buf[ST_SENSORS_TX_MAX_LENGTH] ____cacheline_aligned;
150};
151
152/**
153 * struct st_sensor_transfer_function - ST sensor device I/O function
154 * @read_byte: Function used to read one byte.
155 * @write_byte: Function used to write one byte.
156 * @read_multiple_byte: Function used to read multiple byte.
157 */
158struct st_sensor_transfer_function {
159 int (*read_byte) (struct st_sensor_transfer_buffer *tb,
160 struct device *dev, u8 reg_addr, u8 *res_byte);
161 int (*write_byte) (struct st_sensor_transfer_buffer *tb,
162 struct device *dev, u8 reg_addr, u8 data);
163 int (*read_multiple_byte) (struct st_sensor_transfer_buffer *tb,
164 struct device *dev, u8 reg_addr, int len, u8 *data,
165 bool multiread_bit);
166};
167
168/**
169 * struct st_sensors - ST sensors list
170 * @wai: Contents of WhoAmI register.
171 * @sensors_supported: List of supported sensors by struct itself.
172 * @ch: IIO channels for the sensor.
173 * @odr: Output data rate register and ODR list available.
174 * @pw: Power register of the sensor.
175 * @enable_axis: Enable one or more axis of the sensor.
176 * @fs: Full scale register and full scale list available.
177 * @bdu: Block data update register.
178 * @drdy_irq: Data ready register of the sensor.
179 * @multi_read_bit: Use or not particular bit for [I2C/SPI] multi-read.
180 * @bootime: samples to discard when sensor passing from power-down to power-up.
181 */
182struct st_sensors {
183 u8 wai;
184 char sensors_supported[ST_SENSORS_MAX_4WAI][ST_SENSORS_MAX_NAME];
185 struct iio_chan_spec *ch;
186 struct st_sensor_odr odr;
187 struct st_sensor_power pw;
188 struct st_sensor_axis enable_axis;
189 struct st_sensor_fullscale fs;
190 struct st_sensor_bdu bdu;
191 struct st_sensor_data_ready_irq drdy_irq;
192 bool multi_read_bit;
193 unsigned int bootime;
194};
195
196/**
197 * struct st_sensor_data - ST sensor device status
198 * @dev: Pointer to instance of struct device (I2C or SPI).
199 * @trig: The trigger in use by the core driver.
200 * @sensor: Pointer to the current sensor struct in use.
201 * @current_fullscale: Maximum range of measure by the sensor.
202 * @enabled: Status of the sensor (false->off, true->on).
203 * @multiread_bit: Use or not particular bit for [I2C/SPI] multiread.
204 * @buffer_data: Data used by buffer part.
205 * @odr: Output data rate of the sensor [Hz].
206 * @get_irq_data_ready: Function to get the IRQ used for data ready signal.
207 * @tf: Transfer function structure used by I/O operations.
208 * @tb: Transfer buffers and mutex used by I/O operations.
209 */
210struct st_sensor_data {
211 struct device *dev;
212 struct iio_trigger *trig;
213 struct st_sensors *sensor;
214 struct st_sensor_fullscale_avl *current_fullscale;
215
216 bool enabled;
217 bool multiread_bit;
218
219 char *buffer_data;
220
221 unsigned int odr;
222
223 unsigned int (*get_irq_data_ready) (struct iio_dev *indio_dev);
224
225 const struct st_sensor_transfer_function *tf;
226 struct st_sensor_transfer_buffer tb;
227};
228
229#ifdef CONFIG_IIO_BUFFER
230int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
231 const struct iio_trigger_ops *trigger_ops);
232
233void st_sensors_deallocate_trigger(struct iio_dev *indio_dev);
234
235irqreturn_t st_sensors_trigger_handler(int irq, void *p);
236
237int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf);
238#endif
239
240int st_sensors_init_sensor(struct iio_dev *indio_dev);
241
242int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable);
243
244int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable);
245
246int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr);
247
248int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable);
249
250int st_sensors_set_fullscale_by_gain(struct iio_dev *indio_dev, int scale);
251
252int st_sensors_read_info_raw(struct iio_dev *indio_dev,
253 struct iio_chan_spec const *ch, int *val);
254
255int st_sensors_check_device_support(struct iio_dev *indio_dev,
256 int num_sensors_list, const struct st_sensors *sensors);
257
258ssize_t st_sensors_sysfs_get_sampling_frequency(struct device *dev,
259 struct device_attribute *attr, char *buf);
260
261ssize_t st_sensors_sysfs_set_sampling_frequency(struct device *dev,
262 struct device_attribute *attr, const char *buf, size_t size);
263
264ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
265 struct device_attribute *attr, char *buf);
266
267ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
268 struct device_attribute *attr, char *buf);
269
270#endif /* ST_SENSORS_H */
diff --git a/include/linux/iio/common/st_sensors_i2c.h b/include/linux/iio/common/st_sensors_i2c.h
new file mode 100644
index 000000000000..67d845385ae2
--- /dev/null
+++ b/include/linux/iio/common/st_sensors_i2c.h
@@ -0,0 +1,20 @@
1/*
2 * STMicroelectronics sensors i2c library 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#ifndef ST_SENSORS_I2C_H
12#define ST_SENSORS_I2C_H
13
14#include <linux/i2c.h>
15#include <linux/iio/common/st_sensors.h>
16
17void st_sensors_i2c_configure(struct iio_dev *indio_dev,
18 struct i2c_client *client, struct st_sensor_data *sdata);
19
20#endif /* ST_SENSORS_I2C_H */
diff --git a/include/linux/iio/common/st_sensors_spi.h b/include/linux/iio/common/st_sensors_spi.h
new file mode 100644
index 000000000000..d964a3563dc6
--- /dev/null
+++ b/include/linux/iio/common/st_sensors_spi.h
@@ -0,0 +1,20 @@
1/*
2 * STMicroelectronics sensors spi library 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#ifndef ST_SENSORS_SPI_H
12#define ST_SENSORS_SPI_H
13
14#include <linux/spi/spi.h>
15#include <linux/iio/common/st_sensors.h>
16
17void st_sensors_spi_configure(struct iio_dev *indio_dev,
18 struct spi_device *spi, struct st_sensor_data *sdata);
19
20#endif /* ST_SENSORS_SPI_H */
diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
index 16c35ac045bd..a85787ac66ab 100644
--- a/include/linux/iio/consumer.h
+++ b/include/linux/iio/consumer.h
@@ -15,6 +15,7 @@
15 15
16struct iio_dev; 16struct iio_dev;
17struct iio_chan_spec; 17struct iio_chan_spec;
18struct device;
18 19
19/** 20/**
20 * struct iio_channel - everything needed for a consumer to use a channel 21 * struct iio_channel - everything needed for a consumer to use a channel
@@ -48,14 +49,14 @@ void iio_channel_release(struct iio_channel *chan);
48 49
49/** 50/**
50 * iio_channel_get_all() - get all channels associated with a client 51 * iio_channel_get_all() - get all channels associated with a client
51 * @name: name of consumer device. 52 * @dev: Pointer to consumer device.
52 * 53 *
53 * Returns an array of iio_channel structures terminated with one with 54 * Returns an array of iio_channel structures terminated with one with
54 * null iio_dev pointer. 55 * null iio_dev pointer.
55 * This function is used by fairly generic consumers to get all the 56 * This function is used by fairly generic consumers to get all the
56 * channels registered as having this consumer. 57 * channels registered as having this consumer.
57 */ 58 */
58struct iio_channel *iio_channel_get_all(const char *name); 59struct iio_channel *iio_channel_get_all(struct device *dev);
59 60
60/** 61/**
61 * iio_channel_release_all() - reverse iio_channel_get_all 62 * iio_channel_release_all() - reverse iio_channel_get_all
@@ -66,7 +67,7 @@ void iio_channel_release_all(struct iio_channel *chan);
66struct iio_cb_buffer; 67struct iio_cb_buffer;
67/** 68/**
68 * iio_channel_get_all_cb() - register callback for triggered capture 69 * iio_channel_get_all_cb() - register callback for triggered capture
69 * @name: Name of client device. 70 * @dev: Pointer to client device.
70 * @cb: Callback function. 71 * @cb: Callback function.
71 * @private: Private data passed to callback. 72 * @private: Private data passed to callback.
72 * 73 *
@@ -74,7 +75,7 @@ struct iio_cb_buffer;
74 * So if the channels requested come from different devices this will 75 * So if the channels requested come from different devices this will
75 * fail. 76 * fail.
76 */ 77 */
77struct iio_cb_buffer *iio_channel_get_all_cb(const char *name, 78struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
78 int (*cb)(u8 *data, 79 int (*cb)(u8 *data,
79 void *private), 80 void *private),
80 void *private); 81 void *private);
diff --git a/include/linux/iio/driver.h b/include/linux/iio/driver.h
index a4f8b2e05af5..7dfb10ee2669 100644
--- a/include/linux/iio/driver.h
+++ b/include/linux/iio/driver.h
@@ -22,13 +22,10 @@ int iio_map_array_register(struct iio_dev *indio_dev,
22 struct iio_map *map); 22 struct iio_map *map);
23 23
24/** 24/**
25 * iio_map_array_unregister() - tell the core to remove consumer mappings 25 * iio_map_array_unregister() - tell the core to remove consumer mappings for
26 * the given provider device
26 * @indio_dev: provider device 27 * @indio_dev: provider device
27 * @map: array of mappings to remove. Note these must have same memory
28 * addresses as those originally added not just equal parameter
29 * values.
30 */ 28 */
31int iio_map_array_unregister(struct iio_dev *indio_dev, 29int iio_map_array_unregister(struct iio_dev *indio_dev);
32 struct iio_map *map);
33 30
34#endif 31#endif
diff --git a/include/linux/iio/gyro/itg3200.h b/include/linux/iio/gyro/itg3200.h
new file mode 100644
index 000000000000..c53f16914b77
--- /dev/null
+++ b/include/linux/iio/gyro/itg3200.h
@@ -0,0 +1,154 @@
1/*
2 * itg3200.h -- support InvenSense ITG3200
3 * Digital 3-Axis Gyroscope driver
4 *
5 * Copyright (c) 2011 Christian Strobel <christian.strobel@iis.fraunhofer.de>
6 * Copyright (c) 2011 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
7 * Copyright (c) 2012 Thorsten Nowak <thorsten.nowak@iis.fraunhofer.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#ifndef I2C_ITG3200_H_
15#define I2C_ITG3200_H_
16
17#include <linux/iio/iio.h>
18
19/* Register with I2C address (34h) */
20#define ITG3200_REG_ADDRESS 0x00
21
22/* Sample rate divider
23 * Range: 0 to 255
24 * Default value: 0x00 */
25#define ITG3200_REG_SAMPLE_RATE_DIV 0x15
26
27/* Digital low pass filter settings */
28#define ITG3200_REG_DLPF 0x16
29/* DLPF full scale range */
30#define ITG3200_DLPF_FS_SEL_2000 0x18
31/* Bandwidth (Hz) and internal sample rate
32 * (kHz) of DLPF */
33#define ITG3200_DLPF_256_8 0x00
34#define ITG3200_DLPF_188_1 0x01
35#define ITG3200_DLPF_98_1 0x02
36#define ITG3200_DLPF_42_1 0x03
37#define ITG3200_DLPF_20_1 0x04
38#define ITG3200_DLPF_10_1 0x05
39#define ITG3200_DLPF_5_1 0x06
40
41#define ITG3200_DLPF_CFG_MASK 0x07
42
43/* Configuration for interrupt operations */
44#define ITG3200_REG_IRQ_CONFIG 0x17
45/* Logic level */
46#define ITG3200_IRQ_ACTIVE_LOW 0x80
47#define ITG3200_IRQ_ACTIVE_HIGH 0x00
48/* Drive type */
49#define ITG3200_IRQ_OPEN_DRAIN 0x40
50#define ITG3200_IRQ_PUSH_PULL 0x00
51/* Latch mode */
52#define ITG3200_IRQ_LATCH_UNTIL_CLEARED 0x20
53#define ITG3200_IRQ_LATCH_50US_PULSE 0x00
54/* Latch clear method */
55#define ITG3200_IRQ_LATCH_CLEAR_ANY 0x10
56#define ITG3200_IRQ_LATCH_CLEAR_STATUS 0x00
57/* Enable interrupt when device is ready */
58#define ITG3200_IRQ_DEVICE_RDY_ENABLE 0x04
59/* Enable interrupt when data is available */
60#define ITG3200_IRQ_DATA_RDY_ENABLE 0x01
61
62/* Determine the status of ITG-3200 interrupts */
63#define ITG3200_REG_IRQ_STATUS 0x1A
64/* Status of 'device is ready'-interrupt */
65#define ITG3200_IRQ_DEVICE_RDY_STATUS 0x04
66/* Status of 'data is available'-interrupt */
67#define ITG3200_IRQ_DATA_RDY_STATUS 0x01
68
69/* Sensor registers */
70#define ITG3200_REG_TEMP_OUT_H 0x1B
71#define ITG3200_REG_TEMP_OUT_L 0x1C
72#define ITG3200_REG_GYRO_XOUT_H 0x1D
73#define ITG3200_REG_GYRO_XOUT_L 0x1E
74#define ITG3200_REG_GYRO_YOUT_H 0x1F
75#define ITG3200_REG_GYRO_YOUT_L 0x20
76#define ITG3200_REG_GYRO_ZOUT_H 0x21
77#define ITG3200_REG_GYRO_ZOUT_L 0x22
78
79/* Power management */
80#define ITG3200_REG_POWER_MANAGEMENT 0x3E
81/* Reset device and internal registers to the
82 * power-up-default settings */
83#define ITG3200_RESET 0x80
84/* Enable low power sleep mode */
85#define ITG3200_SLEEP 0x40
86/* Put according gyroscope in standby mode */
87#define ITG3200_STANDBY_GYRO_X 0x20
88#define ITG3200_STANDBY_GYRO_Y 0x10
89#define ITG3200_STANDBY_GYRO_Z 0x08
90/* Determine the device clock source */
91#define ITG3200_CLK_INTERNAL 0x00
92#define ITG3200_CLK_GYRO_X 0x01
93#define ITG3200_CLK_GYRO_Y 0x02
94#define ITG3200_CLK_GYRO_Z 0x03
95#define ITG3200_CLK_EXT_32K 0x04
96#define ITG3200_CLK_EXT_19M 0x05
97
98
99/**
100 * struct itg3200 - device instance specific data
101 * @i2c: actual i2c_client
102 * @trig: data ready trigger from itg3200 pin
103 **/
104struct itg3200 {
105 struct i2c_client *i2c;
106 struct iio_trigger *trig;
107};
108
109enum ITG3200_SCAN_INDEX {
110 ITG3200_SCAN_TEMP,
111 ITG3200_SCAN_GYRO_X,
112 ITG3200_SCAN_GYRO_Y,
113 ITG3200_SCAN_GYRO_Z,
114 ITG3200_SCAN_ELEMENTS,
115};
116
117int itg3200_write_reg_8(struct iio_dev *indio_dev,
118 u8 reg_address, u8 val);
119
120int itg3200_read_reg_8(struct iio_dev *indio_dev,
121 u8 reg_address, u8 *val);
122
123
124#ifdef CONFIG_IIO_BUFFER
125
126void itg3200_remove_trigger(struct iio_dev *indio_dev);
127int itg3200_probe_trigger(struct iio_dev *indio_dev);
128
129int itg3200_buffer_configure(struct iio_dev *indio_dev);
130void itg3200_buffer_unconfigure(struct iio_dev *indio_dev);
131
132#else /* CONFIG_IIO_BUFFER */
133
134static inline void itg3200_remove_trigger(struct iio_dev *indio_dev)
135{
136}
137
138static inline int itg3200_probe_trigger(struct iio_dev *indio_dev)
139{
140 return 0;
141}
142
143static inline int itg3200_buffer_configure(struct iio_dev *indio_dev)
144{
145 return 0;
146}
147
148static inline void itg3200_buffer_unconfigure(struct iio_dev *indio_dev)
149{
150}
151
152#endif /* CONFIG_IIO_RING_BUFFER */
153
154#endif /* ITG3200_H_ */