* [PATCH 1/4] iio: st_sensors: Add DT bindings for st_accel and st_gyro
[not found] ` <1372767338-13179-1-git-send-email-l.czerwinski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
@ 2013-07-02 12:15 ` Lukasz Czerwinski
2013-07-02 12:15 ` [PATCH 2/4] iio: st_sensors: Add threshold events support Lukasz Czerwinski
` (2 subsequent siblings)
3 siblings, 0 replies; 11+ messages in thread
From: Lukasz Czerwinski @ 2013-07-02 12:15 UTC (permalink / raw)
To: jic23-DgEjT+Ai2ygdnm+yROfE0A, denis.ciocca-qxv4g6HH51o
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Lukasz Czerwinski,
Kyungmin Park
This patch adds DT support for the STM accelometers and gyroscopes.
Signed-off-by: Lukasz Czerwinski <l.czerwinski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
.../bindings/iio/accelerometer/st_accel.txt | 53 ++++++++++++++++++++
.../devicetree/bindings/iio/gyroscope/st_gyro.txt | 51 +++++++++++++++++++
drivers/iio/accel/st_accel.h | 19 ++++---
drivers/iio/accel/st_accel_core.c | 10 ++--
drivers/iio/accel/st_accel_i2c.c | 19 ++++++-
drivers/iio/accel/st_accel_spi.c | 19 ++++++-
drivers/iio/common/st_sensors/st_sensors_core.c | 7 +--
drivers/iio/common/st_sensors/st_sensors_i2c.c | 48 ++++++++++++++++--
drivers/iio/common/st_sensors/st_sensors_spi.c | 48 ++++++++++++++++--
drivers/iio/gyro/st_gyro.h | 15 +++---
drivers/iio/gyro/st_gyro_core.c | 8 +--
drivers/iio/gyro/st_gyro_i2c.c | 18 ++++++-
drivers/iio/gyro/st_gyro_spi.c | 18 ++++++-
drivers/iio/magnetometer/st_magn.h | 3 +-
drivers/iio/magnetometer/st_magn_core.c | 5 +-
drivers/iio/magnetometer/st_magn_i2c.c | 2 +-
drivers/iio/magnetometer/st_magn_spi.c | 2 +-
drivers/iio/pressure/st_pressure.h | 3 +-
drivers/iio/pressure/st_pressure_core.c | 12 ++---
drivers/iio/pressure/st_pressure_i2c.c | 2 +-
drivers/iio/pressure/st_pressure_spi.c | 2 +-
include/linux/iio/common/st_sensors.h | 9 +++-
include/linux/platform_data/st_sensors_pdata.h | 2 +
23 files changed, 312 insertions(+), 63 deletions(-)
create mode 100644 Documentation/devicetree/bindings/iio/accelerometer/st_accel.txt
create mode 100644 Documentation/devicetree/bindings/iio/gyroscope/st_gyro.txt
diff --git a/Documentation/devicetree/bindings/iio/accelerometer/st_accel.txt b/Documentation/devicetree/bindings/iio/accelerometer/st_accel.txt
new file mode 100644
index 0000000..9eab7d9
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/accelerometer/st_accel.txt
@@ -0,0 +1,53 @@
+STMicroelectronics 3D accelerometer
+
+Required properties:
+
+ - compatible : should be one from
+ "st,lsm330dlhc-accel"
+ "st,lis3dh"
+ "st,lsm330d-accel"
+ "st,lsm330dl-accel"
+ "st,lsm330dlc-accel"
+ "st,lsm331dlh"
+ "st,lsm303dl-accel"
+ "st,lsm303dlh-accel"
+ "st,lsm303dlm-accel"
+ "st,lsm330-accel"
+
+ - reg : the I2C address of the accelerometer
+
+Optional properties:
+ - drdy-int-pin: default DRDY interrupt pin number (u8)
+ - interrupt-parent : phandle to the interrupt map subnode
+ - interrupts : interrupt mapping for st_accel interrupt sources:
+ 0: INT1 irq_data_ready
+ - irq-map : irq sub-node defining interrupt map
+ (all properties listed below are required):
+ - #interrupt-cells : should be 1
+ - #address-cells : should be 0
+ - #size-cells : should be 0
+ - interrupt-map : table of entries consisting of three child elements:
+ - unit_interrupt_specifier - 0 : INT1, 1 : INT2
+ - interrupt parent phandle
+ - parent unit interrupt specifier consisiting of two elements:
+ - index of the interrupt within the controller
+ - flags : should be 0
+
+Example:
+
+lsm330dlc_accel@19 {
+ compatible = "st,lsm330dlc-accel";
+ reg = <0x19>;
+ drdy-int-pin = /bits/ 8 <1>;
+ interrupt-parent = <&lsm330dlc_accel_map>;
+ interrupts= <0>, <1>;
+
+ lsm330dlc_accel_map: lsm330dlc-accel-map {
+ compatible = "samsung,lsm330dlc-accel-map";
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = <1 &gpx0 0 0>;
+ };
+};
+
diff --git a/Documentation/devicetree/bindings/iio/gyroscope/st_gyro.txt b/Documentation/devicetree/bindings/iio/gyroscope/st_gyro.txt
new file mode 100644
index 0000000..f4bf233
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/gyroscope/st_gyro.txt
@@ -0,0 +1,51 @@
+STMicroelectronics 3D gyroscope
+
+Required properties:
+
+ - compatible : should be one from
+ "st,l3g4200d"
+ "st,lsm330d-gyro"
+ "st,lsm330dl-gyro"
+ "st,lsm330dlc-gyro"
+ "st,l3gd20"
+ "st,l3gd20h"
+ "st,l3g4is-ui"
+ "st,lsm330-gyro"
+
+ - reg : the I2C address of the gyroscope
+
+Optional properties:
+
+ - drdy-int-pin: default DRDY interrupt pin number (u8)
+ - interrupt-parent : phandle to the interrupt map subnode
+ - interrupts : interrupt mapping for st_accel interrupt sources:
+ 0: INT1 irq_data_ready
+ - irq-map : irq sub-node defining interrupt map
+ (all properties listed below are required):
+ - #interrupt-cells : should be 1
+ - #address-cells : should be 0
+ - #size-cells : should be 0
+ - interrupt-map : table of entries consisting of three child elements:
+ - unit_interrupt_specifier - 0 : INT1, 1 : INT2
+ - interrupt parent phandle
+ - parent unit interrupt specifier consisiting of two elements:
+ - index of the interrupt within the controller
+ - flags : should be 0
+
+Example:
+
+lsm330dlc_gyro@6b {
+ compatible = "st,lsm330dlc-gyro";
+ reg = <0x6b>;
+ drdy-int-pin = /bits/ 8 <1>;
+ interrupt-parent = <&lsm330dlc_gyro_map>;
+ interrupts= <0> , <1>;
+
+ lsm330dlc_gyro_map: lsm330dlc-gyro-map {
+ compatible = "samsung,lsm330dlc-gyro-map";
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = <0 &gpf0 3 0>;
+ };
+};
diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h
index c387763..08a0eb7 100644
--- a/drivers/iio/accel/st_accel.h
+++ b/drivers/iio/accel/st_accel.h
@@ -14,16 +14,16 @@
#include <linux/types.h>
#include <linux/iio/common/st_sensors.h>
-#define LSM303DLHC_ACCEL_DEV_NAME "lsm303dlhc_accel"
+#define LSM303DLHC_ACCEL_DEV_NAME "lsm303dlhc-accel"
#define LIS3DH_ACCEL_DEV_NAME "lis3dh"
-#define LSM330D_ACCEL_DEV_NAME "lsm330d_accel"
-#define LSM330DL_ACCEL_DEV_NAME "lsm330dl_accel"
-#define LSM330DLC_ACCEL_DEV_NAME "lsm330dlc_accel"
+#define LSM330D_ACCEL_DEV_NAME "lsm330d-accel"
+#define LSM330DL_ACCEL_DEV_NAME "lsm330dl-accel"
+#define LSM330DLC_ACCEL_DEV_NAME "lsm330dlc-accel"
#define LIS331DLH_ACCEL_DEV_NAME "lis331dlh"
-#define LSM303DL_ACCEL_DEV_NAME "lsm303dl_accel"
-#define LSM303DLH_ACCEL_DEV_NAME "lsm303dlh_accel"
-#define LSM303DLM_ACCEL_DEV_NAME "lsm303dlm_accel"
-#define LSM330_ACCEL_DEV_NAME "lsm330_accel"
+#define LSM303DL_ACCEL_DEV_NAME "lsm303dl-accel"
+#define LSM303DLH_ACCEL_DEV_NAME "lsm303dlh-accel"
+#define LSM303DLM_ACCEL_DEV_NAME "lsm303dlm-accel"
+#define LSM330_ACCEL_DEV_NAME "lsm330-accel"
/**
* struct st_sensors_platform_data - default accel platform data
@@ -33,8 +33,7 @@ static const struct st_sensors_platform_data default_accel_pdata = {
.drdy_int_pin = 1,
};
-int st_accel_common_probe(struct iio_dev *indio_dev,
- struct st_sensors_platform_data *pdata);
+int st_accel_common_probe(struct iio_dev *indio_dev);
void st_accel_common_remove(struct iio_dev *indio_dev);
#ifdef CONFIG_IIO_BUFFER
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index aef3c9b..385cd86 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -449,8 +449,7 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
#define ST_ACCEL_TRIGGER_OPS NULL
#endif
-int st_accel_common_probe(struct iio_dev *indio_dev,
- struct st_sensors_platform_data *plat_data)
+int st_accel_common_probe(struct iio_dev *indio_dev)
{
int err;
struct st_sensor_data *adata = iio_priv(indio_dev);
@@ -472,11 +471,10 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
&adata->sensor->fs.fs_avl[0];
adata->odr = adata->sensor->odr.odr_avl[0].hz;
- if (!plat_data)
- plat_data =
- (struct st_sensors_platform_data *)&default_accel_pdata;
+ if (!adata->dev->platform_data && !adata->dev->of_node)
+ adata->drdy_int_pin = default_accel_pdata.drdy_int_pin;
- err = st_sensors_init_sensor(indio_dev, plat_data);
+ err = st_sensors_init_sensor(indio_dev);
if (err < 0)
goto st_accel_common_probe_error;
diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c
index 58d164d..63992f2 100644
--- a/drivers/iio/accel/st_accel_i2c.c
+++ b/drivers/iio/accel/st_accel_i2c.c
@@ -36,7 +36,7 @@ static int st_accel_i2c_probe(struct i2c_client *client,
st_sensors_i2c_configure(indio_dev, client, adata);
- err = st_accel_common_probe(indio_dev, client->dev.platform_data);
+ err = st_accel_common_probe(indio_dev);
if (err < 0)
goto st_accel_common_probe_error;
@@ -70,10 +70,27 @@ static const struct i2c_device_id st_accel_id_table[] = {
};
MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
+#ifdef CONFIG_OF
+static struct of_device_id st_accel_dt_match[] = {
+ { .compatible = "st,lsm330dlhc_accel" },
+ { .compatible = "st,lis3dh" },
+ { .compatible = "st,lsm330d-accel" },
+ { .compatible = "st,lsm330dl-accel" },
+ { .compatible = "st,lsm330dlc-accel" },
+ { .compatible = "st,lsm331dlh" },
+ { .compatible = "st,lsm303dl-accel" },
+ { .compatible = "st,lsm303dlh-accel" },
+ { .compatible = "st,lsm303dlm-accel" },
+ { .compatible = "st,lsm330-accel" },
+ { }
+};
+#endif
+
static struct i2c_driver st_accel_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "st-accel-i2c",
+ .of_match_table = of_match_ptr(st_accel_dt_match),
},
.probe = st_accel_i2c_probe,
.remove = st_accel_i2c_remove,
diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c
index 21ed929..671fd48 100644
--- a/drivers/iio/accel/st_accel_spi.c
+++ b/drivers/iio/accel/st_accel_spi.c
@@ -35,7 +35,7 @@ static int st_accel_spi_probe(struct spi_device *spi)
st_sensors_spi_configure(indio_dev, spi, adata);
- err = st_accel_common_probe(indio_dev, spi->dev.platform_data);
+ err = st_accel_common_probe(indio_dev);
if (err < 0)
goto st_accel_common_probe_error;
@@ -69,10 +69,27 @@ static const struct spi_device_id st_accel_id_table[] = {
};
MODULE_DEVICE_TABLE(spi, st_accel_id_table);
+#ifdef CONFIG_OF
+static struct of_device_id st_accel_dt_match[] = {
+ { .compatible = "st,lsm330dlhc-accel" },
+ { .compatible = "st,lis3dh" },
+ { .compatible = "st,lsm330d-accel" },
+ { .compatible = "st,lsm330dl-accel" },
+ { .compatible = "st,lsm330dlc-accel" },
+ { .compatible = "st,lsm331dlh" },
+ { .compatible = "st,lsm303dl-accel" },
+ { .compatible = "st,lsm303dlh-accel" },
+ { .compatible = "st,lsm303dlm-accel" },
+ { .compatible = "st,lsm330-accel" },
+ { }
+};
+#endif
+
static struct spi_driver st_accel_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "st-accel-spi",
+ .of_match_table = of_match_ptr(st_accel_dt_match),
},
.probe = st_accel_spi_probe,
.remove = st_accel_spi_remove,
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index 965ee22..461eaf2 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -198,15 +198,14 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable)
}
EXPORT_SYMBOL(st_sensors_set_axis_enable);
-int st_sensors_init_sensor(struct iio_dev *indio_dev,
- struct st_sensors_platform_data *pdata)
+int st_sensors_init_sensor(struct iio_dev *indio_dev)
{
int err;
struct st_sensor_data *sdata = iio_priv(indio_dev);
mutex_init(&sdata->tb.buf_lock);
- switch (pdata->drdy_int_pin) {
+ switch (sdata->drdy_int_pin) {
case 1:
if (sdata->sensor->drdy_irq.mask_int1 == 0) {
dev_err(&indio_dev->dev,
@@ -214,7 +213,6 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
err = -EINVAL;
goto init_error;
}
- sdata->drdy_int_pin = 1;
break;
case 2:
if (sdata->sensor->drdy_irq.mask_int2 == 0) {
@@ -223,7 +221,6 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
err = -EINVAL;
goto init_error;
}
- sdata->drdy_int_pin = 2;
break;
default:
dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n");
diff --git a/drivers/iio/common/st_sensors/st_sensors_i2c.c b/drivers/iio/common/st_sensors/st_sensors_i2c.c
index 38af944..cad5acc 100644
--- a/drivers/iio/common/st_sensors/st_sensors_i2c.c
+++ b/drivers/iio/common/st_sensors/st_sensors_i2c.c
@@ -8,6 +8,8 @@
* Licensed under the GPL-2.
*/
+#include <linux/of.h>
+#include <linux/of_irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -18,11 +20,48 @@
#define ST_SENSORS_I2C_MULTIREAD 0x80
-static unsigned int st_sensors_i2c_get_irq(struct iio_dev *indio_dev)
+static unsigned int st_sensors_i2c_get_data_rdy_irq(struct iio_dev *indio_dev)
{
struct st_sensor_data *sdata = iio_priv(indio_dev);
- return to_i2c_client(sdata->dev)->irq;
+ return sdata->irq_map[ST_SENSORS_INT1];
+}
+
+static void st_sensors_parse_platform_data(struct i2c_client *client,
+ struct iio_dev *indio_dev)
+{
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+ struct device_node *np = client->dev.of_node;
+ struct st_sensors_platform_data *pdata = client->dev.platform_data;
+
+ if (pdata)
+ sdata->drdy_int_pin = pdata->drdy_int_pin;
+ else if (np)
+ of_property_read_u8(np, "drdy-int-pin",
+ (u8 *)&sdata->drdy_int_pin);
+}
+
+static unsigned int st_sensors_i2c_map_irq(struct i2c_client *client,
+ unsigned int irq_pos)
+{
+ struct device_node *np = client->dev.of_node;
+ struct st_sensors_platform_data *pdata = client->dev.platform_data;
+
+ if (pdata)
+ return pdata->irqs[irq_pos];
+ else if (np)
+ return irq_of_parse_and_map(np, irq_pos);
+
+ return 0;
+}
+
+static void st_sensors_i2c_map_irqs(struct i2c_client *client,
+ struct iio_dev *indio_dev)
+{
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+
+ sdata->irq_map[ST_SENSORS_INT1] =
+ st_sensors_i2c_map_irq(client, ST_SENSORS_INT1);
}
static int st_sensors_i2c_read_byte(struct st_sensor_transfer_buffer *tb,
@@ -71,8 +110,11 @@ void st_sensors_i2c_configure(struct iio_dev *indio_dev,
indio_dev->dev.parent = &client->dev;
indio_dev->name = client->name;
+ st_sensors_parse_platform_data(client, indio_dev);
+
sdata->tf = &st_sensors_tf_i2c;
- sdata->get_irq_data_ready = st_sensors_i2c_get_irq;
+ st_sensors_i2c_map_irqs(client, indio_dev);
+ sdata->get_irq_data_ready = st_sensors_i2c_get_data_rdy_irq;
}
EXPORT_SYMBOL(st_sensors_i2c_configure);
diff --git a/drivers/iio/common/st_sensors/st_sensors_spi.c b/drivers/iio/common/st_sensors/st_sensors_spi.c
index 251baf6..5531bd4 100644
--- a/drivers/iio/common/st_sensors/st_sensors_spi.c
+++ b/drivers/iio/common/st_sensors/st_sensors_spi.c
@@ -8,6 +8,8 @@
* Licensed under the GPL-2.
*/
+#include <linux/of.h>
+#include <linux/of_irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -19,11 +21,48 @@
#define ST_SENSORS_SPI_MULTIREAD 0xc0
#define ST_SENSORS_SPI_READ 0x80
-static unsigned int st_sensors_spi_get_irq(struct iio_dev *indio_dev)
+static unsigned int st_sensors_spi_get_data_rdy_irq(struct iio_dev *indio_dev)
{
struct st_sensor_data *sdata = iio_priv(indio_dev);
- return to_spi_device(sdata->dev)->irq;
+ return sdata->irq_map[ST_SENSORS_INT1];
+}
+
+static void st_sensors_parse_platform_data(struct spi_device *spi,
+ struct iio_dev *indio_dev)
+{
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+ struct device_node *np = spi->dev.of_node;
+ struct st_sensors_platform_data *pdata = spi->dev.platform_data;
+
+ if (pdata)
+ sdata->drdy_int_pin = pdata->drdy_int_pin;
+ else if (np)
+ of_property_read_u8(np, "drdy-int-pin",
+ (u8 *)&sdata->drdy_int_pin);
+}
+
+static unsigned int st_sensors_spi_map_irq(struct spi_device *spi,
+ unsigned int irq_pos)
+{
+ struct device_node *np = spi->dev.of_node;
+ struct st_sensors_platform_data *pdata = spi->dev.platform_data;
+
+ if (pdata)
+ return pdata->irqs[irq_pos];
+ else if (np)
+ return irq_of_parse_and_map(np, irq_pos);
+
+ return 0;
+}
+
+static void st_sensors_spi_map_irqs(struct spi_device *spi,
+ struct iio_dev *indio_dev)
+{
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+
+ sdata->irq_map[ST_SENSORS_INT1] =
+ st_sensors_spi_map_irq(spi, ST_SENSORS_INT1);
}
static int st_sensors_spi_read(struct st_sensor_transfer_buffer *tb,
@@ -111,8 +150,11 @@ void st_sensors_spi_configure(struct iio_dev *indio_dev,
indio_dev->dev.parent = &spi->dev;
indio_dev->name = spi->modalias;
+ st_sensors_parse_platform_data(spi, indio_dev);
+
sdata->tf = &st_sensors_tf_spi;
- sdata->get_irq_data_ready = st_sensors_spi_get_irq;
+ st_sensors_spi_map_irqs(spi, indio_dev);
+ sdata->get_irq_data_ready = st_sensors_spi_get_data_rdy_irq;
}
EXPORT_SYMBOL(st_sensors_spi_configure);
diff --git a/drivers/iio/gyro/st_gyro.h b/drivers/iio/gyro/st_gyro.h
index f8f2bf8..81e5ec3 100644
--- a/drivers/iio/gyro/st_gyro.h
+++ b/drivers/iio/gyro/st_gyro.h
@@ -15,24 +15,23 @@
#include <linux/iio/common/st_sensors.h>
#define L3G4200D_GYRO_DEV_NAME "l3g4200d"
-#define LSM330D_GYRO_DEV_NAME "lsm330d_gyro"
-#define LSM330DL_GYRO_DEV_NAME "lsm330dl_gyro"
-#define LSM330DLC_GYRO_DEV_NAME "lsm330dlc_gyro"
+#define LSM330D_GYRO_DEV_NAME "lsm330d-gyro"
+#define LSM330DL_GYRO_DEV_NAME "lsm330dl-gyro"
+#define LSM330DLC_GYRO_DEV_NAME "lsm330dlc-gyro"
#define L3GD20_GYRO_DEV_NAME "l3gd20"
#define L3GD20H_GYRO_DEV_NAME "l3gd20h"
-#define L3G4IS_GYRO_DEV_NAME "l3g4is_ui"
-#define LSM330_GYRO_DEV_NAME "lsm330_gyro"
+#define L3G4IS_GYRO_DEV_NAME "l3g4is-ui"
+#define LSM330_GYRO_DEV_NAME "lsm330-gyro"
/**
* struct st_sensors_platform_data - gyro platform data
* @drdy_int_pin: DRDY on gyros is available only on INT2 pin.
*/
-static const struct st_sensors_platform_data gyro_pdata = {
+static const struct st_sensors_platform_data default_gyro_pdata = {
.drdy_int_pin = 2,
};
-int st_gyro_common_probe(struct iio_dev *indio_dev,
- struct st_sensors_platform_data *pdata);
+int st_gyro_common_probe(struct iio_dev *indio_dev);
void st_gyro_common_remove(struct iio_dev *indio_dev);
#ifdef CONFIG_IIO_BUFFER
diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c
index 85fa8d3..e86684c 100644
--- a/drivers/iio/gyro/st_gyro_core.c
+++ b/drivers/iio/gyro/st_gyro_core.c
@@ -302,8 +302,7 @@ static const struct iio_trigger_ops st_gyro_trigger_ops = {
#define ST_GYRO_TRIGGER_OPS NULL
#endif
-int st_gyro_common_probe(struct iio_dev *indio_dev,
- struct st_sensors_platform_data *pdata)
+int st_gyro_common_probe(struct iio_dev *indio_dev)
{
int err;
struct st_sensor_data *gdata = iio_priv(indio_dev);
@@ -325,7 +324,10 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
&gdata->sensor->fs.fs_avl[0];
gdata->odr = gdata->sensor->odr.odr_avl[0].hz;
- err = st_sensors_init_sensor(indio_dev, pdata);
+ if (!gdata->dev->platform_data && !gdata->dev->of_node)
+ gdata->drdy_int_pin = default_gyro_pdata.drdy_int_pin;
+
+ err = st_sensors_init_sensor(indio_dev);
if (err < 0)
goto st_gyro_common_probe_error;
diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c
index c7a29a4..413062e 100644
--- a/drivers/iio/gyro/st_gyro_i2c.c
+++ b/drivers/iio/gyro/st_gyro_i2c.c
@@ -36,8 +36,8 @@ static int st_gyro_i2c_probe(struct i2c_client *client,
st_sensors_i2c_configure(indio_dev, client, gdata);
- err = st_gyro_common_probe(indio_dev,
- (struct st_sensors_platform_data *)&gyro_pdata);
+ err = st_gyro_common_probe(indio_dev);
+
if (err < 0)
goto st_gyro_common_probe_error;
@@ -69,10 +69,24 @@ static const struct i2c_device_id st_gyro_id_table[] = {
};
MODULE_DEVICE_TABLE(i2c, st_gyro_id_table);
+#ifdef CONFIG_OF
+static struct of_device_id st_gyro_dt_match[] = {
+ { .compatible = "st,l3g4200d" },
+ { .compatible = "st,lsm330d-gyro" },
+ { .compatible = "st,lsm330dl-gyro" },
+ { .compatible = "st,lsm330dlc-gyro" },
+ { .compatible = "st,l3gd20" },
+ { .compatible = "st,l3gd20h" },
+ { .compatible = "st,l3g4is-ui" },
+ { .compatible = "st,lsm330-gyro" },
+};
+#endif
+
static struct i2c_driver st_gyro_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "st-gyro-i2c",
+ .of_match_table = of_match_ptr(st_gyro_dt_match),
},
.probe = st_gyro_i2c_probe,
.remove = st_gyro_i2c_remove,
diff --git a/drivers/iio/gyro/st_gyro_spi.c b/drivers/iio/gyro/st_gyro_spi.c
index 14b0762..4956dcc 100644
--- a/drivers/iio/gyro/st_gyro_spi.c
+++ b/drivers/iio/gyro/st_gyro_spi.c
@@ -35,8 +35,8 @@ static int st_gyro_spi_probe(struct spi_device *spi)
st_sensors_spi_configure(indio_dev, spi, gdata);
- err = st_gyro_common_probe(indio_dev,
- (struct st_sensors_platform_data *)&gyro_pdata);
+ err = st_gyro_common_probe(indio_dev);
+
if (err < 0)
goto st_gyro_common_probe_error;
@@ -68,10 +68,24 @@ static const struct spi_device_id st_gyro_id_table[] = {
};
MODULE_DEVICE_TABLE(spi, st_gyro_id_table);
+#ifdef CONFIG_OF
+static struct of_device_id st_gyro_dt_match[] = {
+ { .compatible = "st,l3g4200d" },
+ { .compatible = "st,lsm330d-gyro" },
+ { .compatible = "st,lsm330dl-gyro" },
+ { .compatible = "st,lsm330dlc-gyro" },
+ { .compatible = "st,l3gd20" },
+ { .compatible = "st,l3gd20h" },
+ { .compatible = "st,l3g4is-ui" },
+ { .compatible = "st,lsm330-gyro" },
+};
+#endif
+
static struct spi_driver st_gyro_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "st-gyro-spi",
+ .of_match_table = of_match_ptr(st_gyro_dt_match),
},
.probe = st_gyro_spi_probe,
.remove = st_gyro_spi_remove,
diff --git a/drivers/iio/magnetometer/st_magn.h b/drivers/iio/magnetometer/st_magn.h
index 694e33e..7e81d00 100644
--- a/drivers/iio/magnetometer/st_magn.h
+++ b/drivers/iio/magnetometer/st_magn.h
@@ -18,8 +18,7 @@
#define LSM303DLM_MAGN_DEV_NAME "lsm303dlm_magn"
#define LIS3MDL_MAGN_DEV_NAME "lis3mdl"
-int st_magn_common_probe(struct iio_dev *indio_dev,
- struct st_sensors_platform_data *pdata);
+int st_magn_common_probe(struct iio_dev *indio_dev);
void st_magn_common_remove(struct iio_dev *indio_dev);
#ifdef CONFIG_IIO_BUFFER
diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c
index 7cd784f..ebfe8f1 100644
--- a/drivers/iio/magnetometer/st_magn_core.c
+++ b/drivers/iio/magnetometer/st_magn_core.c
@@ -345,8 +345,7 @@ static const struct iio_info magn_info = {
.write_raw = &st_magn_write_raw,
};
-int st_magn_common_probe(struct iio_dev *indio_dev,
- struct st_sensors_platform_data *pdata)
+int st_magn_common_probe(struct iio_dev *indio_dev)
{
int err;
struct st_sensor_data *mdata = iio_priv(indio_dev);
@@ -368,7 +367,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
&mdata->sensor->fs.fs_avl[0];
mdata->odr = mdata->sensor->odr.odr_avl[0].hz;
- err = st_sensors_init_sensor(indio_dev, pdata);
+ err = st_sensors_init_sensor(indio_dev);
if (err < 0)
goto st_magn_common_probe_error;
diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c
index 1bed117..e6adc4a 100644
--- a/drivers/iio/magnetometer/st_magn_i2c.c
+++ b/drivers/iio/magnetometer/st_magn_i2c.c
@@ -36,7 +36,7 @@ static int st_magn_i2c_probe(struct i2c_client *client,
st_sensors_i2c_configure(indio_dev, client, mdata);
- err = st_magn_common_probe(indio_dev, NULL);
+ err = st_magn_common_probe(indio_dev);
if (err < 0)
goto st_magn_common_probe_error;
diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c
index a2333a1..51adb79 100644
--- a/drivers/iio/magnetometer/st_magn_spi.c
+++ b/drivers/iio/magnetometer/st_magn_spi.c
@@ -35,7 +35,7 @@ static int st_magn_spi_probe(struct spi_device *spi)
st_sensors_spi_configure(indio_dev, spi, mdata);
- err = st_magn_common_probe(indio_dev, NULL);
+ err = st_magn_common_probe(indio_dev);
if (err < 0)
goto st_magn_common_probe_error;
diff --git a/drivers/iio/pressure/st_pressure.h b/drivers/iio/pressure/st_pressure.h
index b0b6306..8a8a900 100644
--- a/drivers/iio/pressure/st_pressure.h
+++ b/drivers/iio/pressure/st_pressure.h
@@ -24,8 +24,7 @@ static const struct st_sensors_platform_data default_press_pdata = {
.drdy_int_pin = 1,
};
-int st_press_common_probe(struct iio_dev *indio_dev,
- struct st_sensors_platform_data *pdata);
+int st_press_common_probe(struct iio_dev *indio_dev);
void st_press_common_remove(struct iio_dev *indio_dev);
#ifdef CONFIG_IIO_BUFFER
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
index b8ecc87..aacea2a 100644
--- a/drivers/iio/pressure/st_pressure_core.c
+++ b/drivers/iio/pressure/st_pressure_core.c
@@ -202,8 +202,7 @@ static const struct iio_trigger_ops st_press_trigger_ops = {
#define ST_PRESS_TRIGGER_OPS NULL
#endif
-int st_press_common_probe(struct iio_dev *indio_dev,
- struct st_sensors_platform_data *plat_data)
+int st_press_common_probe(struct iio_dev *indio_dev)
{
int err;
struct st_sensor_data *pdata = iio_priv(indio_dev);
@@ -219,17 +218,18 @@ int st_press_common_probe(struct iio_dev *indio_dev,
pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS;
pdata->multiread_bit = pdata->sensor->multi_read_bit;
indio_dev->channels = pdata->sensor->ch;
+
indio_dev->num_channels = ARRAY_SIZE(st_press_channels);
pdata->current_fullscale = (struct st_sensor_fullscale_avl *)
&pdata->sensor->fs.fs_avl[0];
pdata->odr = pdata->sensor->odr.odr_avl[0].hz;
- if (!plat_data)
- plat_data =
- (struct st_sensors_platform_data *)&default_press_pdata;
- err = st_sensors_init_sensor(indio_dev, plat_data);
+ if (!pdata->dev->platform_data && !pdata->dev->of_node)
+ pdata->drdy_int_pin = default_press_pdata.drdy_int_pin;
+
+ err = st_sensors_init_sensor(indio_dev);
if (err < 0)
goto st_press_common_probe_error;
diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c
index 3065993..7cebcc7 100644
--- a/drivers/iio/pressure/st_pressure_i2c.c
+++ b/drivers/iio/pressure/st_pressure_i2c.c
@@ -36,7 +36,7 @@ static int st_press_i2c_probe(struct i2c_client *client,
st_sensors_i2c_configure(indio_dev, client, pdata);
- err = st_press_common_probe(indio_dev, client->dev.platform_data);
+ err = st_press_common_probe(indio_dev);
if (err < 0)
goto st_press_common_probe_error;
diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c
index b2aded6..17a1490 100644
--- a/drivers/iio/pressure/st_pressure_spi.c
+++ b/drivers/iio/pressure/st_pressure_spi.c
@@ -35,7 +35,7 @@ static int st_press_spi_probe(struct spi_device *spi)
st_sensors_spi_configure(indio_dev, spi, pdata);
- err = st_press_common_probe(indio_dev, spi->dev.platform_data);
+ err = st_press_common_probe(indio_dev);
if (err < 0)
goto st_press_common_probe_error;
diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
index e51f654..07e27e4 100644
--- a/include/linux/iio/common/st_sensors.h
+++ b/include/linux/iio/common/st_sensors.h
@@ -40,6 +40,10 @@
#define ST_SENSORS_MAX_NAME 17
#define ST_SENSORS_MAX_4WAI 7
+#define ST_SENSORS_INT_MAX 2
+#define ST_SENSORS_INT1 0
+#define ST_SENSORS_INT2 1
+
#define ST_SENSORS_LSM_CHANNELS(device_type, mask, index, mod, \
ch2, s, endian, rbits, sbits, addr) \
{ \
@@ -205,6 +209,7 @@ struct st_sensors {
* @buffer_data: Data used by buffer part.
* @odr: Output data rate of the sensor [Hz].
* num_data_channels: Number of data channels used in buffer.
+ * @irq_map: Container of mapped IRQs.
* @drdy_int_pin: Redirect DRDY on pin 1 (1) or pin 2 (2).
* @get_irq_data_ready: Function to get the IRQ used for data ready signal.
* @tf: Transfer function structure used by I/O operations.
@@ -223,6 +228,7 @@ struct st_sensor_data {
unsigned int odr;
unsigned int num_data_channels;
+ unsigned int irq_map[ST_SENSORS_INT_MAX];
u8 drdy_int_pin;
@@ -256,8 +262,7 @@ static inline void st_sensors_deallocate_trigger(struct iio_dev *indio_dev)
}
#endif
-int st_sensors_init_sensor(struct iio_dev *indio_dev,
- struct st_sensors_platform_data *pdata);
+int st_sensors_init_sensor(struct iio_dev *indio_dev);
int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable);
diff --git a/include/linux/platform_data/st_sensors_pdata.h b/include/linux/platform_data/st_sensors_pdata.h
index 7538391..991db72 100644
--- a/include/linux/platform_data/st_sensors_pdata.h
+++ b/include/linux/platform_data/st_sensors_pdata.h
@@ -19,6 +19,8 @@
*/
struct st_sensors_platform_data {
u8 drdy_int_pin;
+
+ unsigned int irqs[2];
};
#endif /* ST_SENSORS_PDATA_H */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/4] iio: st_sensors: Add threshold events support
[not found] ` <1372767338-13179-1-git-send-email-l.czerwinski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2013-07-02 12:15 ` [PATCH 1/4] iio: st_sensors: Add DT bindings for st_accel and st_gyro Lukasz Czerwinski
@ 2013-07-02 12:15 ` Lukasz Czerwinski
[not found] ` <1372767338-13179-3-git-send-email-l.czerwinski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2013-07-02 12:15 ` [PATCH 3/4] iio: accel: Add event subsystem to st_accel driver Lukasz Czerwinski
2013-07-02 12:15 ` [PATCH 4/4] iio: lps331ap: Add support for DT Lukasz Czerwinski
3 siblings, 1 reply; 11+ messages in thread
From: Lukasz Czerwinski @ 2013-07-02 12:15 UTC (permalink / raw)
To: jic23-DgEjT+Ai2ygdnm+yROfE0A, denis.ciocca-qxv4g6HH51o
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Lukasz Czerwinski,
Kyungmin Park
This patch adds threshold events support for the ST common
library.
Signed-off-by: Lukasz Czerwinski <l.czerwinski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
drivers/iio/common/st_sensors/st_sensors_core.c | 218 ++++++++++++++++++++++-
drivers/iio/common/st_sensors/st_sensors_i2c.c | 11 ++
drivers/iio/common/st_sensors/st_sensors_spi.c | 11 ++
include/linux/iio/common/st_sensors.h | 79 +++++++-
4 files changed, 316 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index 461eaf2..211661e 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -13,7 +13,9 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
+#include <linux/iio/events.h>
#include <asm/unaligned.h>
+#include <linux/interrupt.h>
#include <linux/iio/common/st_sensors.h>
@@ -359,7 +361,8 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev,
*val = *val >> ch->scan_type.shift;
- err = st_sensors_set_enable(indio_dev, false);
+ if (!sdata->events_flag)
+ err = st_sensors_set_enable(indio_dev, false);
}
mutex_unlock(&indio_dev->mlock);
@@ -488,6 +491,219 @@ ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
}
EXPORT_SYMBOL(st_sensors_sysfs_scale_avail);
+static struct st_sensor_event *st_sensor_find_event_data(struct
+ st_sensor_data * sdata, u64 event_code)
+{
+ int i;
+ int mod = IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code);
+ int type = IIO_EVENT_CODE_EXTRACT_TYPE(event_code);
+ int chan_type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code);
+ int dir = IIO_EVENT_CODE_EXTRACT_DIR(event_code);
+ struct st_sensor_event_irq *irq = &sdata->sensor->event_irq;
+ struct st_sensor_event *event;
+
+ if (irq->event_count == 0)
+ return NULL;
+
+ for (i = 0; i < irq->event_count; i++) {
+ event = &irq->events[i];
+
+ if (event->modifier == mod &&
+ event->event_type == type &&
+ event->direction == dir &&
+ event->chan_type == chan_type)
+ return event;
+ }
+
+ return NULL;
+}
+
+int st_sensors_read_event_config(struct iio_dev *indio_dev,
+ u64 event_code)
+{
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+ struct st_sensor_event *event =
+ st_sensor_find_event_data(sdata, event_code);
+
+ if (event)
+ return (bool)(sdata->events_flag & (1 << event->bit));
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(st_sensors_read_event_config);
+
+int st_sensors_write_event_config(struct iio_dev *indio_dev,
+ u64 event_code,
+ int state)
+{
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+ struct st_sensor_event *event =
+ st_sensor_find_event_data(sdata, event_code);
+ int unsigned mask;
+ int err = -EINVAL;
+
+ mutex_lock(&indio_dev->mlock);
+
+ if (!event)
+ goto error;
+
+ mask = (1 << event->bit);
+ err = st_sensors_write_data_with_mask(indio_dev,
+ sdata->sensor->event_irq.ctrl_reg.addr,
+ mask, (bool)state);
+ if (err < 0)
+ goto error;
+
+ if (state)
+ sdata->events_flag |= mask;
+ else
+ sdata->events_flag &= ~mask;
+
+ err = st_sensors_set_enable(indio_dev, (bool)sdata->events_flag);
+
+ mutex_unlock(&indio_dev->mlock);
+
+ return 0;
+
+error:
+ mutex_unlock(&indio_dev->mlock);
+ return err;
+}
+EXPORT_SYMBOL(st_sensors_write_event_config);
+
+int st_sensors_read_event_value(struct iio_dev *indio_dev,
+ u64 event_code,
+ int *val)
+{
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+ struct st_sensor_event *event =
+ st_sensor_find_event_data(sdata, event_code);
+ u8 byte;
+ int err;
+
+ if (!event)
+ goto error;
+
+ mutex_lock(&indio_dev->mlock);
+
+ err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
+ event->event_ths_reg.addr, &byte);
+ if (!err)
+ *val = byte;
+
+ mutex_unlock(&indio_dev->mlock);
+ return err;
+
+error:
+ return -EINVAL;
+
+}
+EXPORT_SYMBOL(st_sensors_read_event_value);
+
+int st_sensors_write_event_value(struct iio_dev *indio_dev,
+ u64 event_code,
+ int val)
+{
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+ struct st_sensor_event *event =
+ st_sensor_find_event_data(sdata, event_code);
+ int err;
+
+ if (!event)
+ goto error;
+
+ mutex_lock(&indio_dev->mlock);
+
+ err = st_sensors_write_data_with_mask(indio_dev,
+ event->event_ths_reg.addr,
+ event->event_ths_reg.mask,
+ (u8)val);
+
+ mutex_unlock(&indio_dev->mlock);
+
+ return err;
+error:
+ return -EINVAL;
+
+}
+EXPORT_SYMBOL(st_sensors_write_event_value);
+
+static irqreturn_t st_sensor_event_handler(int irq, void *private)
+{
+ struct iio_dev *indio_dev = private;
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+ struct st_sensor_event_irq *irq_data =
+ &sdata->sensor->event_irq;
+ struct st_sensor_event *event;
+ s64 timestamp = iio_get_time_ns();
+ u8 status, mask, i;
+ int err = -EIO;
+
+ if (sdata)
+ err = sdata->tf->read_byte(&sdata->tb,
+ sdata->dev,
+ irq_data->status_reg.addr,
+ &status);
+
+ if (err < 0)
+ goto exit;
+
+ for (i = 0; i < irq_data->event_count; i++) {
+ event = &irq_data->events[i];
+ mask = (1 << event->bit);
+ if (status & mask)
+ iio_push_event(indio_dev,
+ IIO_MOD_EVENT_CODE(event->chan_type,
+ 0,
+ event->modifier,
+ event->event_type,
+ event->direction),
+ timestamp);
+ }
+
+exit:
+
+ return IRQ_HANDLED;
+}
+
+int st_sensors_request_event_irq(struct iio_dev *indio_dev)
+{
+ int err;
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+
+ err = request_threaded_irq(sdata->get_irq_event(indio_dev),
+ NULL,
+ st_sensor_event_handler,
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+ dev_name(&indio_dev->dev),
+ indio_dev);
+
+ return err;
+}
+
+int st_sensors_enable_events(struct iio_dev *indio_dev)
+{
+ int err;
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+ struct st_sensor_event_irq *irq = &sdata->sensor->event_irq;
+
+ err = st_sensors_write_data_with_mask(indio_dev,
+ irq->addr,
+ irq->mask,
+ 1);
+
+ if (err < 0)
+ goto error;
+
+ err = st_sensors_write_data_with_mask(indio_dev,
+ irq->ctrl_reg.addr,
+ irq->ctrl_reg.mask,
+ irq->ctrl_reg.val);
+error:
+ return err;
+}
+EXPORT_SYMBOL(st_sensors_enable_events);
+
MODULE_AUTHOR("Denis Ciocca <denis.ciocca-qxv4g6HH51o@public.gmane.org>");
MODULE_DESCRIPTION("STMicroelectronics ST-sensors core");
MODULE_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
index cad5acc..b364398 100644
--- a/drivers/iio/common/st_sensors/st_sensors_i2c.c
+++ b/drivers/iio/common/st_sensors/st_sensors_i2c.c
@@ -27,6 +27,13 @@ static unsigned int st_sensors_i2c_get_data_rdy_irq(struct iio_dev *indio_dev)
return sdata->irq_map[ST_SENSORS_INT1];
}
+static unsigned int st_sensors_i2c_get_event_irq(struct iio_dev *indio_dev)
+{
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+
+ return sdata->irq_map[ST_SENSORS_INT2];
+}
+
static void st_sensors_parse_platform_data(struct i2c_client *client,
struct iio_dev *indio_dev)
{
@@ -62,6 +69,9 @@ static void st_sensors_i2c_map_irqs(struct i2c_client *client,
sdata->irq_map[ST_SENSORS_INT1] =
st_sensors_i2c_map_irq(client, ST_SENSORS_INT1);
+
+ sdata->irq_map[ST_SENSORS_INT2] =
+ st_sensors_i2c_map_irq(client, ST_SENSORS_INT2);
}
static int st_sensors_i2c_read_byte(struct st_sensor_transfer_buffer *tb,
@@ -115,6 +125,7 @@ void st_sensors_i2c_configure(struct iio_dev *indio_dev,
sdata->tf = &st_sensors_tf_i2c;
st_sensors_i2c_map_irqs(client, indio_dev);
sdata->get_irq_data_ready = st_sensors_i2c_get_data_rdy_irq;
+ sdata->get_irq_event = st_sensors_i2c_get_event_irq;
}
EXPORT_SYMBOL(st_sensors_i2c_configure);
diff --git a/drivers/iio/common/st_sensors/st_sensors_spi.c b/drivers/iio/common/st_sensors/st_sensors_spi.c
index 5531bd4..5baf0ec 100644
--- a/drivers/iio/common/st_sensors/st_sensors_spi.c
+++ b/drivers/iio/common/st_sensors/st_sensors_spi.c
@@ -28,6 +28,13 @@ static unsigned int st_sensors_spi_get_data_rdy_irq(struct iio_dev *indio_dev)
return sdata->irq_map[ST_SENSORS_INT1];
}
+static unsigned int st_sensors_spi_get_event_irq(struct iio_dev *indio_dev)
+{
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+
+ return sdata->irq_map[ST_SENSORS_INT2];
+}
+
static void st_sensors_parse_platform_data(struct spi_device *spi,
struct iio_dev *indio_dev)
{
@@ -63,6 +70,9 @@ static void st_sensors_spi_map_irqs(struct spi_device *spi,
sdata->irq_map[ST_SENSORS_INT1] =
st_sensors_spi_map_irq(spi, ST_SENSORS_INT1);
+
+ sdata->irq_map[ST_SENSORS_INT2] =
+ st_sensors_spi_map_irq(spi, ST_SENSORS_INT2);
}
static int st_sensors_spi_read(struct st_sensor_transfer_buffer *tb,
@@ -155,6 +165,7 @@ void st_sensors_spi_configure(struct iio_dev *indio_dev,
sdata->tf = &st_sensors_tf_spi;
st_sensors_spi_map_irqs(spi, indio_dev);
sdata->get_irq_data_ready = st_sensors_spi_get_data_rdy_irq;
+ sdata->get_irq_event = st_sensors_spi_get_event_irq;
}
EXPORT_SYMBOL(st_sensors_spi_configure);
diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
index 07e27e4..428d02b 100644
--- a/include/linux/iio/common/st_sensors.h
+++ b/include/linux/iio/common/st_sensors.h
@@ -14,6 +14,7 @@
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/irqreturn.h>
+#include <linux/iio/events.h>
#include <linux/iio/trigger.h>
#include <linux/bitops.h>
@@ -24,6 +25,7 @@
#define ST_SENSORS_ODR_LIST_MAX 10
#define ST_SENSORS_FULLSCALE_AVL_MAX 10
+#define ST_SENSORS_EVENTS_MAX 10
#define ST_SENSORS_NUMBER_ALL_CHANNELS 4
#define ST_SENSORS_ENABLE_ALL_AXIS 0x07
@@ -44,14 +46,19 @@
#define ST_SENSORS_INT1 0
#define ST_SENSORS_INT2 1
+#define ST_SENSORS_LSM_EVENTS_MASK \
+ (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
+
#define ST_SENSORS_LSM_CHANNELS(device_type, mask, index, mod, \
- ch2, s, endian, rbits, sbits, addr) \
+ ch, s, endian, rbits, sbits, addr) \
{ \
.type = device_type, \
.modified = mod, \
.info_mask_separate = mask, \
.scan_index = index, \
- .channel2 = ch2, \
+ .channel = ch, \
+ .channel2 = ch, \
.address = addr, \
.scan_type = { \
.sign = s, \
@@ -111,6 +118,12 @@ struct st_sensor_fullscale {
struct st_sensor_fullscale_avl fs_avl[ST_SENSORS_FULLSCALE_AVL_MAX];
};
+struct st_sensor_register {
+ u8 addr;
+ u8 mask;
+ u8 val;
+};
+
/**
* struct st_sensor_bdu - ST sensor device block data update
* @addr: address of the register.
@@ -141,6 +154,47 @@ struct st_sensor_data_ready_irq {
};
/**
+ * struct st_sensor_event - event data.
+ * @bit: position of bit in status register related to event
+ * @chan: channel number.
+ * @chan_type: channel type.
+ * @modifier: modifier for the channel.
+ * @event_type: type of the event.
+ * @direction: direction of the event.
+ * @event_ths_reg: represents the threshold
+ * register of event.
+ */
+struct st_sensor_event {
+ u8 bit;
+ u8 chan;
+ enum iio_chan_type chan_type;
+ enum iio_modifier modifier;
+ enum iio_event_type event_type;
+ enum iio_event_direction direction;
+ struct st_sensor_register event_ths_reg;
+};
+
+/**
+ * struct st_sensor_event_irq -ST sensor event interrupt.
+ * @addr: address of the interrupt register.
+ * @mask: mask to write on/off value.
+ * @event_count: number of events declared in @events array.
+ * @ctrl_reg: represents the control register
+ * of event system
+ * @status_reg: status register of event subsystem.
+ * @events array: driver events declared by user
+ */
+struct st_sensor_event_irq {
+ u8 addr;
+ u8 mask;
+ u8 event_count;
+ struct st_sensor_register ctrl_reg;
+ struct st_sensor_register status_reg;
+ struct st_sensor_event events[ST_SENSORS_EVENTS_MAX];
+};
+
+
+/**
* struct st_sensor_transfer_buffer - ST sensor device I/O buffer
* @buf_lock: Mutex to protect rx and tx buffers.
* @tx_buf: Buffer used by SPI transfer function to send data to the sensors.
@@ -181,6 +235,7 @@ struct st_sensor_transfer_function {
* @fs: Full scale register and full scale list available.
* @bdu: Block data update register.
* @drdy_irq: Data ready register of the sensor.
+ * @event_irq: Event register of the sensor.
* @multi_read_bit: Use or not particular bit for [I2C/SPI] multi-read.
* @bootime: samples to discard when sensor passing from power-down to power-up.
*/
@@ -194,6 +249,7 @@ struct st_sensors {
struct st_sensor_fullscale fs;
struct st_sensor_bdu bdu;
struct st_sensor_data_ready_irq drdy_irq;
+ struct st_sensor_event_irq event_irq;
bool multi_read_bit;
unsigned int bootime;
};
@@ -209,9 +265,11 @@ struct st_sensors {
* @buffer_data: Data used by buffer part.
* @odr: Output data rate of the sensor [Hz].
* num_data_channels: Number of data channels used in buffer.
+ * @events_flag: Data used by event part.
* @irq_map: Container of mapped IRQs.
* @drdy_int_pin: Redirect DRDY on pin 1 (1) or pin 2 (2).
* @get_irq_data_ready: Function to get the IRQ used for data ready signal.
+ * @get_irq_event: Function to get the IRQ used for event signal.
* @tf: Transfer function structure used by I/O operations.
* @tb: Transfer buffers and mutex used by I/O operations.
*/
@@ -228,11 +286,13 @@ struct st_sensor_data {
unsigned int odr;
unsigned int num_data_channels;
+ unsigned int events_flag;
unsigned int irq_map[ST_SENSORS_INT_MAX];
u8 drdy_int_pin;
unsigned int (*get_irq_data_ready) (struct iio_dev *indio_dev);
+ unsigned int (*get_irq_event) (struct iio_dev *indio_dev);
const struct st_sensor_transfer_function *tf;
struct st_sensor_transfer_buffer tb;
@@ -292,4 +352,19 @@ ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
struct device_attribute *attr, char *buf);
+int st_sensors_read_event_config(struct iio_dev *indio_dev,
+ u64 event_code);
+
+int st_sensors_write_event_config(struct iio_dev *indio_dev,
+ u64 event_code, int state);
+
+int st_sensors_read_event_value(struct iio_dev *indio_dev,
+ u64 event_code, int *val);
+
+int st_sensors_write_event_value(struct iio_dev *indio_dev,
+ u64 event_code, int val);
+
+int st_sensors_request_event_irq(struct iio_dev *indio_dev);
+
+int st_sensors_enable_events(struct iio_dev *indio_dev);
#endif /* ST_SENSORS_H */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/4] iio: accel: Add event subsystem to st_accel driver
[not found] ` <1372767338-13179-1-git-send-email-l.czerwinski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2013-07-02 12:15 ` [PATCH 1/4] iio: st_sensors: Add DT bindings for st_accel and st_gyro Lukasz Czerwinski
2013-07-02 12:15 ` [PATCH 2/4] iio: st_sensors: Add threshold events support Lukasz Czerwinski
@ 2013-07-02 12:15 ` Lukasz Czerwinski
[not found] ` <1372767338-13179-4-git-send-email-l.czerwinski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2013-07-02 12:15 ` [PATCH 4/4] iio: lps331ap: Add support for DT Lukasz Czerwinski
3 siblings, 1 reply; 11+ messages in thread
From: Lukasz Czerwinski @ 2013-07-02 12:15 UTC (permalink / raw)
To: jic23-DgEjT+Ai2ygdnm+yROfE0A, denis.ciocca-qxv4g6HH51o
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Lukasz Czerwinski,
Kyungmin Park
This patch adds event support for iio st_accel driver.
Signed-off-by: Lukasz Czerwinski <l.czerwinski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
.../bindings/iio/accelerometer/st_accel.txt | 1 +
drivers/iio/accel/st_accel_core.c | 149 ++++++++++++++++++++
2 files changed, 150 insertions(+)
diff --git a/Documentation/devicetree/bindings/iio/accelerometer/st_accel.txt b/Documentation/devicetree/bindings/iio/accelerometer/st_accel.txt
index 9eab7d9..f461a77 100644
--- a/Documentation/devicetree/bindings/iio/accelerometer/st_accel.txt
+++ b/Documentation/devicetree/bindings/iio/accelerometer/st_accel.txt
@@ -21,6 +21,7 @@ Optional properties:
- interrupt-parent : phandle to the interrupt map subnode
- interrupts : interrupt mapping for st_accel interrupt sources:
0: INT1 irq_data_ready
+ 1: INT2 irq_event
- irq-map : irq sub-node defining interrupt map
(all properties listed below are required):
- #interrupt-cells : should be 1
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index 385cd86..983e8c4 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -19,6 +19,7 @@
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/iio/iio.h>
+#include <linux/iio/events.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/buffer.h>
@@ -68,6 +69,20 @@
#define ST_ACCEL_1_DRDY_IRQ_INT1_MASK 0x10
#define ST_ACCEL_1_DRDY_IRQ_INT2_MASK 0x08
#define ST_ACCEL_1_MULTIREAD_BIT true
+#define ST_ACCEL_1_EVENT_IRQ_ADDR 0x22
+#define ST_ACCEL_1_EVENT_IRQ_MASK 0x40
+#define ST_ACCEL_1_EVENT_CTRL_REG 0x30
+#define ST_ACCEL_1_EVENT_CTRL_MASK 0xc0
+#define ST_ACCEL_1_EVENT_CTRL_DEFAULT_VAL 0x01
+#define ST_ACCEL_1_THS_REG 0x32
+#define ST_ACCEL_1_EVENT_STATUS_REG 0x31
+#define ST_ACCEL_1_EVENT_STATUS_REG_MASK 0x7f
+#define ST_ACCEL_1_INT1_XL 0
+#define ST_ACCEL_1_INT1_XH 1
+#define ST_ACCEL_1_INT1_YL 2
+#define ST_ACCEL_1_INT1_YH 3
+#define ST_ACCEL_1_INT1_ZL 4
+#define ST_ACCEL_1_INT1_ZH 5
/* CUSTOM VALUES FOR SENSOR 2 */
#define ST_ACCEL_2_WAI_EXP 0x32
@@ -93,6 +108,20 @@
#define ST_ACCEL_2_DRDY_IRQ_INT1_MASK 0x02
#define ST_ACCEL_2_DRDY_IRQ_INT2_MASK 0x10
#define ST_ACCEL_2_MULTIREAD_BIT true
+#define ST_ACCEL_2_EVENT_IRQ_ADDR 0x22
+#define ST_ACCEL_2_EVENT_IRQ_MASK 0x01
+#define ST_ACCEL_2_EVENT_CTRL_REG 0x30
+#define ST_ACCEL_2_EVENT_CTRL_MASK 0xc0
+#define ST_ACCEL_2_EVENT_CTRL_DEFAULT_VAL 0x01
+#define ST_ACCEL_2_THS_REG 0x32
+#define ST_ACCEL_2_EVENT_STATUS_REG 0x31
+#define ST_ACCEL_2_EVENT_STATUS_REG_MASK 0x7f
+#define ST_ACCEL_2_INT1_XL 0
+#define ST_ACCEL_2_INT1_XH 1
+#define ST_ACCEL_2_INT1_YL 2
+#define ST_ACCEL_2_INT1_YH 3
+#define ST_ACCEL_2_INT1_ZL 4
+#define ST_ACCEL_2_INT1_ZH 5
/* CUSTOM VALUES FOR SENSOR 3 */
#define ST_ACCEL_3_WAI_EXP 0x40
@@ -129,6 +158,20 @@
#define ST_ACCEL_3_IG1_EN_MASK 0x08
#define ST_ACCEL_3_MULTIREAD_BIT false
+#define ST_SENSORS_LSM_ACCEL_EVENT(ch, mod, dir, bit_pos, ths_reg) \
+{ \
+ .bit = bit_pos,\
+ .chan = ch, \
+ .chan_type = IIO_ACCEL, \
+ .modifier = mod, \
+ .event_type = IIO_EV_TYPE_THRESH, \
+ .direction = dir, \
+ .event_ths_reg = { \
+ .addr = ths_reg, \
+ .mask = 0x7f, \
+ }, \
+}
+
static const struct iio_chan_spec st_accel_12bit_channels[] = {
ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
@@ -232,6 +275,46 @@ static const struct st_sensors st_accel_sensors[] = {
},
.multi_read_bit = ST_ACCEL_1_MULTIREAD_BIT,
.bootime = 2,
+ .event_irq = {
+ .addr = ST_ACCEL_1_EVENT_IRQ_ADDR,
+ .mask = ST_ACCEL_1_EVENT_IRQ_MASK,
+ .event_count = 6,
+ .ctrl_reg = {
+ .addr = ST_ACCEL_1_EVENT_CTRL_REG,
+ .mask = ST_ACCEL_1_EVENT_CTRL_MASK,
+ .val = ST_ACCEL_1_EVENT_CTRL_DEFAULT_VAL,
+ },
+ .status_reg = {
+ .addr = ST_ACCEL_1_EVENT_STATUS_REG,
+ .mask = ST_ACCEL_1_EVENT_STATUS_REG_MASK,
+ },
+ .events = {
+ ST_SENSORS_LSM_ACCEL_EVENT(0, IIO_MOD_X,
+ IIO_EV_DIR_FALLING,
+ ST_ACCEL_1_INT1_XL,
+ ST_ACCEL_1_THS_REG),
+ ST_SENSORS_LSM_ACCEL_EVENT(0, IIO_MOD_X,
+ IIO_EV_DIR_RISING,
+ ST_ACCEL_1_INT1_XH,
+ ST_ACCEL_1_THS_REG),
+ ST_SENSORS_LSM_ACCEL_EVENT(1, IIO_MOD_Y,
+ IIO_EV_DIR_FALLING,
+ ST_ACCEL_1_INT1_YL,
+ ST_ACCEL_1_THS_REG),
+ ST_SENSORS_LSM_ACCEL_EVENT(1, IIO_MOD_Y,
+ IIO_EV_DIR_RISING,
+ ST_ACCEL_1_INT1_YH,
+ ST_ACCEL_1_THS_REG),
+ ST_SENSORS_LSM_ACCEL_EVENT(2, IIO_MOD_Z,
+ IIO_EV_DIR_FALLING,
+ ST_ACCEL_1_INT1_ZL,
+ ST_ACCEL_1_THS_REG),
+ ST_SENSORS_LSM_ACCEL_EVENT(2, IIO_MOD_Z,
+ IIO_EV_DIR_RISING,
+ ST_ACCEL_1_INT1_ZH,
+ ST_ACCEL_1_THS_REG),
+ },
+ },
},
{
.wai = ST_ACCEL_2_WAI_EXP,
@@ -294,6 +377,47 @@ static const struct st_sensors st_accel_sensors[] = {
},
.multi_read_bit = ST_ACCEL_2_MULTIREAD_BIT,
.bootime = 2,
+ .event_irq = {
+ .addr = ST_ACCEL_2_EVENT_IRQ_ADDR,
+ .mask = ST_ACCEL_2_EVENT_IRQ_MASK,
+ .event_count = 6,
+ .ctrl_reg = {
+ .addr = ST_ACCEL_2_EVENT_CTRL_REG,
+ .mask = ST_ACCEL_2_EVENT_CTRL_MASK,
+ .val = ST_ACCEL_2_EVENT_CTRL_DEFAULT_VAL,
+ },
+ .status_reg = {
+ .addr = ST_ACCEL_2_EVENT_STATUS_REG,
+ .mask = ST_ACCEL_2_EVENT_STATUS_REG_MASK,
+ },
+ .events = {
+ ST_SENSORS_LSM_ACCEL_EVENT(0, IIO_MOD_X,
+ IIO_EV_DIR_FALLING,
+ ST_ACCEL_2_INT1_XL,
+ ST_ACCEL_2_THS_REG),
+ ST_SENSORS_LSM_ACCEL_EVENT(0, IIO_MOD_X,
+ IIO_EV_DIR_RISING,
+ ST_ACCEL_2_INT1_XH,
+ ST_ACCEL_2_THS_REG),
+ ST_SENSORS_LSM_ACCEL_EVENT(1, IIO_MOD_Y,
+ IIO_EV_DIR_FALLING,
+ ST_ACCEL_2_INT1_YL,
+ ST_ACCEL_2_THS_REG),
+ ST_SENSORS_LSM_ACCEL_EVENT(1, IIO_MOD_Y,
+ IIO_EV_DIR_RISING,
+ ST_ACCEL_2_INT1_YH,
+ ST_ACCEL_2_THS_REG),
+ ST_SENSORS_LSM_ACCEL_EVENT(2, IIO_MOD_Z,
+ IIO_EV_DIR_FALLING,
+ ST_ACCEL_2_INT1_ZL,
+ ST_ACCEL_2_THS_REG),
+ ST_SENSORS_LSM_ACCEL_EVENT(2, IIO_MOD_Z,
+ IIO_EV_DIR_RISING,
+ ST_ACCEL_2_INT1_ZH,
+ ST_ACCEL_2_THS_REG),
+ },
+ },
+
},
{
.wai = ST_ACCEL_3_WAI_EXP,
@@ -437,6 +561,10 @@ static const struct iio_info accel_info = {
.attrs = &st_accel_attribute_group,
.read_raw = &st_accel_read_raw,
.write_raw = &st_accel_write_raw,
+ .read_event_value = &st_sensors_read_event_value,
+ .write_event_value = &st_sensors_write_event_value,
+ .read_event_config = &st_sensors_read_event_config,
+ .write_event_config = &st_sensors_write_event_config,
};
#ifdef CONFIG_IIO_TRIGGER
@@ -452,6 +580,7 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
int st_accel_common_probe(struct iio_dev *indio_dev)
{
int err;
+ int i;
struct st_sensor_data *adata = iio_priv(indio_dev);
indio_dev->modes = INDIO_DIRECT_MODE;
@@ -489,6 +618,20 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
goto st_accel_probe_trigger_error;
}
+ if (adata->get_irq_event(indio_dev) > 0) {
+ err = st_sensors_request_event_irq(indio_dev);
+ if (err < 0)
+ goto st_accel_request_irq_event_error;
+
+ for (i = 0; i < indio_dev->num_channels; i++)
+ adata->sensor->ch[i].event_mask =
+ ST_SENSORS_LSM_EVENTS_MASK;
+
+ err = st_sensors_enable_events(indio_dev);
+ if (err < 0)
+ goto st_accel_enable_events_error;
+ }
+
err = iio_device_register(indio_dev);
if (err)
goto st_accel_device_register_error;
@@ -496,6 +639,10 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
return err;
st_accel_device_register_error:
+st_accel_enable_events_error:
+ if (adata->get_irq_event(indio_dev) > 0)
+ free_irq(adata->get_irq_event(indio_dev), indio_dev);
+st_accel_request_irq_event_error:
if (adata->get_irq_data_ready(indio_dev) > 0)
st_sensors_deallocate_trigger(indio_dev);
st_accel_probe_trigger_error:
@@ -515,6 +662,8 @@ void st_accel_common_remove(struct iio_dev *indio_dev)
st_sensors_deallocate_trigger(indio_dev);
st_accel_deallocate_ring(indio_dev);
}
+ if (adata->get_irq_event(indio_dev) > 0)
+ free_irq(adata->get_irq_event(indio_dev), indio_dev);
iio_device_free(indio_dev);
}
EXPORT_SYMBOL(st_accel_common_remove);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/4] iio: lps331ap: Add support for DT
[not found] ` <1372767338-13179-1-git-send-email-l.czerwinski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
` (2 preceding siblings ...)
2013-07-02 12:15 ` [PATCH 3/4] iio: accel: Add event subsystem to st_accel driver Lukasz Czerwinski
@ 2013-07-02 12:15 ` Lukasz Czerwinski
[not found] ` <1372767338-13179-5-git-send-email-l.czerwinski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
3 siblings, 1 reply; 11+ messages in thread
From: Lukasz Czerwinski @ 2013-07-02 12:15 UTC (permalink / raw)
To: jic23-DgEjT+Ai2ygdnm+yROfE0A, denis.ciocca-qxv4g6HH51o
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Jacek Anaszewski,
Kyungmin Park
From: Jacek Anaszewski <j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
This patch adds DT support for the lps331ap barometer
sensor.
Signed-off-by: Jacek Anaszewski <j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
.../bindings/iio/pressure/st_pressure.txt | 41 ++++++++++++++++++++
drivers/iio/pressure/st_pressure_i2c.c | 9 +++++
drivers/iio/pressure/st_pressure_spi.c | 9 +++++
3 files changed, 59 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/pressure/st_pressure.txt
diff --git a/Documentation/devicetree/bindings/iio/pressure/st_pressure.txt b/Documentation/devicetree/bindings/iio/pressure/st_pressure.txt
new file mode 100644
index 0000000..73a4b7d
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/pressure/st_pressure.txt
@@ -0,0 +1,41 @@
+* STMicroelectronics LPS331AP barometer sensor
+
+Required properties:
+
+ - compatible : should be "lps331ap"
+ - reg : the I2C address of the barometer
+
+Optional properties:
+
+ - drdy-int-pin : redirect DRDY on pin INT1 (1) or pin INT2 (2) (u8)
+ - interrupt-parent : phandle to the interrupt map subnode
+ - interrupts : interrupt mapping for LPS331AP interrupt sources:
+ 2 sources: 0 - INT1, 1 - INT2
+ - irq-map : irq sub-node defining interrupt map
+ (all properties listed below are required):
+ - #interrupt-cells : should be 1
+ - #address-cells : should be 0
+ - #size-cells : should be 0
+ - interrupt-map : table of entries consisting of three child elements:
+ - unit_interrupt_specifier - 0 : INT1, 1 : INT2
+ - interrupt parent phandle
+ - parent unit interrupt specifier consisiting of two elements:
+ - index of the interrupt within the controller
+ - flags : should be 0
+
+Example:
+
+lps331ap@5d {
+ compatible = "lps331ap";
+ reg = <0x5d>;
+ drdy-int-pin = /bits/ 8 <2>;
+ interrupt-parent = <&irq_map>;
+ interrupts = <0>, <1>;
+
+ irq_map: irq-map {
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = <0 &gpf0 5 0>;
+ };
+};
diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c
index 7cebcc7..a1ad3cf 100644
--- a/drivers/iio/pressure/st_pressure_i2c.c
+++ b/drivers/iio/pressure/st_pressure_i2c.c
@@ -61,10 +61,19 @@ static const struct i2c_device_id st_press_id_table[] = {
};
MODULE_DEVICE_TABLE(i2c, st_press_id_table);
+#ifdef CONFIG_OF
+static const struct of_device_id lps331ap_of_match[] = {
+ { .compatible = LPS331AP_PRESS_DEV_NAME, },
+ { }
+};
+MODULE_DEVICE_TABLE(of, lps331ap_of_match);
+#endif
+
static struct i2c_driver st_press_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "st-press-i2c",
+ .of_match_table = of_match_ptr(lps331ap_of_match),
},
.probe = st_press_i2c_probe,
.remove = st_press_i2c_remove,
diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c
index 17a1490..e49269d 100644
--- a/drivers/iio/pressure/st_pressure_spi.c
+++ b/drivers/iio/pressure/st_pressure_spi.c
@@ -60,10 +60,19 @@ static const struct spi_device_id st_press_id_table[] = {
};
MODULE_DEVICE_TABLE(spi, st_press_id_table);
+#ifdef CONFIG_OF
+static const struct of_device_id lps331ap_of_match[] = {
+ { .compatible = LPS331AP_PRESS_DEV_NAME, },
+ { }
+};
+MODULE_DEVICE_TABLE(of, lps331ap_of_match);
+#endif
+
static struct spi_driver st_press_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "st-press-spi",
+ .of_match_table = of_match_ptr(lps331ap_of_match),
},
.probe = st_press_spi_probe,
.remove = st_press_spi_remove,
--
1.7.9.5
^ permalink raw reply related [flat|nested] 11+ messages in thread