All of lore.kernel.org
 help / color / mirror / Atom feed
* [Patch v1 1/4] iio: imu: inv_mpu6050: Add compatibity with MPU6500
@ 2014-03-19 16:56 ` Srinivas Pandruvada
  0 siblings, 0 replies; 17+ 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] 17+ messages in thread

* [Patch v1 1/4] iio: imu: inv_mpu6050: Add compatibity with MPU6500
@ 2014-03-19 16:56 ` Srinivas Pandruvada
  0 siblings, 0 replies; 17+ messages in thread
From: Srinivas Pandruvada @ 2014-03-19 16:56 UTC (permalink / raw)
  To: jic23; +Cc: linux-iio, linux-acpi, 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@linux.intel.com>
---
 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] 17+ messages in thread

* [Patch v1 2/4] iio: imu: inv_mpu6050: Enable default bypass mode
  2014-03-19 16:56 ` Srinivas Pandruvada
@ 2014-03-19 16:56     ` Srinivas Pandruvada
  -1 siblings, 0 replies; 17+ 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] 17+ messages in thread

* [Patch v1 2/4] iio: imu: inv_mpu6050: Enable default bypass mode
@ 2014-03-19 16:56     ` Srinivas Pandruvada
  0 siblings, 0 replies; 17+ messages in thread
From: Srinivas Pandruvada @ 2014-03-19 16:56 UTC (permalink / raw)
  To: jic23; +Cc: linux-iio, linux-acpi, 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@linux.intel.com>
---
 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] 17+ messages in thread

* [Patch v1 3/4] iio: imu: Enable checking of presence of device
  2014-03-19 16:56 ` Srinivas Pandruvada
  (?)
  (?)
@ 2014-03-19 16:56 ` Srinivas Pandruvada
       [not found]   ` <1395248203-17027-3-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
  -1 siblings, 1 reply; 17+ 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] 17+ messages in thread

* [Patch v1 4/4] iio: imu: inv_mpu6050: ACPI enumeration
  2014-03-19 16:56 ` Srinivas Pandruvada
                   ` (2 preceding siblings ...)
  (?)
@ 2014-03-19 16:56 ` Srinivas Pandruvada
       [not found]   ` <1395248203-17027-4-git-send-email-srinivas.pandruvada-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
  -1 siblings, 1 reply; 17+ 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] 17+ messages in thread

* Re: [Patch v1 1/4] iio: imu: inv_mpu6050: Add compatibity with MPU6500
  2014-03-19 16:56 ` Srinivas Pandruvada
@ 2014-03-29 10:46     ` Jonathan Cameron
  -1 siblings, 0 replies; 17+ 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] 17+ messages in thread

* Re: [Patch v1 1/4] iio: imu: inv_mpu6050: Add compatibity with MPU6500
@ 2014-03-29 10:46     ` Jonathan Cameron
  0 siblings, 0 replies; 17+ messages in thread
From: Jonathan Cameron @ 2014-03-29 10:46 UTC (permalink / raw)
  To: Srinivas Pandruvada; +Cc: linux-iio, linux-acpi

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@linux.intel.com>
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] 17+ messages in thread

* Re: [Patch v1 2/4] iio: imu: inv_mpu6050: Enable default bypass mode
  2014-03-19 16:56     ` Srinivas Pandruvada
@ 2014-03-29 10:49         ` Jonathan Cameron
  -1 siblings, 0 replies; 17+ 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] 17+ messages in thread

* Re: [Patch v1 2/4] iio: imu: inv_mpu6050: Enable default bypass mode
@ 2014-03-29 10:49         ` Jonathan Cameron
  0 siblings, 0 replies; 17+ messages in thread
From: Jonathan Cameron @ 2014-03-29 10:49 UTC (permalink / raw)
  To: Srinivas Pandruvada; +Cc: linux-iio, linux-acpi, 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@linux.intel.com>
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] 17+ messages in thread

* Re: [Patch v1 3/4] iio: imu: Enable checking of presence of device
  2014-03-19 16:56 ` [Patch v1 3/4] iio: imu: Enable checking of presence of device Srinivas Pandruvada
@ 2014-03-29 10:52       ` Jonathan Cameron
  0 siblings, 0 replies; 17+ 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] 17+ messages in thread

* Re: [Patch v1 3/4] iio: imu: Enable checking of presence of device
@ 2014-03-29 10:52       ` Jonathan Cameron
  0 siblings, 0 replies; 17+ messages in thread
From: Jonathan Cameron @ 2014-03-29 10:52 UTC (permalink / raw)
  To: Srinivas Pandruvada; +Cc: linux-iio, linux-acpi

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@linux.intel.com>
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] 17+ messages in thread

* Re: [Patch v1 4/4] iio: imu: inv_mpu6050: ACPI enumeration
  2014-03-19 16:56 ` [Patch v1 4/4] iio: imu: inv_mpu6050: ACPI enumeration Srinivas Pandruvada
@ 2014-03-29 10:59       ` Jonathan Cameron
  0 siblings, 0 replies; 17+ 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] 17+ messages in thread

* Re: [Patch v1 4/4] iio: imu: inv_mpu6050: ACPI enumeration
@ 2014-03-29 10:59       ` Jonathan Cameron
  0 siblings, 0 replies; 17+ messages in thread
From: Jonathan Cameron @ 2014-03-29 10:59 UTC (permalink / raw)
  To: Srinivas Pandruvada; +Cc: linux-iio, linux-acpi

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@linux.intel.com>
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] 17+ messages in thread

* Re: [Patch v1 2/4] iio: imu: inv_mpu6050: Enable default bypass mode
  2014-03-29 10:49         ` Jonathan Cameron
  (?)
@ 2014-04-11 23:24         ` Srinivas Pandruvada
  2014-04-12 16:28           ` Jonathan Cameron
  -1 siblings, 1 reply; 17+ messages in thread
From: Srinivas Pandruvada @ 2014-04-11 23:24 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, Manuel Stahl, Wolfram Sang

On 03/29/2014 03:49 AM, Jonathan Cameron wrote:
> 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@linux.intel.com>
> 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.
>

I am looking at a way to implement multiplexing 1:1 as suggested in 
email chains.
The problem I have:
My two slave devices (MPU6XXX and AK8963 enumerated via ACPI. So they 
i2clients are already tied to the I2C adapter.
We don't have a board setup file in PC like platform.
I have implemented in mux in MPU6XXX driver. But AK8963 driver is not 
aware about mux adapter, it will not call my mux select function. So I 
feel that we need to have a board setup file, to correctly create i2C 
clients attaching to correct adapter for using this design.
Is this correct?

Thanks,
Srinivas




> 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] 17+ messages in thread

* Re: [Patch v1 2/4] iio: imu: inv_mpu6050: Enable default bypass mode
  2014-04-11 23:24         ` Srinivas Pandruvada
@ 2014-04-12 16:28           ` Jonathan Cameron
  2014-04-14  2:21             ` Srinivas Pandruvada
  0 siblings, 1 reply; 17+ messages in thread
From: Jonathan Cameron @ 2014-04-12 16:28 UTC (permalink / raw)
  To: Srinivas Pandruvada; +Cc: linux-iio, Manuel Stahl, Wolfram Sang

On 12/04/14 00:24, Srinivas Pandruvada wrote:
> On 03/29/2014 03:49 AM, Jonathan Cameron wrote:
>> 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@linux.intel.com>
>> 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.
>>
>
> I am looking at a way to implement multiplexing 1:1 as suggested in email chains.
> The problem I have:
> My two slave devices (MPU6XXX and AK8963 enumerated via ACPI. So they i2clients are already tied to the I2C adapter.
So the ACPI has no description of the fact that the ak8963 is connected through the
MPU device.  That's irritating.

> We don't have a board setup file in PC like platform.
> I have implemented in mux in MPU6XXX driver. But AK8963 driver is not
> aware about mux adapter, it will not call my mux select function. So
> I feel that we need to have a board setup file, to correctly create
> i2C clients attaching to correct adapter for using this design. Is
> this correct?
It ought to be possible to do it from ACPI enumeration but
only if there is some representation of the topology from ACPI.
Otherwise we will need to represent this weirdness somewhere...

>
> Thanks,
> Srinivas
>
>
>
>
>> 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,
>>>
>>
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

* Re: [Patch v1 2/4] iio: imu: inv_mpu6050: Enable default bypass mode
  2014-04-12 16:28           ` Jonathan Cameron
@ 2014-04-14  2:21             ` Srinivas Pandruvada
  0 siblings, 0 replies; 17+ messages in thread
From: Srinivas Pandruvada @ 2014-04-14  2:21 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, Manuel Stahl, Wolfram Sang


On 04/12/2014 09:28 AM, Jonathan Cameron wrote:
> On 12/04/14 00:24, Srinivas Pandruvada wrote:
>> On 03/29/2014 03:49 AM, Jonathan Cameron wrote:
>>> 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@linux.intel.com>
>>> 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.
>>>
>>
>> I am looking at a way to implement multiplexing 1:1 as suggested in 
>> email chains.
>> The problem I have:
>> My two slave devices (MPU6XXX and AK8963 enumerated via ACPI. So they 
>> i2clients are already tied to the I2C adapter.
> So the ACPI has no description of the fact that the ak8963 is 
> connected through the
> MPU device.  That's irritating.
>
>> We don't have a board setup file in PC like platform.
>> I have implemented in mux in MPU6XXX driver. But AK8963 driver is not
>> aware about mux adapter, it will not call my mux select function. So
>> I feel that we need to have a board setup file, to correctly create
>> i2C clients attaching to correct adapter for using this design. Is
>> this correct?
> It ought to be possible to do it from ACPI enumeration but
> only if there is some representation of the topology from ACPI.
> Otherwise we will need to represent this weirdness somewhere...
>
The ACPI definition currently defined for non-bypass mode for Win8 
driver in popular Asus T100 tablet.
I will hold onto my MPU6XXX patches for sometimes, till I find a way to 
introduce this weirdness somewhere in T100 specific platform driver.

Thanks,
Srinivas
>>
>> Thanks,
>> Srinivas
>>
>>
>>
>>
>>> 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,
>>>>
>>>
>>>
>>
>> -- 
>> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
> -- 
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

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

end of thread, other threads:[~2014-04-14  2:21 UTC | newest]

Thread overview: 17+ 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 ` Srinivas Pandruvada
     [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-19 16:56     ` 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:49         ` Jonathan Cameron
2014-04-11 23:24         ` Srinivas Pandruvada
2014-04-12 16:28           ` Jonathan Cameron
2014-04-14  2:21             ` Srinivas Pandruvada
2014-03-29 10:46   ` [Patch v1 1/4] iio: imu: inv_mpu6050: Add compatibity with MPU6500 Jonathan Cameron
2014-03-29 10:46     ` Jonathan Cameron
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-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
2014-03-29 10:59       ` 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.