lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 13 Apr 2016 22:01:51 +0300
From:	Crestez Dan Leonard <leonard.crestez@...el.com>
To:	Jonathan Cameron <jic23@...nel.org>, linux-iio@...r.kernel.org,
	Giuseppe Barba <giuseppe.barba@...com>,
	Denis Ciocca <denis.ciocca@...com>
Cc:	linux-kernel@...r.kernel.org, Hartmut Knaack <knaack.h@....de>,
	Lars-Peter Clausen <lars@...afoo.de>,
	Peter Meerwald-Stadler <pmeerw@...erw.net>,
	Daniel Baluta <daniel.baluta@...el.com>,
	Crestez Dan Leonard <leonard.crestez@...el.com>
Subject: [RFC] iio: st: Add lsm9ds0 support for gyro accel and magn

Device is an integrated gyro/accel/magn and temperature sensor. The
device has two i2c/spi interfaces: one for the gyro and one for the
accel/magn/temp sensor.

Datasheet: http://www2.st.com/resource/en/datasheet/lsm9ds0.pdf

The patch uses existing iio st_sensor infrastructure and just adds a
bunch of new device IDs and the new register mappings.

Temperature support is not included.

Signed-off-by: Crestez Dan Leonard <leonard.crestez@...el.com>
---

I tested basic reading of values using software triggers and i2c and the values
seems plausible.

I tested lsm9ds0-accel and lsm9ds0-magn separately because I don't know how to
instantiate two iio drivers for the same I2C device using devicetree. Can you
provide a sample of this or is this not currently supported?

It seems to me that the LSM303AGR device has the same problem: it's an
accel+magn combo behind a single I2C address. How is that supposed to be
instantiated? Other supported combo devices seem to have multiple I2C
addresses.

It's also not clear how to properly deal with bits shared between the accel and
magn part like "block data update" or "interrupt polarity".

 .../devicetree/bindings/iio/st-sensors.txt         |   3 +
 drivers/iio/accel/st_accel.h                       |   1 +
 drivers/iio/accel/st_accel_core.c                  | 122 ++++++++++++++++++++
 drivers/iio/accel/st_accel_i2c.c                   |   5 +
 drivers/iio/accel/st_accel_spi.c                   |   1 +
 drivers/iio/gyro/st_gyro.h                         |   1 +
 drivers/iio/gyro/st_gyro_core.c                    |   1 +
 drivers/iio/gyro/st_gyro_i2c.c                     |   5 +
 drivers/iio/gyro/st_gyro_spi.c                     |   1 +
 drivers/iio/magnetometer/st_magn.h                 |   1 +
 drivers/iio/magnetometer/st_magn_core.c            | 123 +++++++++++++++++++++
 drivers/iio/magnetometer/st_magn_i2c.c             |   5 +
 drivers/iio/magnetometer/st_magn_spi.c             |   1 +
 13 files changed, 270 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/st-sensors.txt b/Documentation/devicetree/bindings/iio/st-sensors.txt
index 71b7bdf..65339ef 100644
--- a/Documentation/devicetree/bindings/iio/st-sensors.txt
+++ b/Documentation/devicetree/bindings/iio/st-sensors.txt
@@ -38,6 +38,7 @@ Accelerometers:
 - st,lsm303agr-accel
 - st,lis2dh12-accel
 - st,h3lis331dl-accel
+- st,lsm9ds0-accel
 
 Gyroscopes:
 - st,l3g4200d-gyro
@@ -47,6 +48,7 @@ Gyroscopes:
 - st,l3gd20-gyro
 - st,l3g4is-gyro
 - st,lsm330-gyro
+- st,lsm9ds0-gyro
 
 Magnetometers:
 - st,lsm303agr-magn
@@ -54,6 +56,7 @@ Magnetometers:
 - st,lsm303dlhc-magn
 - st,lsm303dlm-magn
 - st,lis3mdl-magn
+- st,lsm9ds0-magn
 
 Pressure sensors:
 - st,lps001wp-press
diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h
index 57f83a6..e90cd6a 100644
--- a/drivers/iio/accel/st_accel.h
+++ b/drivers/iio/accel/st_accel.h
@@ -29,6 +29,7 @@
 #define LSM330_ACCEL_DEV_NAME		"lsm330_accel"
 #define LSM303AGR_ACCEL_DEV_NAME	"lsm303agr_accel"
 #define LIS2DH12_ACCEL_DEV_NAME		"lis2dh12_accel"
+#define LSM9DS0_ACCEL_DEV_NAME		"lsm9ds0_accel"
 
 /**
 * struct st_sensors_platform_data - default accel platform data
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index fee32e3..0941b46 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -211,6 +211,50 @@
 #define ST_ACCEL_6_IHL_IRQ_MASK			0x80
 #define ST_ACCEL_6_MULTIREAD_BIT		true
 
+/* CUSTOM VALUES FOR SENSOR 7 */
+#define ST_ACCEL_7_WAI_EXP			0x49
+#define ST_ACCEL_7_ODR_ADDR			0x20
+#define ST_ACCEL_7_ODR_MASK			0xf0
+#define ST_ACCEL_7_ODR_AVL_3HZ_VAL		0x01
+#define ST_ACCEL_7_ODR_AVL_6HZ_VAL		0x02
+#define ST_ACCEL_7_ODR_AVL_12HZ_VAL		0x03
+#define ST_ACCEL_7_ODR_AVL_25HZ_VAL		0x04
+#define ST_ACCEL_7_ODR_AVL_50HZ_VAL		0x05
+#define ST_ACCEL_7_ODR_AVL_100HZ_VAL		0x06
+#define ST_ACCEL_7_ODR_AVL_200HZ_VAL		0x07
+#define ST_ACCEL_7_ODR_AVL_400HZ_VAL		0x08
+#define ST_ACCEL_7_ODR_AVL_800HZ_VAL		0x09
+#define ST_ACCEL_7_ODR_AVL_1600HZ_VAL		0x0a
+#define ST_ACCEL_7_FS_ADDR			0x21
+#define ST_ACCEL_7_FS_MASK			0x38
+#define ST_ACCEL_7_FS_AVL_2_VAL			0x00
+#define ST_ACCEL_7_FS_AVL_4_VAL			0x01
+#define ST_ACCEL_7_FS_AVL_6_VAL			0x02
+#define ST_ACCEL_7_FS_AVL_8_VAL			0x03
+#define ST_ACCEL_7_FS_AVL_16_VAL		0x04
+#define ST_ACCEL_7_FS_AVL_2_GAIN		IIO_G_TO_M_S_2(61)
+#define ST_ACCEL_7_FS_AVL_4_GAIN		IIO_G_TO_M_S_2(122)
+#define ST_ACCEL_7_FS_AVL_6_GAIN		IIO_G_TO_M_S_2(183)
+#define ST_ACCEL_7_FS_AVL_8_GAIN		IIO_G_TO_M_S_2(244)
+#define ST_ACCEL_7_FS_AVL_16_GAIN		IIO_G_TO_M_S_2(732)
+#define ST_ACCEL_7_BDU_ADDR			0x20
+#define ST_ACCEL_7_BDU_MASK			0x08
+#define ST_ACCEL_7_DRDY_IRQ_ADDR		0x22
+#define ST_ACCEL_7_DRDY_IRQ_INT1_MASK		0x04
+/* INT2 is actually at another address. Not supported by driver */
+/*
+#define ST_ACCEL_7_DRDY_IRQ_INT2_ADDR		0x23
+#define ST_ACCEL_7_DRDY_IRQ_INT2_MASK		0x08
+ */
+/* Common to magnetometer so not supported */
+/*
+#define ST_ACCEL_7_IHL_IRQ_ADDR			0x12
+#define ST_ACCEL_7_IHL_IRQ_MASK			0x80
+ */
+#define ST_ACCEL_7_IG1_EN_ADDR			0x22
+#define ST_ACCEL_7_IG1_EN_MASK			0x20
+#define ST_ACCEL_7_MULTIREAD_BIT		true
+
 static const struct iio_chan_spec st_accel_8bit_channels[] = {
 	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
@@ -649,6 +693,84 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
 		.multi_read_bit = ST_ACCEL_6_MULTIREAD_BIT,
 		.bootime = 2,
 	},
+	{
+		.wai = ST_ACCEL_7_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
+		.sensors_supported = {
+			[0] = LSM9DS0_ACCEL_DEV_NAME,
+		},
+		.ch = (struct iio_chan_spec *)st_accel_16bit_channels,
+		.odr = {
+			.addr = ST_ACCEL_7_ODR_ADDR,
+			.mask = ST_ACCEL_7_ODR_MASK,
+			.odr_avl = {
+				{ 3, ST_ACCEL_7_ODR_AVL_3HZ_VAL },
+				{ 6, ST_ACCEL_7_ODR_AVL_6HZ_VAL, },
+				{ 12, ST_ACCEL_7_ODR_AVL_12HZ_VAL, },
+				{ 25, ST_ACCEL_7_ODR_AVL_25HZ_VAL, },
+				{ 50, ST_ACCEL_7_ODR_AVL_50HZ_VAL, },
+				{ 100, ST_ACCEL_7_ODR_AVL_100HZ_VAL, },
+				{ 200, ST_ACCEL_7_ODR_AVL_200HZ_VAL, },
+				{ 400, ST_ACCEL_7_ODR_AVL_400HZ_VAL, },
+				{ 800, ST_ACCEL_7_ODR_AVL_800HZ_VAL, },
+				{ 1600, ST_ACCEL_7_ODR_AVL_1600HZ_VAL, },
+			},
+		},
+		.pw = {
+			.addr = ST_ACCEL_7_ODR_ADDR,
+			.mask = ST_ACCEL_7_ODR_MASK,
+			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+		},
+		.enable_axis = {
+			.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
+			.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
+		},
+		.fs = {
+			.addr = ST_ACCEL_7_FS_ADDR,
+			.mask = ST_ACCEL_7_FS_MASK,
+			.fs_avl = {
+				[0] = {
+					.num = ST_ACCEL_FS_AVL_2G,
+					.value = ST_ACCEL_7_FS_AVL_2_VAL,
+					.gain = ST_ACCEL_7_FS_AVL_2_GAIN,
+				},
+				[1] = {
+					.num = ST_ACCEL_FS_AVL_4G,
+					.value = ST_ACCEL_7_FS_AVL_4_VAL,
+					.gain = ST_ACCEL_7_FS_AVL_4_GAIN,
+				},
+				[2] = {
+					.num = ST_ACCEL_FS_AVL_6G,
+					.value = ST_ACCEL_7_FS_AVL_6_VAL,
+					.gain = ST_ACCEL_7_FS_AVL_6_GAIN,
+				},
+				[3] = {
+					.num = ST_ACCEL_FS_AVL_8G,
+					.value = ST_ACCEL_7_FS_AVL_8_VAL,
+					.gain = ST_ACCEL_7_FS_AVL_8_GAIN,
+				},
+				[4] = {
+					.num = ST_ACCEL_FS_AVL_16G,
+					.value = ST_ACCEL_7_FS_AVL_16_VAL,
+					.gain = ST_ACCEL_7_FS_AVL_16_GAIN,
+				},
+			},
+		},
+		.bdu = {
+			.addr = ST_ACCEL_7_BDU_ADDR,
+			.mask = ST_ACCEL_7_BDU_MASK,
+		},
+		.drdy_irq = {
+			.addr = ST_ACCEL_7_DRDY_IRQ_ADDR,
+			.mask_int1 = ST_ACCEL_7_DRDY_IRQ_INT1_MASK,
+			.ig1 = {
+				.en_addr = ST_ACCEL_7_IG1_EN_ADDR,
+				.en_mask = ST_ACCEL_7_IG1_EN_MASK,
+			},
+		},
+		.multi_read_bit = ST_ACCEL_7_MULTIREAD_BIT,
+		.bootime = 2,
+	},
 };
 
 static int st_accel_read_raw(struct iio_dev *indio_dev,
diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c
index 7333ee9..7a2a3ab 100644
--- a/drivers/iio/accel/st_accel_i2c.c
+++ b/drivers/iio/accel/st_accel_i2c.c
@@ -80,6 +80,10 @@ static const struct of_device_id st_accel_of_match[] = {
 		.compatible = "st,h3lis331dl-accel",
 		.data = H3LIS331DL_DRIVER_NAME,
 	},
+	{
+		.compatible = "st,lsm9ds0-accel",
+		.data = LSM9DS0_ACCEL_DEV_NAME,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, st_accel_of_match);
@@ -130,6 +134,7 @@ static const struct i2c_device_id st_accel_id_table[] = {
 	{ LSM330_ACCEL_DEV_NAME },
 	{ LSM303AGR_ACCEL_DEV_NAME },
 	{ LIS2DH12_ACCEL_DEV_NAME },
+	{ LSM9DS0_ACCEL_DEV_NAME },
 	{},
 };
 MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c
index fcd5847..2fc32c92f 100644
--- a/drivers/iio/accel/st_accel_spi.c
+++ b/drivers/iio/accel/st_accel_spi.c
@@ -59,6 +59,7 @@ static const struct spi_device_id st_accel_id_table[] = {
 	{ LSM330_ACCEL_DEV_NAME },
 	{ LSM303AGR_ACCEL_DEV_NAME },
 	{ LIS2DH12_ACCEL_DEV_NAME },
+	{ LSM9DS0_ACCEL_DEV_NAME },
 	{},
 };
 MODULE_DEVICE_TABLE(spi, st_accel_id_table);
diff --git a/drivers/iio/gyro/st_gyro.h b/drivers/iio/gyro/st_gyro.h
index 5353d63..a5c5c4e 100644
--- a/drivers/iio/gyro/st_gyro.h
+++ b/drivers/iio/gyro/st_gyro.h
@@ -21,6 +21,7 @@
 #define L3GD20_GYRO_DEV_NAME		"l3gd20"
 #define L3G4IS_GYRO_DEV_NAME		"l3g4is_ui"
 #define LSM330_GYRO_DEV_NAME		"lsm330_gyro"
+#define LSM9DS0_GYRO_DEV_NAME		"lsm9ds0_gyro"
 
 /**
  * struct st_sensors_platform_data - gyro platform data
diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c
index 110f95b..9589ba9 100644
--- a/drivers/iio/gyro/st_gyro_core.c
+++ b/drivers/iio/gyro/st_gyro_core.c
@@ -203,6 +203,7 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = {
 			[2] = LSM330DLC_GYRO_DEV_NAME,
 			[3] = L3G4IS_GYRO_DEV_NAME,
 			[4] = LSM330_GYRO_DEV_NAME,
+			[5] = LSM9DS0_GYRO_DEV_NAME,
 		},
 		.ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
 		.odr = {
diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c
index 6848451..40056b8 100644
--- a/drivers/iio/gyro/st_gyro_i2c.c
+++ b/drivers/iio/gyro/st_gyro_i2c.c
@@ -48,6 +48,10 @@ static const struct of_device_id st_gyro_of_match[] = {
 		.compatible = "st,lsm330-gyro",
 		.data = LSM330_GYRO_DEV_NAME,
 	},
+	{
+		.compatible = "st,lsm9ds0-gyro",
+		.data = LSM9DS0_GYRO_DEV_NAME,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, st_gyro_of_match);
@@ -93,6 +97,7 @@ static const struct i2c_device_id st_gyro_id_table[] = {
 	{ L3GD20_GYRO_DEV_NAME },
 	{ L3G4IS_GYRO_DEV_NAME },
 	{ LSM330_GYRO_DEV_NAME },
+	{ LSM9DS0_GYRO_DEV_NAME },
 	{},
 };
 MODULE_DEVICE_TABLE(i2c, st_gyro_id_table);
diff --git a/drivers/iio/gyro/st_gyro_spi.c b/drivers/iio/gyro/st_gyro_spi.c
index d2b7a5f..fbf2fae 100644
--- a/drivers/iio/gyro/st_gyro_spi.c
+++ b/drivers/iio/gyro/st_gyro_spi.c
@@ -54,6 +54,7 @@ static const struct spi_device_id st_gyro_id_table[] = {
 	{ L3GD20_GYRO_DEV_NAME },
 	{ L3G4IS_GYRO_DEV_NAME },
 	{ LSM330_GYRO_DEV_NAME },
+	{ LSM9DS0_GYRO_DEV_NAME },
 	{},
 };
 MODULE_DEVICE_TABLE(spi, st_gyro_id_table);
diff --git a/drivers/iio/magnetometer/st_magn.h b/drivers/iio/magnetometer/st_magn.h
index 06a4d9c..2176064 100644
--- a/drivers/iio/magnetometer/st_magn.h
+++ b/drivers/iio/magnetometer/st_magn.h
@@ -19,6 +19,7 @@
 #define LSM303DLM_MAGN_DEV_NAME		"lsm303dlm_magn"
 #define LIS3MDL_MAGN_DEV_NAME		"lis3mdl"
 #define LSM303AGR_MAGN_DEV_NAME		"lsm303agr_magn"
+#define LSM9DS0_MAGN_DEV_NAME		"lsm9ds0_magn"
 
 int st_magn_common_probe(struct iio_dev *indio_dev);
 void st_magn_common_remove(struct iio_dev *indio_dev);
diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c
index 501f858..da3f29a 100644
--- a/drivers/iio/magnetometer/st_magn_core.c
+++ b/drivers/iio/magnetometer/st_magn_core.c
@@ -36,6 +36,7 @@
 /* FULLSCALE */
 #define ST_MAGN_FS_AVL_1300MG			1300
 #define ST_MAGN_FS_AVL_1900MG			1900
+#define ST_MAGN_FS_AVL_2000MG			2000
 #define ST_MAGN_FS_AVL_2500MG			2500
 #define ST_MAGN_FS_AVL_4000MG			4000
 #define ST_MAGN_FS_AVL_4700MG			4700
@@ -183,6 +184,50 @@
 #define ST_MAGN_3_OUT_Y_L_ADDR			0x6a
 #define ST_MAGN_3_OUT_Z_L_ADDR			0x6c
 
+/* CUSTOM VALUES FOR SENSOR 4 */
+#define ST_MAGN_4_WAI_EXP			0x49
+#define ST_MAGN_4_ODR_ADDR			0x24
+#define ST_MAGN_4_ODR_MASK			0x1c
+#define ST_MAGN_4_ODR_AVL_3HZ_VAL		0x00
+#define ST_MAGN_4_ODR_AVL_6HZ_VAL		0x01
+#define ST_MAGN_4_ODR_AVL_12HZ_VAL		0x02
+#define ST_MAGN_4_ODR_AVL_25HZ_VAL		0x03
+#define ST_MAGN_4_ODR_AVL_50HZ_VAL		0x04
+#define ST_MAGN_4_ODR_AVL_100HZ_VAL		0x05
+#define ST_MAGN_4_PW_ADDR			0x26
+#define ST_MAGN_4_PW_MASK			0x03
+#define ST_MAGN_4_PW_ON				0x00
+#define ST_MAGN_4_PW_OFF			0x03
+#define ST_MAGN_4_FS_ADDR			0x25
+#define ST_MAGN_4_FS_MASK			0x60
+#define ST_MAGN_4_FS_AVL_2000_VAL		0x00
+#define ST_MAGN_4_FS_AVL_4000_VAL		0x01
+#define ST_MAGN_4_FS_AVL_8000_VAL		0x02
+#define ST_MAGN_4_FS_AVL_12000_VAL		0x03
+#define ST_MAGN_4_FS_AVL_2000_GAIN		73
+#define ST_MAGN_4_FS_AVL_4000_GAIN		146
+#define ST_MAGN_4_FS_AVL_8000_GAIN		292
+#define ST_MAGN_4_FS_AVL_12000_GAIN		438
+/* Shared with accelerometer */
+#define ST_MAGN_4_BDU_ADDR			0x20
+#define ST_MAGN_4_BDU_MASK			0x08
+#define ST_MAGN_4_DRDY_IRQ_ADDR			0x22
+#define ST_MAGN_4_DRDY_INT_MASK			0x01
+/* INT2 is actually at another address. Not supported by driver */
+/*
+#define ST_MAGN_4_DRDY_IRQ_INT2_ADDR		0x23
+#define ST_MAGN_4_DRDY_IRQ_INT2_MASK		0x04
+ */
+/* Common to accelerometer so not supported */
+/*
+#define ST_MAGN_4_IHL_IRQ_ADDR			0x12
+#define ST_MAGN_4_IHL_IRQ_MASK			0x80
+ */
+#define ST_MAGN_4_MULTIREAD_BIT			true
+#define ST_MAGN_4_OUT_X_L_ADDR			0x08
+#define ST_MAGN_4_OUT_Y_L_ADDR			0x0a
+#define ST_MAGN_4_OUT_Z_L_ADDR			0x0c
+
 static const struct iio_chan_spec st_magn_16bit_channels[] = {
 	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
@@ -231,6 +276,22 @@ static const struct iio_chan_spec st_magn_3_16bit_channels[] = {
 	IIO_CHAN_SOFT_TIMESTAMP(3)
 };
 
+static const struct iio_chan_spec st_magn_4_16bit_channels[] = {
+	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
+			ST_MAGN_4_OUT_X_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
+			ST_MAGN_4_OUT_Y_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
+			ST_MAGN_4_OUT_Z_L_ADDR),
+	IIO_CHAN_SOFT_TIMESTAMP(3)
+};
+
 static const struct st_sensor_settings st_magn_sensors_settings[] = {
 	{
 		.wai = 0, /* This sensor has no valid WhoAmI report 0 */
@@ -488,6 +549,68 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = {
 		.multi_read_bit = ST_MAGN_3_MULTIREAD_BIT,
 		.bootime = 2,
 	},
+	{
+		.wai = ST_MAGN_4_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
+		.sensors_supported = {
+			[0] = LSM9DS0_MAGN_DEV_NAME,
+		},
+		.ch = (struct iio_chan_spec *)st_magn_4_16bit_channels,
+		.odr = {
+			.addr = ST_MAGN_4_ODR_ADDR,
+			.mask = ST_MAGN_4_ODR_MASK,
+			.odr_avl = {
+				{ 3, ST_MAGN_4_ODR_AVL_3HZ_VAL, },
+				{ 6, ST_MAGN_4_ODR_AVL_6HZ_VAL, },
+				{ 12, ST_MAGN_4_ODR_AVL_12HZ_VAL, },
+				{ 25, ST_MAGN_4_ODR_AVL_25HZ_VAL, },
+				{ 50, ST_MAGN_4_ODR_AVL_50HZ_VAL, },
+				{ 100, ST_MAGN_4_ODR_AVL_100HZ_VAL, },
+			},
+		},
+		.pw = {
+			.addr = ST_MAGN_4_PW_ADDR,
+			.mask = ST_MAGN_4_PW_MASK,
+			.value_on = ST_MAGN_4_PW_ON,
+			.value_off = ST_MAGN_4_PW_OFF,
+		},
+		.fs = {
+			.addr = ST_MAGN_4_FS_ADDR,
+			.mask = ST_MAGN_4_FS_MASK,
+			.fs_avl = {
+				[0] = {
+					.num = ST_MAGN_FS_AVL_2000MG,
+					.value = ST_MAGN_4_FS_AVL_2000_VAL,
+					.gain = ST_MAGN_4_FS_AVL_2000_GAIN,
+				},
+				[1] = {
+					.num = ST_MAGN_FS_AVL_4000MG,
+					.value = ST_MAGN_4_FS_AVL_4000_VAL,
+					.gain = ST_MAGN_4_FS_AVL_4000_GAIN,
+				},
+				[2] = {
+					.num = ST_MAGN_FS_AVL_8000MG,
+					.value = ST_MAGN_4_FS_AVL_8000_VAL,
+					.gain = ST_MAGN_4_FS_AVL_8000_GAIN,
+				},
+				[3] = {
+					.num = ST_MAGN_FS_AVL_12000MG,
+					.value = ST_MAGN_4_FS_AVL_12000_VAL,
+					.gain = ST_MAGN_4_FS_AVL_12000_GAIN,
+				},
+			},
+		},
+		.bdu = {
+			.addr = ST_MAGN_4_BDU_ADDR,
+			.mask = ST_MAGN_4_BDU_MASK,
+		},
+		.drdy_irq = {
+			.addr = ST_MAGN_4_DRDY_IRQ_ADDR,
+			.mask_int1 = ST_MAGN_4_DRDY_INT_MASK,
+		},
+		.multi_read_bit = ST_MAGN_4_MULTIREAD_BIT,
+		.bootime = 2,
+	},
 };
 
 static int st_magn_read_raw(struct iio_dev *indio_dev,
diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c
index 8aa37af..1c7c487 100644
--- a/drivers/iio/magnetometer/st_magn_i2c.c
+++ b/drivers/iio/magnetometer/st_magn_i2c.c
@@ -40,6 +40,10 @@ static const struct of_device_id st_magn_of_match[] = {
 		.compatible = "st,lsm303agr-magn",
 		.data = LSM303AGR_MAGN_DEV_NAME,
 	},
+	{
+		.compatible = "st,lsm9ds0-magn",
+		.data = LSM9DS0_MAGN_DEV_NAME,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, st_magn_of_match);
@@ -84,6 +88,7 @@ static const struct i2c_device_id st_magn_id_table[] = {
 	{ LSM303DLM_MAGN_DEV_NAME },
 	{ LIS3MDL_MAGN_DEV_NAME },
 	{ LSM303AGR_MAGN_DEV_NAME },
+	{ LSM9DS0_MAGN_DEV_NAME },
 	{},
 };
 MODULE_DEVICE_TABLE(i2c, st_magn_id_table);
diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c
index 6325e7d..8c4e1d6 100644
--- a/drivers/iio/magnetometer/st_magn_spi.c
+++ b/drivers/iio/magnetometer/st_magn_spi.c
@@ -52,6 +52,7 @@ static const struct spi_device_id st_magn_id_table[] = {
 	{ LSM303DLM_MAGN_DEV_NAME },
 	{ LIS3MDL_MAGN_DEV_NAME },
 	{ LSM303AGR_MAGN_DEV_NAME },
+	{ LSM9DS0_MAGN_DEV_NAME },
 	{},
 };
 MODULE_DEVICE_TABLE(spi, st_magn_id_table);
-- 
2.5.5

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ