* [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
* 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
* [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 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 a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox