* [Patch v1 1/4] iio: imu: inv_mpu6050: Add compatibity with MPU6500
@ 2014-03-19 16:56 Srinivas Pandruvada
2014-03-19 16:56 ` [Patch v1 3/4] iio: imu: Enable checking of presence of device Srinivas Pandruvada
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Srinivas Pandruvada @ 2014-03-19 16:56 UTC (permalink / raw)
To: jic23-DgEjT+Ai2ygdnm+yROfE0A
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA, Srinivas Pandruvada
Adding MPU6500 in target list for this driver.
Description:
Source
Document: MPU-6500 Register Map and Descriptions Revision 2.1
Section 3: Register Map
This section describes difference in terms device programmability
bewteen MPU6050 and MPU6500.
These are different registers, which differs between MPU6050 and
MPU6500.
Addr Name
---------------------
1E LP_ACCEL_ODR
6C PWR_MGMT_2
77 XA_OFFSET_H
78 XA_OFFSET_L
7A YA_OFFSET_H
7B YA_OFFSET_L
7D ZA_OFFSET_H
7E ZA_OFFSET_L
But the current MPU6050 driver doesn't use registers which are different
except PWR_MGMT_2. The difference is support of "LP_WAKE_CTRL" at bit6-7
in MPU6050 mode. In MPU6500 they are not defined.
In current mpu6050 driver, only values used for this register are for
standby mode for gyro and accelerometer.
In both case frequency of wakeups is set to default and not using
bit 6-7.
So this driver van as well support MPU6500. In addition MPU6500 can
run MPU6050 mode by changing device trim settings.
So changing config comments to allow MPU6500 to use this driver.
When ths driver is enhanced to support more functions, i2c driver
data INV_MPU6500 or "WHO_AM_I" register can be used to add additional
functionality.
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---
drivers/iio/imu/inv_mpu6050/Kconfig | 2 ++
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 1 +
drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 1 +
3 files changed, 4 insertions(+)
diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
index 361b232..2d0608b 100644
--- a/drivers/iio/imu/inv_mpu6050/Kconfig
+++ b/drivers/iio/imu/inv_mpu6050/Kconfig
@@ -9,6 +9,8 @@ config INV_MPU6050_IIO
select IIO_TRIGGERED_BUFFER
help
This driver supports the Invensense MPU6050 devices.
+ This driver can also support MPU6500 in MPU6050 compatibility mode
+ and also in MPU6500 mode with some limitations.
It is a gyroscope/accelerometer combo device.
This driver can be built as a module. The module will be called
inv-mpu6050.
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index df7f1e1..52d688b 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -765,6 +765,7 @@ static SIMPLE_DEV_PM_OPS(inv_mpu_pmops, inv_mpu_suspend, inv_mpu_resume);
*/
static const struct i2c_device_id inv_mpu_id[] = {
{"mpu6050", INV_MPU6050},
+ {"mpu6500", INV_MPU6500},
{}
};
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
index f383955..4ddfd03 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
@@ -59,6 +59,7 @@ struct inv_mpu6050_reg_map {
/*device enum */
enum inv_devices {
INV_MPU6050,
+ INV_MPU6500,
INV_NUM_PARTS
};
--
1.7.11.7
^ permalink raw reply related [flat|nested] 8+ messages in thread* [Patch v1 3/4] iio: imu: Enable checking of presence of device 2014-03-19 16:56 [Patch v1 1/4] iio: imu: inv_mpu6050: Add compatibity with MPU6500 Srinivas Pandruvada @ 2014-03-19 16:56 ` Srinivas Pandruvada [not found] ` <1395248203-17027-3-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> 2014-03-19 16:56 ` [Patch v1 4/4] iio: imu: inv_mpu6050: ACPI enumeration Srinivas Pandruvada [not found] ` <1395248203-17027-1-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> 2 siblings, 1 reply; 8+ messages in thread From: Srinivas Pandruvada @ 2014-03-19 16:56 UTC (permalink / raw) To: jic23; +Cc: linux-iio, linux-acpi, Srinivas Pandruvada Added logic to check presence of MPU6050 before continuing. Currently only i2c writes are used in the initialzation path, which don't return any error, if some i2c device responds. In this case it continues to create iio devices, which don't work. This can be reproduced in a PC like platform, where ACPI definition of this defines multiple i2c addresses. We need to check for an valid i2c address by checking some id before continuing. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> --- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 27 +++++++++++++++++++++++++++ drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 5 +++++ 2 files changed, 32 insertions(+) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 744eba4..200163d 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -54,6 +54,7 @@ static const struct inv_mpu6050_reg_map reg_set_6050 = { .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1, .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2, .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG, + .who_am_i = INV_MPU6050_REG_WHOAMI, }; static const struct inv_mpu6050_chip_config chip_config_6050 = { @@ -74,6 +75,12 @@ static const struct inv_mpu6050_hw hw_info[INV_NUM_PARTS] = { }, }; +static const u16 inv_mpu_unique_ids[] = { + INV_MPU60X0_UNIQUE_ID, + INV_MPU6500_UNIQUE_ID, + 0x0000, +}; + int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 d) { return i2c_smbus_write_i2c_block_data(st->client, reg, 1, &d); @@ -630,6 +637,8 @@ static int inv_check_and_setup_chip(struct inv_mpu6050_state *st, const struct i2c_device_id *id) { int result; + bool matched = false; + int i = 0; st->chip_type = INV_MPU6050; st->hw = &hw_info[st->chip_type]; @@ -641,6 +650,24 @@ static int inv_check_and_setup_chip(struct inv_mpu6050_state *st, if (result) return result; msleep(INV_MPU6050_POWER_UP_TIME); + + result = i2c_smbus_read_byte_data(st->client, st->reg->who_am_i); + if (result < 0) { + dev_err(&st->client->dev, "Error reading WhoAmI\n"); + return result; + } + + while (inv_mpu_unique_ids[i] != 0x0000) { + if (inv_mpu_unique_ids[i++] == result) + matched = true; + } + + if (!matched) { + dev_err(&st->client->dev, "Not a valid MPU6XXX device %x\n", + result); + return -ENOSYS; + } + /* toggle power state. After reset, the sleep bit could be on or off depending on the OTP settings. Toggling power would make it in a definite state as well as making the hardware diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index 591ac2e..41196c5 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -55,6 +55,7 @@ struct inv_mpu6050_reg_map { u8 pwr_mgmt_1; u8 pwr_mgmt_2; u8 int_pin_cfg; + u8 who_am_i; }; /*device enum */ @@ -190,6 +191,10 @@ struct inv_mpu6050_state { #define INV_MPU6050_REG_INT_PIN_CFG 0x37 #define INV_MPU6050_BIT_BYPASS_EN 0x2 +#define INV_MPU6050_REG_WHOAMI 0x75 +#define INV_MPU6500_UNIQUE_ID 0x70 +#define INV_MPU60X0_UNIQUE_ID 0x68 + /* scan element definition */ enum inv_mpu6050_scan { INV_MPU6050_SCAN_ACCL_X, -- 1.7.11.7 ^ permalink raw reply related [flat|nested] 8+ messages in thread
[parent not found: <1395248203-17027-3-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>]
* Re: [Patch v1 3/4] iio: imu: Enable checking of presence of device [not found] ` <1395248203-17027-3-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> @ 2014-03-29 10:52 ` Jonathan Cameron 0 siblings, 0 replies; 8+ messages in thread From: Jonathan Cameron @ 2014-03-29 10:52 UTC (permalink / raw) To: Srinivas Pandruvada Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, linux-acpi-u79uwXL29TY76Z2rM5mHXA On 19/03/14 16:56, Srinivas Pandruvada wrote: > Added logic to check presence of MPU6050 before continuing. Currently > only i2c writes are used in the initialzation path, which don't return > any error, if some i2c device responds. In this case it continues to > create iio devices, which don't work. > This can be reproduced in a PC like platform, where ACPI definition > of this defines multiple i2c addresses. That's hideous. oh well - guess we need to cope with it. > We need to check for an valid > i2c address by checking some id before continuing. > > Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> This looks fine, but won't apply without patch 2. If you want to reorder the series to push patch 2 towards the end, then I can take this whilst that more complex issue is being sorted out. > --- > drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 27 +++++++++++++++++++++++++++ > drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 5 +++++ > 2 files changed, 32 insertions(+) > > diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c > index 744eba4..200163d 100644 > --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c > +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c > @@ -54,6 +54,7 @@ static const struct inv_mpu6050_reg_map reg_set_6050 = { > .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1, > .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2, > .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG, > + .who_am_i = INV_MPU6050_REG_WHOAMI, > }; > > static const struct inv_mpu6050_chip_config chip_config_6050 = { > @@ -74,6 +75,12 @@ static const struct inv_mpu6050_hw hw_info[INV_NUM_PARTS] = { > }, > }; > > +static const u16 inv_mpu_unique_ids[] = { > + INV_MPU60X0_UNIQUE_ID, > + INV_MPU6500_UNIQUE_ID, > + 0x0000, > +}; > + > int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 d) > { > return i2c_smbus_write_i2c_block_data(st->client, reg, 1, &d); > @@ -630,6 +637,8 @@ static int inv_check_and_setup_chip(struct inv_mpu6050_state *st, > const struct i2c_device_id *id) > { > int result; > + bool matched = false; > + int i = 0; > > st->chip_type = INV_MPU6050; > st->hw = &hw_info[st->chip_type]; > @@ -641,6 +650,24 @@ static int inv_check_and_setup_chip(struct inv_mpu6050_state *st, > if (result) > return result; > msleep(INV_MPU6050_POWER_UP_TIME); > + > + result = i2c_smbus_read_byte_data(st->client, st->reg->who_am_i); > + if (result < 0) { > + dev_err(&st->client->dev, "Error reading WhoAmI\n"); > + return result; > + } > + > + while (inv_mpu_unique_ids[i] != 0x0000) { > + if (inv_mpu_unique_ids[i++] == result) > + matched = true; > + } > + > + if (!matched) { > + dev_err(&st->client->dev, "Not a valid MPU6XXX device %x\n", > + result); > + return -ENOSYS; > + } > + > /* toggle power state. After reset, the sleep bit could be on > or off depending on the OTP settings. Toggling power would > make it in a definite state as well as making the hardware > diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h > index 591ac2e..41196c5 100644 > --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h > +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h > @@ -55,6 +55,7 @@ struct inv_mpu6050_reg_map { > u8 pwr_mgmt_1; > u8 pwr_mgmt_2; > u8 int_pin_cfg; > + u8 who_am_i; > }; > > /*device enum */ > @@ -190,6 +191,10 @@ struct inv_mpu6050_state { > #define INV_MPU6050_REG_INT_PIN_CFG 0x37 > #define INV_MPU6050_BIT_BYPASS_EN 0x2 > > +#define INV_MPU6050_REG_WHOAMI 0x75 > +#define INV_MPU6500_UNIQUE_ID 0x70 > +#define INV_MPU60X0_UNIQUE_ID 0x68 > + > /* scan element definition */ > enum inv_mpu6050_scan { > INV_MPU6050_SCAN_ACCL_X, > ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Patch v1 4/4] iio: imu: inv_mpu6050: ACPI enumeration 2014-03-19 16:56 [Patch v1 1/4] iio: imu: inv_mpu6050: Add compatibity with MPU6500 Srinivas Pandruvada 2014-03-19 16:56 ` [Patch v1 3/4] iio: imu: Enable checking of presence of device Srinivas Pandruvada @ 2014-03-19 16:56 ` Srinivas Pandruvada [not found] ` <1395248203-17027-4-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> [not found] ` <1395248203-17027-1-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> 2 siblings, 1 reply; 8+ messages in thread From: Srinivas Pandruvada @ 2014-03-19 16:56 UTC (permalink / raw) To: jic23; +Cc: linux-iio, linux-acpi, Srinivas Pandruvada Added changes so that the module can be enumerated via ACPI. Also if there is no platform data available, it will use a default orientation data. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> --- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 31 ++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 200163d..2b3f24d 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -24,8 +24,16 @@ #include <linux/kfifo.h> #include <linux/spinlock.h> #include <linux/iio/iio.h> +#include <linux/acpi.h> #include "inv_mpu_iio.h" +/* Define some default platform data, if not supplied */ +static struct inv_mpu6050_platform_data inv_def_platform_data = { + .orientation = {-1, 0, 0, + 0, 1, 0, + 0, 0, -1 } +}; + /* * this is the gyro scale translated from dynamic range plus/minus * {250, 500, 1000, 2000} to rad/s @@ -706,6 +714,7 @@ static int inv_mpu_probe(struct i2c_client *client, struct inv_mpu6050_state *st; struct iio_dev *indio_dev; int result; + char *name; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) @@ -717,7 +726,10 @@ static int inv_mpu_probe(struct i2c_client *client, st = iio_priv(indio_dev); st->client = client; - st->plat_data = *(struct inv_mpu6050_platform_data + if (!dev_get_platdata(&client->dev)) + st->plat_data = inv_def_platform_data; + else + st->plat_data = *(struct inv_mpu6050_platform_data *)dev_get_platdata(&client->dev); /* power is turned on inside check chip type*/ result = inv_check_and_setup_chip(st, id); @@ -733,7 +745,14 @@ static int inv_mpu_probe(struct i2c_client *client, i2c_set_clientdata(client, indio_dev); indio_dev->dev.parent = &client->dev; - indio_dev->name = id->name; + + /* id will be NULL when enumerated via ACPI */ + if (id) + name = (char *)id->name; + else + name = (char *)dev_name(&client->dev); + + indio_dev->name = name; indio_dev->channels = inv_mpu_channels; indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels); @@ -815,12 +834,20 @@ static const struct i2c_device_id inv_mpu_id[] = { MODULE_DEVICE_TABLE(i2c, inv_mpu_id); +static const struct acpi_device_id inv_acpi_match[] = { + {"INVN6050", INV_MPU6050}, + {"INVN6500", INV_MPU6500}, + { }, +}; +MODULE_DEVICE_TABLE(acpi, inv_acpi_match); + static struct i2c_driver inv_mpu_driver = { .probe = inv_mpu_probe, .remove = inv_mpu_remove, .id_table = inv_mpu_id, .driver = { .owner = THIS_MODULE, + .acpi_match_table = ACPI_PTR(inv_acpi_match), .name = "inv-mpu6050", .pm = INV_MPU6050_PMOPS, }, -- 1.7.11.7 ^ permalink raw reply related [flat|nested] 8+ messages in thread
[parent not found: <1395248203-17027-4-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>]
* Re: [Patch v1 4/4] iio: imu: inv_mpu6050: ACPI enumeration [not found] ` <1395248203-17027-4-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> @ 2014-03-29 10:59 ` Jonathan Cameron 0 siblings, 0 replies; 8+ messages in thread From: Jonathan Cameron @ 2014-03-29 10:59 UTC (permalink / raw) To: Srinivas Pandruvada Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, linux-acpi-u79uwXL29TY76Z2rM5mHXA On 19/03/14 16:56, Srinivas Pandruvada wrote: > Added changes so that the module can be enumerated via ACPI. > Also if there is no platform data available, it will use a default > orientation data. > > Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> This one looks fine as well, but again I can't take it now because of patch 2 interfering with it. Thanks, Jonathan > --- > drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 31 ++++++++++++++++++++++++++++-- > 1 file changed, 29 insertions(+), 2 deletions(-) > > diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c > index 200163d..2b3f24d 100644 > --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c > +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c > @@ -24,8 +24,16 @@ > #include <linux/kfifo.h> > #include <linux/spinlock.h> > #include <linux/iio/iio.h> > +#include <linux/acpi.h> > #include "inv_mpu_iio.h" > > +/* Define some default platform data, if not supplied */ > +static struct inv_mpu6050_platform_data inv_def_platform_data = { > + .orientation = {-1, 0, 0, > + 0, 1, 0, > + 0, 0, -1 } > +}; > + > /* > * this is the gyro scale translated from dynamic range plus/minus > * {250, 500, 1000, 2000} to rad/s > @@ -706,6 +714,7 @@ static int inv_mpu_probe(struct i2c_client *client, > struct inv_mpu6050_state *st; > struct iio_dev *indio_dev; > int result; > + char *name; > > if (!i2c_check_functionality(client->adapter, > I2C_FUNC_SMBUS_I2C_BLOCK)) > @@ -717,7 +726,10 @@ static int inv_mpu_probe(struct i2c_client *client, > > st = iio_priv(indio_dev); > st->client = client; > - st->plat_data = *(struct inv_mpu6050_platform_data > + if (!dev_get_platdata(&client->dev)) > + st->plat_data = inv_def_platform_data; > + else > + st->plat_data = *(struct inv_mpu6050_platform_data > *)dev_get_platdata(&client->dev); > /* power is turned on inside check chip type*/ > result = inv_check_and_setup_chip(st, id); > @@ -733,7 +745,14 @@ static int inv_mpu_probe(struct i2c_client *client, > > i2c_set_clientdata(client, indio_dev); > indio_dev->dev.parent = &client->dev; > - indio_dev->name = id->name; > + > + /* id will be NULL when enumerated via ACPI */ > + if (id) > + name = (char *)id->name; > + else > + name = (char *)dev_name(&client->dev); > + > + indio_dev->name = name; > indio_dev->channels = inv_mpu_channels; > indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels); > > @@ -815,12 +834,20 @@ static const struct i2c_device_id inv_mpu_id[] = { > > MODULE_DEVICE_TABLE(i2c, inv_mpu_id); > > +static const struct acpi_device_id inv_acpi_match[] = { > + {"INVN6050", INV_MPU6050}, > + {"INVN6500", INV_MPU6500}, > + { }, > +}; > +MODULE_DEVICE_TABLE(acpi, inv_acpi_match); > + > static struct i2c_driver inv_mpu_driver = { > .probe = inv_mpu_probe, > .remove = inv_mpu_remove, > .id_table = inv_mpu_id, > .driver = { > .owner = THIS_MODULE, > + .acpi_match_table = ACPI_PTR(inv_acpi_match), > .name = "inv-mpu6050", > .pm = INV_MPU6050_PMOPS, > }, > ^ permalink raw reply [flat|nested] 8+ messages in thread
[parent not found: <1395248203-17027-1-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>]
* [Patch v1 2/4] iio: imu: inv_mpu6050: Enable default bypass mode [not found] ` <1395248203-17027-1-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> @ 2014-03-19 16:56 ` Srinivas Pandruvada [not found] ` <1395248203-17027-2-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> 2014-03-29 10:46 ` [Patch v1 1/4] iio: imu: inv_mpu6050: Add compatibity with MPU6500 Jonathan Cameron 1 sibling, 1 reply; 8+ messages in thread From: Srinivas Pandruvada @ 2014-03-19 16:56 UTC (permalink / raw) To: jic23-DgEjT+Ai2ygdnm+yROfE0A Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, linux-acpi-u79uwXL29TY76Z2rM5mHXA, Srinivas Pandruvada This chip has two modes to control secondary sensor attached to it. One is master mode and another is bypass mode. In master mode MPU6500 will directly communicates to the secondary sensor device attached to it. This can support very few secondary devices in this mode. But when configured in bypass mode the i2c lines are directly connected to host i2c bus controller. Since in master mode it can only support few devices and they are not implemented in this driver, set the default mode to bypass mode. When some multiplexer is implemented to use MPU6050 master mode, this mode can be enabled when requested. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> --- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 19 ++++++++++++++++++- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 4 ++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 52d688b..744eba4 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -53,6 +53,7 @@ static const struct inv_mpu6050_reg_map reg_set_6050 = { .int_enable = INV_MPU6050_REG_INT_ENABLE, .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1, .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2, + .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG, }; static const struct inv_mpu6050_chip_config chip_config_6050 = { @@ -608,6 +609,20 @@ static const struct iio_info mpu_info = { .validate_trigger = inv_mpu6050_validate_trigger, }; +static int inv_set_bypass_status(struct inv_mpu6050_state *st, bool enable) +{ + int ret; + + if (enable) + ret = inv_mpu6050_write_reg(st, st->reg->int_pin_cfg, + st->client->irq | + INV_MPU6050_BIT_BYPASS_EN); + else + ret = inv_mpu6050_write_reg(st, st->reg->int_pin_cfg, + st->client->irq); + return ret; +} + /** * inv_check_and_setup_chip() - check and setup chip. */ @@ -646,7 +661,9 @@ static int inv_check_and_setup_chip(struct inv_mpu6050_state *st, if (result) return result; - return 0; + result = inv_set_bypass_status(st, true); + + return result; } /** diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index 4ddfd03..591ac2e 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -54,6 +54,7 @@ struct inv_mpu6050_reg_map { u8 int_enable; u8 pwr_mgmt_1; u8 pwr_mgmt_2; + u8 int_pin_cfg; }; /*device enum */ @@ -186,6 +187,9 @@ struct inv_mpu6050_state { #define INV_MPU6050_MIN_FIFO_RATE 4 #define INV_MPU6050_ONE_K_HZ 1000 +#define INV_MPU6050_REG_INT_PIN_CFG 0x37 +#define INV_MPU6050_BIT_BYPASS_EN 0x2 + /* scan element definition */ enum inv_mpu6050_scan { INV_MPU6050_SCAN_ACCL_X, -- 1.7.11.7 ^ permalink raw reply related [flat|nested] 8+ messages in thread
[parent not found: <1395248203-17027-2-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>]
* Re: [Patch v1 2/4] iio: imu: inv_mpu6050: Enable default bypass mode [not found] ` <1395248203-17027-2-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> @ 2014-03-29 10:49 ` Jonathan Cameron 0 siblings, 0 replies; 8+ messages in thread From: Jonathan Cameron @ 2014-03-29 10:49 UTC (permalink / raw) To: Srinivas Pandruvada Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, linux-acpi-u79uwXL29TY76Z2rM5mHXA, Manuel Stahl, Wolfram Sang On 19/03/14 16:56, Srinivas Pandruvada wrote: > This chip has two modes to control secondary sensor attached to it. > One is master mode and another is bypass mode. In master mode > MPU6500 will directly communicates to the secondary sensor device > attached to it. This can support very few secondary devices in this > mode. > But when configured in bypass mode the i2c lines are directly connected > to host i2c bus controller. > Since in master mode it can only support few devices and they are not > implemented in this driver, set the default mode to bypass mode. > When some multiplexer is implemented to use MPU6050 master mode, > this mode can be enabled when requested. > > Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> To my understanding this still doesn't deal with the fact that devices on the slave bus are not connected if this driver is not loaded or has gone to sleep. Hence this needs as previously discussed to be done as a single input, single output i2c mux. That way the kernel 'knows' there is something inbetween that needs to be in the correct state. Jonathan > --- > drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 19 ++++++++++++++++++- > drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 4 ++++ > 2 files changed, 22 insertions(+), 1 deletion(-) > > diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c > index 52d688b..744eba4 100644 > --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c > +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c > @@ -53,6 +53,7 @@ static const struct inv_mpu6050_reg_map reg_set_6050 = { > .int_enable = INV_MPU6050_REG_INT_ENABLE, > .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1, > .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2, > + .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG, > }; > > static const struct inv_mpu6050_chip_config chip_config_6050 = { > @@ -608,6 +609,20 @@ static const struct iio_info mpu_info = { > .validate_trigger = inv_mpu6050_validate_trigger, > }; > > +static int inv_set_bypass_status(struct inv_mpu6050_state *st, bool enable) > +{ > + int ret; > + > + if (enable) > + ret = inv_mpu6050_write_reg(st, st->reg->int_pin_cfg, > + st->client->irq | > + INV_MPU6050_BIT_BYPASS_EN); > + else > + ret = inv_mpu6050_write_reg(st, st->reg->int_pin_cfg, > + st->client->irq); > + return ret; > +} > + > /** > * inv_check_and_setup_chip() - check and setup chip. > */ > @@ -646,7 +661,9 @@ static int inv_check_and_setup_chip(struct inv_mpu6050_state *st, > if (result) > return result; > > - return 0; > + result = inv_set_bypass_status(st, true); > + > + return result; > } > > /** > diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h > index 4ddfd03..591ac2e 100644 > --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h > +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h > @@ -54,6 +54,7 @@ struct inv_mpu6050_reg_map { > u8 int_enable; > u8 pwr_mgmt_1; > u8 pwr_mgmt_2; > + u8 int_pin_cfg; > }; > > /*device enum */ > @@ -186,6 +187,9 @@ struct inv_mpu6050_state { > #define INV_MPU6050_MIN_FIFO_RATE 4 > #define INV_MPU6050_ONE_K_HZ 1000 > > +#define INV_MPU6050_REG_INT_PIN_CFG 0x37 > +#define INV_MPU6050_BIT_BYPASS_EN 0x2 > + > /* scan element definition */ > enum inv_mpu6050_scan { > INV_MPU6050_SCAN_ACCL_X, > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Patch v1 1/4] iio: imu: inv_mpu6050: Add compatibity with MPU6500 [not found] ` <1395248203-17027-1-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> 2014-03-19 16:56 ` [Patch v1 2/4] iio: imu: inv_mpu6050: Enable default bypass mode Srinivas Pandruvada @ 2014-03-29 10:46 ` Jonathan Cameron 1 sibling, 0 replies; 8+ messages in thread From: Jonathan Cameron @ 2014-03-29 10:46 UTC (permalink / raw) To: Srinivas Pandruvada Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, linux-acpi-u79uwXL29TY76Z2rM5mHXA On 19/03/14 16:56, Srinivas Pandruvada wrote: > Adding MPU6500 in target list for this driver. > > Description: > Source > Document: MPU-6500 Register Map and Descriptions Revision 2.1 > Section 3: Register Map > > This section describes difference in terms device programmability > bewteen MPU6050 and MPU6500. > These are different registers, which differs between MPU6050 and > MPU6500. > > Addr Name > --------------------- > 1E LP_ACCEL_ODR > 6C PWR_MGMT_2 > 77 XA_OFFSET_H > 78 XA_OFFSET_L > 7A YA_OFFSET_H > 7B YA_OFFSET_L > 7D ZA_OFFSET_H > 7E ZA_OFFSET_L > > But the current MPU6050 driver doesn't use registers which are different > except PWR_MGMT_2. The difference is support of "LP_WAKE_CTRL" at bit6-7 > in MPU6050 mode. In MPU6500 they are not defined. > In current mpu6050 driver, only values used for this register are for > standby mode for gyro and accelerometer. > In both case frequency of wakeups is set to default and not using > bit 6-7. > > So this driver van as well support MPU6500. In addition MPU6500 can > run MPU6050 mode by changing device trim settings. > > So changing config comments to allow MPU6500 to use this driver. > When ths driver is enhanced to support more functions, i2c driver > data INV_MPU6500 or "WHO_AM_I" register can be used to add additional > functionality. > > Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> Applied to the togreg branch of iio.git - initially pushed out as the testing branch. Thanks, Jonathan > --- > drivers/iio/imu/inv_mpu6050/Kconfig | 2 ++ > drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 1 + > drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 1 + > 3 files changed, 4 insertions(+) > > diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig > index 361b232..2d0608b 100644 > --- a/drivers/iio/imu/inv_mpu6050/Kconfig > +++ b/drivers/iio/imu/inv_mpu6050/Kconfig > @@ -9,6 +9,8 @@ config INV_MPU6050_IIO > select IIO_TRIGGERED_BUFFER > help > This driver supports the Invensense MPU6050 devices. > + This driver can also support MPU6500 in MPU6050 compatibility mode > + and also in MPU6500 mode with some limitations. > It is a gyroscope/accelerometer combo device. > This driver can be built as a module. The module will be called > inv-mpu6050. > diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c > index df7f1e1..52d688b 100644 > --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c > +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c > @@ -765,6 +765,7 @@ static SIMPLE_DEV_PM_OPS(inv_mpu_pmops, inv_mpu_suspend, inv_mpu_resume); > */ > static const struct i2c_device_id inv_mpu_id[] = { > {"mpu6050", INV_MPU6050}, > + {"mpu6500", INV_MPU6500}, > {} > }; > > diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h > index f383955..4ddfd03 100644 > --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h > +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h > @@ -59,6 +59,7 @@ struct inv_mpu6050_reg_map { > /*device enum */ > enum inv_devices { > INV_MPU6050, > + INV_MPU6500, > INV_NUM_PARTS > }; > > ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2014-03-29 10:59 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-19 16:56 [Patch v1 1/4] iio: imu: inv_mpu6050: Add compatibity with MPU6500 Srinivas Pandruvada
2014-03-19 16:56 ` [Patch v1 3/4] iio: imu: Enable checking of presence of device Srinivas Pandruvada
[not found] ` <1395248203-17027-3-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2014-03-29 10:52 ` Jonathan Cameron
2014-03-19 16:56 ` [Patch v1 4/4] iio: imu: inv_mpu6050: ACPI enumeration Srinivas Pandruvada
[not found] ` <1395248203-17027-4-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2014-03-29 10:59 ` Jonathan Cameron
[not found] ` <1395248203-17027-1-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2014-03-19 16:56 ` [Patch v1 2/4] iio: imu: inv_mpu6050: Enable default bypass mode Srinivas Pandruvada
[not found] ` <1395248203-17027-2-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2014-03-29 10:49 ` Jonathan Cameron
2014-03-29 10:46 ` [Patch v1 1/4] iio: imu: inv_mpu6050: Add compatibity with MPU6500 Jonathan Cameron
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox