All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Add MPU9150 magnetometer support
@ 2019-11-15 14:06 Jean-Baptiste Maneyrol
  2019-11-15 14:06 ` [PATCH 1/2] iio: imu: inv_mpu6050: delete not existing MPU9150 spi support Jean-Baptiste Maneyrol
  2019-11-15 14:06 ` [PATCH 2/2] iio: imu: inv_mpu6050: add support of MPU9150 magnetometer Jean-Baptiste Maneyrol
  0 siblings, 2 replies; 5+ messages in thread
From: Jean-Baptiste Maneyrol @ 2019-11-15 14:06 UTC (permalink / raw)
  To: jic23; +Cc: linux-iio, Jean-Baptiste Maneyrol

WARNING: this patch series apply on top of linux-next master branch. It requires
both MPU925x magnetometer support and the fix no data on MPU6050.

This series adds support of driving MPU9150 magnetometer (AK8975) from MPU6050.

Jean-Baptiste Maneyrol (2):
  iio: imu: inv_mpu6050: delete not existing MPU9150 spi support
  iio: imu: inv_mpu6050: add support of MPU9150 magnetometer

 drivers/iio/imu/inv_mpu6050/Kconfig           |  6 +-
 drivers/iio/imu/inv_mpu6050/inv_mpu_core.c    | 57 ++++++++++---
 drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c     |  2 +
 drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c    | 80 +++++++++++++------
 drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c     |  1 -
 drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c |  1 +
 6 files changed, 107 insertions(+), 40 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] iio: imu: inv_mpu6050: delete not existing MPU9150 spi support
  2019-11-15 14:06 [PATCH 0/2] Add MPU9150 magnetometer support Jean-Baptiste Maneyrol
@ 2019-11-15 14:06 ` Jean-Baptiste Maneyrol
  2019-11-16 17:16   ` Jonathan Cameron
  2019-11-15 14:06 ` [PATCH 2/2] iio: imu: inv_mpu6050: add support of MPU9150 magnetometer Jean-Baptiste Maneyrol
  1 sibling, 1 reply; 5+ messages in thread
From: Jean-Baptiste Maneyrol @ 2019-11-15 14:06 UTC (permalink / raw)
  To: jic23; +Cc: linux-iio, Jean-Baptiste Maneyrol

MPU9150 is i2c only.
Update Kconfig to delete in description chips that are i2c or
spi only.

Signed-off-by: Jean-Baptiste Maneyrol <jmaneyrol@invensense.com>
---
 drivers/iio/imu/inv_mpu6050/Kconfig       | 6 +++---
 drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 1 -
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
index e4c4c12236a7..963a0cafe0cb 100644
--- a/drivers/iio/imu/inv_mpu6050/Kconfig
+++ b/drivers/iio/imu/inv_mpu6050/Kconfig
@@ -14,7 +14,7 @@ config INV_MPU6050_I2C
 	select INV_MPU6050_IIO
 	select REGMAP_I2C
 	help
-	  This driver supports the Invensense MPU6000/6050/6500/6515,
+	  This driver supports the Invensense MPU6050/6500/6515,
 	  MPU9150/9250/9255 and ICM20608/20602 motion tracking devices
 	  over I2C.
 	  This driver can be built as a module. The module will be called
@@ -26,8 +26,8 @@ config INV_MPU6050_SPI
 	select INV_MPU6050_IIO
 	select REGMAP_SPI
 	help
-	  This driver supports the Invensense MPU6000/6050/6500/6515,
-	  MPU9150/9250/9255 and ICM20608/20602 motion tracking devices
+	  This driver supports the Invensense MPU6000/6500/6515,
+	  MPU9250/9255 and ICM20608/20602 motion tracking devices
 	  over SPI.
 	  This driver can be built as a module. The module will be called
 	  inv-mpu6050-spi.
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
index 142692fc0758..ec102d5a5c77 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
@@ -74,7 +74,6 @@ static int inv_mpu_probe(struct spi_device *spi)
 static const struct spi_device_id inv_mpu_id[] = {
 	{"mpu6000", INV_MPU6000},
 	{"mpu6500", INV_MPU6500},
-	{"mpu9150", INV_MPU9150},
 	{"mpu9250", INV_MPU9250},
 	{"mpu9255", INV_MPU9255},
 	{"icm20608", INV_ICM20608},
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] iio: imu: inv_mpu6050: add support of MPU9150 magnetometer
  2019-11-15 14:06 [PATCH 0/2] Add MPU9150 magnetometer support Jean-Baptiste Maneyrol
  2019-11-15 14:06 ` [PATCH 1/2] iio: imu: inv_mpu6050: delete not existing MPU9150 spi support Jean-Baptiste Maneyrol
@ 2019-11-15 14:06 ` Jean-Baptiste Maneyrol
  2019-11-16 17:20   ` Jonathan Cameron
  1 sibling, 1 reply; 5+ messages in thread
From: Jean-Baptiste Maneyrol @ 2019-11-15 14:06 UTC (permalink / raw)
  To: jic23; +Cc: linux-iio, Jean-Baptiste Maneyrol

Add support for driving MPU9150 magnetometer (AK8975) from mpu.

Signed-off-by: Jean-Baptiste Maneyrol <jmaneyrol@invensense.com>
---
 drivers/iio/imu/inv_mpu6050/inv_mpu_core.c    | 57 ++++++++++---
 drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c     |  2 +
 drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c    | 80 +++++++++++++------
 drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c |  1 +
 4 files changed, 104 insertions(+), 36 deletions(-)

diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index 45e77b308238..23c0557891a0 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -914,6 +914,33 @@ static const unsigned long inv_mpu_scan_masks[] = {
 		.ext_info = inv_ext_info,				\
 	}
 
+static const struct iio_chan_spec inv_mpu9150_channels[] = {
+	IIO_CHAN_SOFT_TIMESTAMP(INV_MPU9X50_SCAN_TIMESTAMP),
+	/*
+	 * Note that temperature should only be via polled reading only,
+	 * not the final scan elements output.
+	 */
+	{
+		.type = IIO_TEMP,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW)
+				| BIT(IIO_CHAN_INFO_OFFSET)
+				| BIT(IIO_CHAN_INFO_SCALE),
+		.scan_index = -1,
+	},
+	INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
+	INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU6050_SCAN_GYRO_Y),
+	INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU6050_SCAN_GYRO_Z),
+
+	INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_MPU6050_SCAN_ACCL_X),
+	INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_MPU6050_SCAN_ACCL_Y),
+	INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
+
+	/* Magnetometer resolution is 13 bits */
+	INV_MPU9X50_MAGN_CHAN(IIO_MOD_X, 13, INV_MPU9X50_SCAN_MAGN_X),
+	INV_MPU9X50_MAGN_CHAN(IIO_MOD_Y, 13, INV_MPU9X50_SCAN_MAGN_Y),
+	INV_MPU9X50_MAGN_CHAN(IIO_MOD_Z, 13, INV_MPU9X50_SCAN_MAGN_Z),
+};
+
 static const struct iio_chan_spec inv_mpu9250_channels[] = {
 	IIO_CHAN_SOFT_TIMESTAMP(INV_MPU9X50_SCAN_TIMESTAMP),
 	/*
@@ -1323,21 +1350,16 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
 		inv_mpu_bus_setup(indio_dev);
 
 	switch (chip_type) {
+	case INV_MPU9150:
+		indio_dev->channels = inv_mpu9150_channels;
+		indio_dev->num_channels = ARRAY_SIZE(inv_mpu9150_channels);
+		indio_dev->available_scan_masks = inv_mpu9x50_scan_masks;
+		break;
 	case INV_MPU9250:
 	case INV_MPU9255:
-		/*
-		 * Use magnetometer inside the chip only if there is no i2c
-		 * auxiliary device in use.
-		 */
-		if (!st->magn_disabled) {
-			indio_dev->channels = inv_mpu9250_channels;
-			indio_dev->num_channels = ARRAY_SIZE(inv_mpu9250_channels);
-			indio_dev->available_scan_masks = inv_mpu9x50_scan_masks;
-		} else {
-			indio_dev->channels = inv_mpu_channels;
-			indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
-			indio_dev->available_scan_masks = inv_mpu_scan_masks;
-		}
+		indio_dev->channels = inv_mpu9250_channels;
+		indio_dev->num_channels = ARRAY_SIZE(inv_mpu9250_channels);
+		indio_dev->available_scan_masks = inv_mpu9x50_scan_masks;
 		break;
 	case INV_ICM20602:
 		indio_dev->channels = inv_icm20602_channels;
@@ -1350,6 +1372,15 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
 		indio_dev->available_scan_masks = inv_mpu_scan_masks;
 		break;
 	}
+	/*
+	 * Use magnetometer inside the chip only if there is no i2c
+	 * auxiliary device in use. Otherwise Going back to 6-axis only.
+	 */
+	if (st->magn_disabled) {
+		indio_dev->channels = inv_mpu_channels;
+		indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
+		indio_dev->available_scan_masks = inv_mpu_scan_masks;
+	}
 
 	indio_dev->info = &mpu_info;
 	indio_dev->modes = INDIO_BUFFER_TRIGGERED;
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
index 389cc8505e0e..f47a28b4be23 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
@@ -77,6 +77,7 @@ static bool inv_mpu_i2c_aux_bus(struct device *dev)
 	case INV_ICM20602:
 		/* no i2c auxiliary bus on the chip */
 		return false;
+	case INV_MPU9150:
 	case INV_MPU9250:
 	case INV_MPU9255:
 		if (st->magn_disabled)
@@ -102,6 +103,7 @@ static int inv_mpu_magn_disable(struct iio_dev *indio_dev)
 	struct device_node *mux_node;
 
 	switch (st->chip_type) {
+	case INV_MPU9150:
 	case INV_MPU9250:
 	case INV_MPU9255:
 		mux_node = of_get_child_by_name(dev->of_node, "i2c-gate");
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c
index 02735af152c8..4f192352521e 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c
@@ -12,7 +12,9 @@
 #include "inv_mpu_magn.h"
 
 /*
- * MPU9250 magnetometer is an AKM AK8963 chip on I2C aux bus
+ * MPU9xxx magnetometer are AKM chips on I2C aux bus
+ * MPU9150 is AK8975
+ * MPU9250 is AK8963
  */
 #define INV_MPU_MAGN_I2C_ADDR		0x0C
 
@@ -33,10 +35,10 @@
 #define INV_MPU_MAGN_BITS_MODE_PWDN	0x00
 #define INV_MPU_MAGN_BITS_MODE_SINGLE	0x01
 #define INV_MPU_MAGN_BITS_MODE_FUSE	0x0F
-#define INV_MPU_MAGN_BIT_OUTPUT_BIT	0x10
+#define INV_MPU9250_MAGN_BIT_OUTPUT_BIT	0x10
 
-#define INV_MPU_MAGN_REG_CNTL2		0x0B
-#define INV_MPU_MAGN_BIT_SRST		0x01
+#define INV_MPU9250_MAGN_REG_CNTL2	0x0B
+#define INV_MPU9250_MAGN_BIT_SRST	0x01
 
 #define INV_MPU_MAGN_REG_ASAX		0x10
 #define INV_MPU_MAGN_REG_ASAY		0x11
@@ -48,6 +50,7 @@
 static bool inv_magn_supported(const struct inv_mpu6050_state *st)
 {
 	switch (st->chip_type) {
+	case INV_MPU9150:
 	case INV_MPU9250:
 	case INV_MPU9255:
 		return true;
@@ -61,6 +64,7 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
 {
 	uint8_t val;
 	uint8_t asa[3];
+	int32_t sensitivity;
 	int ret;
 
 	/* check whoami */
@@ -71,12 +75,19 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
 	if (val != INV_MPU_MAGN_BITS_WIA)
 		return -ENODEV;
 
-	/* reset chip */
-	ret = inv_mpu_aux_write(st, INV_MPU_MAGN_I2C_ADDR,
-				INV_MPU_MAGN_REG_CNTL2,
-				INV_MPU_MAGN_BIT_SRST);
-	if (ret)
-		return ret;
+	/* software reset for MPU925x only */
+	switch (st->chip_type) {
+	case INV_MPU9250:
+	case INV_MPU9255:
+		ret = inv_mpu_aux_write(st, INV_MPU_MAGN_I2C_ADDR,
+					INV_MPU9250_MAGN_REG_CNTL2,
+					INV_MPU9250_MAGN_BIT_SRST);
+		if (ret)
+			return ret;
+		break;
+	default:
+		break;
+	}
 
 	/* read fuse ROM data */
 	ret = inv_mpu_aux_write(st, INV_MPU_MAGN_I2C_ADDR,
@@ -97,6 +108,25 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
 	if (ret)
 		return ret;
 
+	/*
+	 * Sensor sentivity
+	 * 1 uT = 0.01 G and value is in micron (1e6)
+	 * sensitvity = x uT * 0.01 * 1e6
+	 */
+	switch (st->chip_type) {
+	case INV_MPU9150:
+		/* sensor sensitivity is 0.3 uT */
+		sensitivity = 3000;
+		break;
+	case INV_MPU9250:
+	case INV_MPU9255:
+		/* sensor sensitivity in 16 bits mode: 0.15 uT */
+		sensitivity = 1500;
+		break;
+	default:
+		return -EINVAL;
+	}
+
 	/*
 	 * Sensitivity adjustement and scale to Gauss
 	 *
@@ -104,16 +134,11 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
 	 * Factor simplification:
 	 * Hadj = H * ((ASA + 128) / 256)
 	 *
-	 * Sensor sentivity
-	 * 0.15 uT in 16 bits mode
-	 * 1 uT = 0.01 G and value is in micron (1e6)
-	 * sensitvity = 0.15 uT * 0.01 * 1e6
-	 *
-	 * raw_to_gauss = Hadj * 1500
+	 * raw_to_gauss = Hadj * sensitivity
 	 */
-	st->magn_raw_to_gauss[0] = (((int32_t)asa[0] + 128) * 1500) / 256;
-	st->magn_raw_to_gauss[1] = (((int32_t)asa[1] + 128) * 1500) / 256;
-	st->magn_raw_to_gauss[2] = (((int32_t)asa[2] + 128) * 1500) / 256;
+	st->magn_raw_to_gauss[0] = (((int32_t)asa[0] + 128) * sensitivity) / 256;
+	st->magn_raw_to_gauss[1] = (((int32_t)asa[1] + 128) * sensitivity) / 256;
+	st->magn_raw_to_gauss[2] = (((int32_t)asa[2] + 128) * sensitivity) / 256;
 
 	return 0;
 }
@@ -129,6 +154,7 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
  */
 int inv_mpu_magn_probe(struct inv_mpu6050_state *st)
 {
+	uint8_t val;
 	int ret;
 
 	/* quit if chip is not supported */
@@ -179,10 +205,17 @@ int inv_mpu_magn_probe(struct inv_mpu6050_state *st)
 	if (ret)
 		return ret;
 
-	/* add 16 bits mode */
-	ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_DO(1),
-			   INV_MPU_MAGN_BITS_MODE_SINGLE |
-			   INV_MPU_MAGN_BIT_OUTPUT_BIT);
+	/* add 16 bits mode for MPU925x */
+	val = INV_MPU_MAGN_BITS_MODE_SINGLE;
+	switch (st->chip_type) {
+	case INV_MPU9250:
+	case INV_MPU9255:
+		val |= INV_MPU9250_MAGN_BIT_OUTPUT_BIT;
+		break;
+	default:
+		break;
+	}
+	ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_DO(1), val);
 	if (ret)
 		return ret;
 
@@ -237,6 +270,7 @@ int inv_mpu_magn_set_orient(struct inv_mpu6050_state *st)
 
 	/* fill magnetometer orientation */
 	switch (st->chip_type) {
+	case INV_MPU9150:
 	case INV_MPU9250:
 	case INV_MPU9255:
 		/* x <- y */
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
index d7d951927a44..a9c75bc62f18 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
@@ -50,6 +50,7 @@ static void inv_scan_query(struct iio_dev *indio_dev)
 	struct inv_mpu6050_state *st = iio_priv(indio_dev);
 
 	switch (st->chip_type) {
+	case INV_MPU9150:
 	case INV_MPU9250:
 	case INV_MPU9255:
 		return inv_scan_query_mpu9x50(indio_dev);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] iio: imu: inv_mpu6050: delete not existing MPU9150 spi support
  2019-11-15 14:06 ` [PATCH 1/2] iio: imu: inv_mpu6050: delete not existing MPU9150 spi support Jean-Baptiste Maneyrol
@ 2019-11-16 17:16   ` Jonathan Cameron
  0 siblings, 0 replies; 5+ messages in thread
From: Jonathan Cameron @ 2019-11-16 17:16 UTC (permalink / raw)
  To: Jean-Baptiste Maneyrol; +Cc: linux-iio

On Fri, 15 Nov 2019 15:06:21 +0100
Jean-Baptiste Maneyrol <jmaneyrol@invensense.com> wrote:

> MPU9150 is i2c only.
> Update Kconfig to delete in description chips that are i2c or
> spi only.
> 
> Signed-off-by: Jean-Baptiste Maneyrol <jmaneyrol@invensense.com>
Good to clean this up.

Applied to the togreg branch of iio.git and pushed out as testing
to be ignored (hopefully)

> ---
>  drivers/iio/imu/inv_mpu6050/Kconfig       | 6 +++---
>  drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 1 -
>  2 files changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
> index e4c4c12236a7..963a0cafe0cb 100644
> --- a/drivers/iio/imu/inv_mpu6050/Kconfig
> +++ b/drivers/iio/imu/inv_mpu6050/Kconfig
> @@ -14,7 +14,7 @@ config INV_MPU6050_I2C
>  	select INV_MPU6050_IIO
>  	select REGMAP_I2C
>  	help
> -	  This driver supports the Invensense MPU6000/6050/6500/6515,
> +	  This driver supports the Invensense MPU6050/6500/6515,
>  	  MPU9150/9250/9255 and ICM20608/20602 motion tracking devices
>  	  over I2C.
>  	  This driver can be built as a module. The module will be called
> @@ -26,8 +26,8 @@ config INV_MPU6050_SPI
>  	select INV_MPU6050_IIO
>  	select REGMAP_SPI
>  	help
> -	  This driver supports the Invensense MPU6000/6050/6500/6515,
> -	  MPU9150/9250/9255 and ICM20608/20602 motion tracking devices
> +	  This driver supports the Invensense MPU6000/6500/6515,
> +	  MPU9250/9255 and ICM20608/20602 motion tracking devices
>  	  over SPI.
>  	  This driver can be built as a module. The module will be called
>  	  inv-mpu6050-spi.
> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
> index 142692fc0758..ec102d5a5c77 100644
> --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
> @@ -74,7 +74,6 @@ static int inv_mpu_probe(struct spi_device *spi)
>  static const struct spi_device_id inv_mpu_id[] = {
>  	{"mpu6000", INV_MPU6000},
>  	{"mpu6500", INV_MPU6500},
> -	{"mpu9150", INV_MPU9150},
>  	{"mpu9250", INV_MPU9250},
>  	{"mpu9255", INV_MPU9255},
>  	{"icm20608", INV_ICM20608},


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] iio: imu: inv_mpu6050: add support of MPU9150 magnetometer
  2019-11-15 14:06 ` [PATCH 2/2] iio: imu: inv_mpu6050: add support of MPU9150 magnetometer Jean-Baptiste Maneyrol
@ 2019-11-16 17:20   ` Jonathan Cameron
  0 siblings, 0 replies; 5+ messages in thread
From: Jonathan Cameron @ 2019-11-16 17:20 UTC (permalink / raw)
  To: Jean-Baptiste Maneyrol; +Cc: linux-iio

On Fri, 15 Nov 2019 15:06:22 +0100
Jean-Baptiste Maneyrol <jmaneyrol@invensense.com> wrote:

> Add support for driving MPU9150 magnetometer (AK8975) from mpu.
> 
> Signed-off-by: Jean-Baptiste Maneyrol <jmaneyrol@invensense.com>
All the prerequisits are now (I think) in my togreg branch so
applied to that and pushed out as testing for the autobuilders
to do more build tests than I can be bothered with :)

Thanks,

Jonathan

> ---
>  drivers/iio/imu/inv_mpu6050/inv_mpu_core.c    | 57 ++++++++++---
>  drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c     |  2 +
>  drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c    | 80 +++++++++++++------
>  drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c |  1 +
>  4 files changed, 104 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
> index 45e77b308238..23c0557891a0 100644
> --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
> @@ -914,6 +914,33 @@ static const unsigned long inv_mpu_scan_masks[] = {
>  		.ext_info = inv_ext_info,				\
>  	}
>  
> +static const struct iio_chan_spec inv_mpu9150_channels[] = {
> +	IIO_CHAN_SOFT_TIMESTAMP(INV_MPU9X50_SCAN_TIMESTAMP),
> +	/*
> +	 * Note that temperature should only be via polled reading only,
> +	 * not the final scan elements output.
> +	 */
> +	{
> +		.type = IIO_TEMP,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW)
> +				| BIT(IIO_CHAN_INFO_OFFSET)
> +				| BIT(IIO_CHAN_INFO_SCALE),
> +		.scan_index = -1,
> +	},
> +	INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
> +	INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU6050_SCAN_GYRO_Y),
> +	INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU6050_SCAN_GYRO_Z),
> +
> +	INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_MPU6050_SCAN_ACCL_X),
> +	INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_MPU6050_SCAN_ACCL_Y),
> +	INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
> +
> +	/* Magnetometer resolution is 13 bits */
> +	INV_MPU9X50_MAGN_CHAN(IIO_MOD_X, 13, INV_MPU9X50_SCAN_MAGN_X),
> +	INV_MPU9X50_MAGN_CHAN(IIO_MOD_Y, 13, INV_MPU9X50_SCAN_MAGN_Y),
> +	INV_MPU9X50_MAGN_CHAN(IIO_MOD_Z, 13, INV_MPU9X50_SCAN_MAGN_Z),
> +};
> +
>  static const struct iio_chan_spec inv_mpu9250_channels[] = {
>  	IIO_CHAN_SOFT_TIMESTAMP(INV_MPU9X50_SCAN_TIMESTAMP),
>  	/*
> @@ -1323,21 +1350,16 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
>  		inv_mpu_bus_setup(indio_dev);
>  
>  	switch (chip_type) {
> +	case INV_MPU9150:
> +		indio_dev->channels = inv_mpu9150_channels;
> +		indio_dev->num_channels = ARRAY_SIZE(inv_mpu9150_channels);
> +		indio_dev->available_scan_masks = inv_mpu9x50_scan_masks;
> +		break;
>  	case INV_MPU9250:
>  	case INV_MPU9255:
> -		/*
> -		 * Use magnetometer inside the chip only if there is no i2c
> -		 * auxiliary device in use.
> -		 */
> -		if (!st->magn_disabled) {
> -			indio_dev->channels = inv_mpu9250_channels;
> -			indio_dev->num_channels = ARRAY_SIZE(inv_mpu9250_channels);
> -			indio_dev->available_scan_masks = inv_mpu9x50_scan_masks;
> -		} else {
> -			indio_dev->channels = inv_mpu_channels;
> -			indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
> -			indio_dev->available_scan_masks = inv_mpu_scan_masks;
> -		}
> +		indio_dev->channels = inv_mpu9250_channels;
> +		indio_dev->num_channels = ARRAY_SIZE(inv_mpu9250_channels);
> +		indio_dev->available_scan_masks = inv_mpu9x50_scan_masks;
>  		break;
>  	case INV_ICM20602:
>  		indio_dev->channels = inv_icm20602_channels;
> @@ -1350,6 +1372,15 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
>  		indio_dev->available_scan_masks = inv_mpu_scan_masks;
>  		break;
>  	}
> +	/*
> +	 * Use magnetometer inside the chip only if there is no i2c
> +	 * auxiliary device in use. Otherwise Going back to 6-axis only.
> +	 */
> +	if (st->magn_disabled) {
> +		indio_dev->channels = inv_mpu_channels;
> +		indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
> +		indio_dev->available_scan_masks = inv_mpu_scan_masks;
> +	}
>  
>  	indio_dev->info = &mpu_info;
>  	indio_dev->modes = INDIO_BUFFER_TRIGGERED;
> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
> index 389cc8505e0e..f47a28b4be23 100644
> --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
> @@ -77,6 +77,7 @@ static bool inv_mpu_i2c_aux_bus(struct device *dev)
>  	case INV_ICM20602:
>  		/* no i2c auxiliary bus on the chip */
>  		return false;
> +	case INV_MPU9150:
>  	case INV_MPU9250:
>  	case INV_MPU9255:
>  		if (st->magn_disabled)
> @@ -102,6 +103,7 @@ static int inv_mpu_magn_disable(struct iio_dev *indio_dev)
>  	struct device_node *mux_node;
>  
>  	switch (st->chip_type) {
> +	case INV_MPU9150:
>  	case INV_MPU9250:
>  	case INV_MPU9255:
>  		mux_node = of_get_child_by_name(dev->of_node, "i2c-gate");
> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c
> index 02735af152c8..4f192352521e 100644
> --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c
> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c
> @@ -12,7 +12,9 @@
>  #include "inv_mpu_magn.h"
>  
>  /*
> - * MPU9250 magnetometer is an AKM AK8963 chip on I2C aux bus
> + * MPU9xxx magnetometer are AKM chips on I2C aux bus
> + * MPU9150 is AK8975
> + * MPU9250 is AK8963
>   */
>  #define INV_MPU_MAGN_I2C_ADDR		0x0C
>  
> @@ -33,10 +35,10 @@
>  #define INV_MPU_MAGN_BITS_MODE_PWDN	0x00
>  #define INV_MPU_MAGN_BITS_MODE_SINGLE	0x01
>  #define INV_MPU_MAGN_BITS_MODE_FUSE	0x0F
> -#define INV_MPU_MAGN_BIT_OUTPUT_BIT	0x10
> +#define INV_MPU9250_MAGN_BIT_OUTPUT_BIT	0x10
>  
> -#define INV_MPU_MAGN_REG_CNTL2		0x0B
> -#define INV_MPU_MAGN_BIT_SRST		0x01
> +#define INV_MPU9250_MAGN_REG_CNTL2	0x0B
> +#define INV_MPU9250_MAGN_BIT_SRST	0x01
>  
>  #define INV_MPU_MAGN_REG_ASAX		0x10
>  #define INV_MPU_MAGN_REG_ASAY		0x11
> @@ -48,6 +50,7 @@
>  static bool inv_magn_supported(const struct inv_mpu6050_state *st)
>  {
>  	switch (st->chip_type) {
> +	case INV_MPU9150:
>  	case INV_MPU9250:
>  	case INV_MPU9255:
>  		return true;
> @@ -61,6 +64,7 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
>  {
>  	uint8_t val;
>  	uint8_t asa[3];
> +	int32_t sensitivity;
>  	int ret;
>  
>  	/* check whoami */
> @@ -71,12 +75,19 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
>  	if (val != INV_MPU_MAGN_BITS_WIA)
>  		return -ENODEV;
>  
> -	/* reset chip */
> -	ret = inv_mpu_aux_write(st, INV_MPU_MAGN_I2C_ADDR,
> -				INV_MPU_MAGN_REG_CNTL2,
> -				INV_MPU_MAGN_BIT_SRST);
> -	if (ret)
> -		return ret;
> +	/* software reset for MPU925x only */
> +	switch (st->chip_type) {
> +	case INV_MPU9250:
> +	case INV_MPU9255:
> +		ret = inv_mpu_aux_write(st, INV_MPU_MAGN_I2C_ADDR,
> +					INV_MPU9250_MAGN_REG_CNTL2,
> +					INV_MPU9250_MAGN_BIT_SRST);
> +		if (ret)
> +			return ret;
> +		break;
> +	default:
> +		break;
> +	}
>  
>  	/* read fuse ROM data */
>  	ret = inv_mpu_aux_write(st, INV_MPU_MAGN_I2C_ADDR,
> @@ -97,6 +108,25 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
>  	if (ret)
>  		return ret;
>  
> +	/*
> +	 * Sensor sentivity
> +	 * 1 uT = 0.01 G and value is in micron (1e6)
> +	 * sensitvity = x uT * 0.01 * 1e6
> +	 */
> +	switch (st->chip_type) {
> +	case INV_MPU9150:
> +		/* sensor sensitivity is 0.3 uT */
> +		sensitivity = 3000;
> +		break;
> +	case INV_MPU9250:
> +	case INV_MPU9255:
> +		/* sensor sensitivity in 16 bits mode: 0.15 uT */
> +		sensitivity = 1500;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
>  	/*
>  	 * Sensitivity adjustement and scale to Gauss
>  	 *
> @@ -104,16 +134,11 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
>  	 * Factor simplification:
>  	 * Hadj = H * ((ASA + 128) / 256)
>  	 *
> -	 * Sensor sentivity
> -	 * 0.15 uT in 16 bits mode
> -	 * 1 uT = 0.01 G and value is in micron (1e6)
> -	 * sensitvity = 0.15 uT * 0.01 * 1e6
> -	 *
> -	 * raw_to_gauss = Hadj * 1500
> +	 * raw_to_gauss = Hadj * sensitivity
>  	 */
> -	st->magn_raw_to_gauss[0] = (((int32_t)asa[0] + 128) * 1500) / 256;
> -	st->magn_raw_to_gauss[1] = (((int32_t)asa[1] + 128) * 1500) / 256;
> -	st->magn_raw_to_gauss[2] = (((int32_t)asa[2] + 128) * 1500) / 256;
> +	st->magn_raw_to_gauss[0] = (((int32_t)asa[0] + 128) * sensitivity) / 256;
> +	st->magn_raw_to_gauss[1] = (((int32_t)asa[1] + 128) * sensitivity) / 256;
> +	st->magn_raw_to_gauss[2] = (((int32_t)asa[2] + 128) * sensitivity) / 256;
>  
>  	return 0;
>  }
> @@ -129,6 +154,7 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
>   */
>  int inv_mpu_magn_probe(struct inv_mpu6050_state *st)
>  {
> +	uint8_t val;
>  	int ret;
>  
>  	/* quit if chip is not supported */
> @@ -179,10 +205,17 @@ int inv_mpu_magn_probe(struct inv_mpu6050_state *st)
>  	if (ret)
>  		return ret;
>  
> -	/* add 16 bits mode */
> -	ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_DO(1),
> -			   INV_MPU_MAGN_BITS_MODE_SINGLE |
> -			   INV_MPU_MAGN_BIT_OUTPUT_BIT);
> +	/* add 16 bits mode for MPU925x */
> +	val = INV_MPU_MAGN_BITS_MODE_SINGLE;
> +	switch (st->chip_type) {
> +	case INV_MPU9250:
> +	case INV_MPU9255:
> +		val |= INV_MPU9250_MAGN_BIT_OUTPUT_BIT;
> +		break;
> +	default:
> +		break;
> +	}
> +	ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_DO(1), val);
>  	if (ret)
>  		return ret;
>  
> @@ -237,6 +270,7 @@ int inv_mpu_magn_set_orient(struct inv_mpu6050_state *st)
>  
>  	/* fill magnetometer orientation */
>  	switch (st->chip_type) {
> +	case INV_MPU9150:
>  	case INV_MPU9250:
>  	case INV_MPU9255:
>  		/* x <- y */
> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
> index d7d951927a44..a9c75bc62f18 100644
> --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
> @@ -50,6 +50,7 @@ static void inv_scan_query(struct iio_dev *indio_dev)
>  	struct inv_mpu6050_state *st = iio_priv(indio_dev);
>  
>  	switch (st->chip_type) {
> +	case INV_MPU9150:
>  	case INV_MPU9250:
>  	case INV_MPU9255:
>  		return inv_scan_query_mpu9x50(indio_dev);


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-11-16 17:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-15 14:06 [PATCH 0/2] Add MPU9150 magnetometer support Jean-Baptiste Maneyrol
2019-11-15 14:06 ` [PATCH 1/2] iio: imu: inv_mpu6050: delete not existing MPU9150 spi support Jean-Baptiste Maneyrol
2019-11-16 17:16   ` Jonathan Cameron
2019-11-15 14:06 ` [PATCH 2/2] iio: imu: inv_mpu6050: add support of MPU9150 magnetometer Jean-Baptiste Maneyrol
2019-11-16 17:20   ` Jonathan Cameron

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.