* [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.