[2/3] iio: imu: mpu6050: add support for regulator framework
diff mbox

Message ID 20180711010932.20313-3-masneyb@onstation.org
State New
Headers show

Commit Message

Brian Masney July 11, 2018, 1:09 a.m. UTC
This patch adds support for the regulator framework to the mpu6050
driver.

Signed-off-by: Brian Masney <masneyb@onstation.org>
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
---
This is a variation of Jonathan Marek's patch from postmarketOS
https://gitlab.com/postmarketOS/linux-postmarketos/commit/b8ad1ec1859c8bbcbce94944b3f4dd68f8f9fc37
with the following changes:

- Stripped out 6515 variant code. (See my previous patch in this series)
- Add the regulator to the mpu core instead of only the i2c variant.
- Add error handling.
- Release the regulator on suspend, device remove, etc.
- Device tree documentation.

 .../bindings/iio/imu/inv_mpu6050.txt          |  1 +
 drivers/iio/imu/inv_mpu6050/inv_mpu_core.c    | 57 +++++++++++++++++--
 drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c     |  2 +-
 drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h     |  3 +
 drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c     |  9 +++
 5 files changed, 66 insertions(+), 6 deletions(-)

Comments

kernel test robot July 11, 2018, 8:50 a.m. UTC | #1
Hi Brian,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on iio/togreg]
[also build test ERROR on next-20180710]
[cannot apply to v4.18-rc4]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Brian-Masney/iio-imu-mpu6050-add-support-for-6515-variant/20180711-092023
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg
config: x86_64-allmodconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

>> ERROR: "inv_mpu_core_remove" [drivers/iio/imu/inv_mpu6050/inv-mpu6050-spi.ko] undefined!
>> ERROR: "inv_mpu_core_remove" [drivers/iio/imu/inv_mpu6050/inv-mpu6050-i2c.ko] undefined!

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Brian Masney July 11, 2018, 9:07 a.m. UTC | #2
On Wed, Jul 11, 2018 at 04:50:22PM +0800, kbuild test robot wrote:
> Hi Brian,
> 
> Thank you for the patch! Yet something to improve:
> 
> [auto build test ERROR on iio/togreg]
> [also build test ERROR on next-20180710]
> [cannot apply to v4.18-rc4]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Brian-Masney/iio-imu-mpu6050-add-support-for-6515-variant/20180711-092023
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg
> config: x86_64-allmodconfig (attached as .config)
> compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64 
> 
> All errors (new ones prefixed by >>):
> 
> >> ERROR: "inv_mpu_core_remove" [drivers/iio/imu/inv_mpu6050/inv-mpu6050-spi.ko] undefined!
> >> ERROR: "inv_mpu_core_remove" [drivers/iio/imu/inv_mpu6050/inv-mpu6050-i2c.ko] undefined!

This patch applies cleanly against the iio/testing branch.

https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git/log/?h=testing

Brian
--
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
Himanshu Jha July 11, 2018, 10:04 a.m. UTC | #3
Hi Brain,

On Tue, Jul 10, 2018 at 09:09:31PM -0400, Brian Masney wrote:
> This patch adds support for the regulator framework to the mpu6050
> driver.
> 
> Signed-off-by: Brian Masney <masneyb@onstation.org>
> Signed-off-by: Jonathan Marek <jonathan@marek.ca>
> ---
>  }
>  EXPORT_SYMBOL_GPL(inv_mpu_core_probe);
>  
> +int inv_mpu_core_remove(struct inv_mpu6050_state *st)
> +{
> +	return regulator_disable(st->vddio_supply);
> +}
EXPORT_SYMBOL_GPL(inv_mpu_core_remove); ?

This is causing 0-day test build failure perhaps.
Brian Masney July 11, 2018, 10:31 a.m. UTC | #4
On Wed, Jul 11, 2018 at 03:34:43PM +0530, Himanshu Jha wrote:
> Hi Brain,
> 
> On Tue, Jul 10, 2018 at 09:09:31PM -0400, Brian Masney wrote:
> > This patch adds support for the regulator framework to the mpu6050
> > driver.
> > 
> > Signed-off-by: Brian Masney <masneyb@onstation.org>
> > Signed-off-by: Jonathan Marek <jonathan@marek.ca>
> > ---
> >  }
> >  EXPORT_SYMBOL_GPL(inv_mpu_core_probe);
> >  
> > +int inv_mpu_core_remove(struct inv_mpu6050_state *st)
> > +{
> > +	return regulator_disable(st->vddio_supply);
> > +}
> EXPORT_SYMBOL_GPL(inv_mpu_core_remove); ?
> 
> This is causing 0-day test build failure perhaps.

You are right. It compiles if I have CONFIG_INV_MPU6050_IIO built into
the kernel, which is what I'm using to boot the board, but fails when
compiled as a module. Good catch 0-day!

The patch won't apply to Linus's current master branch and I assumed
that iio/togreg didn't have the required changes as well. Sorry about
the noise.

I'll send a v2 before the weekend.

Brian
--
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

Patch
diff mbox

diff --git a/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt b/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt
index b7def51c8ad9..d39907b12a46 100644
--- a/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt
+++ b/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt
@@ -21,6 +21,7 @@  Required properties:
   bindings.
 
 Optional properties:
+ - vddio-supply: regulator phandle for VDDIO supply
  - mount-matrix: an optional 3x3 mounting rotation matrix
  - i2c-gate node.  These devices also support an auxiliary i2c bus.  This is
    simple enough to be described using the i2c-gate binding. See
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index 12c1b9507007..ec276b7bcc69 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -23,6 +23,7 @@ 
 #include <linux/iio/iio.h>
 #include <linux/acpi.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 #include "inv_mpu_iio.h"
 
 /*
@@ -926,6 +927,19 @@  static int inv_check_and_setup_chip(struct inv_mpu6050_state *st)
 	return result;
 }
 
+static int inv_mpu_core_enable_regulator(struct inv_mpu6050_state *st)
+{
+	int result;
+
+	result = regulator_enable(st->vddio_supply);
+	if (result == 0) {
+		/* Give the device a little bit of time to start up. */
+		usleep_range(35000, 70000);
+	}
+
+	return result;
+}
+
 int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
 		int (*inv_mpu_bus_setup)(struct iio_dev *), int chip_type)
 {
@@ -990,15 +1004,28 @@  int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
 		return -EINVAL;
 	}
 
+	st->vddio_supply = devm_regulator_get_optional(dev, "vddio");
+	if (IS_ERR(st->vddio_supply)) {
+		if (PTR_ERR(st->vddio_supply) != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get vddio regulator %d\n",
+				(int)PTR_ERR(st->vddio_supply));
+
+		return PTR_ERR(st->vddio_supply);
+	}
+
+	result = inv_mpu_core_enable_regulator(st);
+	if (result)
+		return result;
+
 	/* power is turned on inside check chip type*/
 	result = inv_check_and_setup_chip(st);
 	if (result)
-		return result;
+		goto out_disable_regulator;
 
 	result = inv_mpu6050_init_config(indio_dev);
 	if (result) {
 		dev_err(dev, "Could not initialize device.\n");
-		return result;
+		goto out_disable_regulator;
 	}
 
 	if (inv_mpu_bus_setup)
@@ -1023,24 +1050,34 @@  int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
 						 NULL);
 	if (result) {
 		dev_err(dev, "configure buffer fail %d\n", result);
-		return result;
+		goto out_disable_regulator;
 	}
 	result = inv_mpu6050_probe_trigger(indio_dev, irq_type);
 	if (result) {
 		dev_err(dev, "trigger probe fail %d\n", result);
-		return result;
+		goto out_disable_regulator;
 	}
 
 	result = devm_iio_device_register(dev, indio_dev);
 	if (result) {
 		dev_err(dev, "IIO register fail %d\n", result);
-		return result;
+		goto out_disable_regulator;
 	}
 
 	return 0;
+
+out_disable_regulator:
+	regulator_disable(st->vddio_supply);
+	return result;
+
 }
 EXPORT_SYMBOL_GPL(inv_mpu_core_probe);
 
+int inv_mpu_core_remove(struct inv_mpu6050_state *st)
+{
+	return regulator_disable(st->vddio_supply);
+}
+
 #ifdef CONFIG_PM_SLEEP
 
 static int inv_mpu_resume(struct device *dev)
@@ -1050,6 +1087,11 @@  static int inv_mpu_resume(struct device *dev)
 
 	mutex_lock(&st->lock);
 	result = inv_mpu6050_set_power_itg(st, true);
+	if (result)
+		goto out_unlock;
+
+	result = inv_mpu_core_enable_regulator(st);
+out_unlock:
 	mutex_unlock(&st->lock);
 
 	return result;
@@ -1062,6 +1104,11 @@  static int inv_mpu_suspend(struct device *dev)
 
 	mutex_lock(&st->lock);
 	result = inv_mpu6050_set_power_itg(st, false);
+	if (result)
+		goto out_unlock;
+
+	result = regulator_disable(st->vddio_supply);
+out_unlock:
 	mutex_unlock(&st->lock);
 
 	return result;
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
index dd758e3d403d..ce227038c61c 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
@@ -164,7 +164,7 @@  static int inv_mpu_remove(struct i2c_client *client)
 		i2c_mux_del_adapters(st->muxc);
 	}
 
-	return 0;
+	return inv_mpu_core_remove(st);
 }
 
 /*
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
index e69a59659dbc..0289615a6135 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
@@ -129,6 +129,7 @@  struct inv_mpu6050_hw {
  *  @chip_period:	chip internal period estimation (~1kHz).
  *  @it_timestamp:	timestamp from previous interrupt.
  *  @data_timestamp:	timestamp for next data sample.
+ *  @vddio_supply	voltage regulator for the chip.
  */
 struct inv_mpu6050_state {
 	struct mutex lock;
@@ -149,6 +150,7 @@  struct inv_mpu6050_state {
 	s64 chip_period;
 	s64 it_timestamp;
 	s64 data_timestamp;
+	struct regulator *vddio_supply;
 };
 
 /*register and associated bit definition*/
@@ -321,4 +323,5 @@  int inv_mpu_acpi_create_mux_client(struct i2c_client *client);
 void inv_mpu_acpi_delete_mux_client(struct i2c_client *client);
 int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name,
 		int (*inv_mpu_bus_setup)(struct iio_dev *), int chip_type);
+int inv_mpu_core_remove(struct inv_mpu6050_state *st);
 extern const struct dev_pm_ops inv_mpu_pmops;
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
index 227f50afff22..fce935f8f1e4 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
@@ -70,6 +70,14 @@  static int inv_mpu_probe(struct spi_device *spi)
 				  inv_mpu_i2c_disable, chip_type);
 }
 
+static int inv_mpu_remove(struct spi_device *spi)
+{
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct inv_mpu6050_state *st = iio_priv(indio_dev);
+
+	return inv_mpu_core_remove(st);
+}
+
 /*
  * device id table is used to identify what device can be
  * supported by this driver
@@ -94,6 +102,7 @@  MODULE_DEVICE_TABLE(acpi, inv_acpi_match);
 
 static struct spi_driver inv_mpu_driver = {
 	.probe		=	inv_mpu_probe,
+	.remove		=	inv_mpu_remove,
 	.id_table	=	inv_mpu_id,
 	.driver = {
 		.acpi_match_table = ACPI_PTR(inv_acpi_match),