On Tue, 17 Jul 2018 04:41:52 -0400 Brian Masney <masneyb@xxxxxxxxxxxxx> wrote: > This patch adds support for the regulator framework to the mpu6050 > driver. > > Signed-off-by: Brian Masney <masneyb@xxxxxxxxxxxxx> > Signed-off-by: Jonathan Marek <jonathan@xxxxxxxx> I'm not 100% sure what the purpose of the regulator_enabled tracking is. Perhaps you could point out the path where that is needed? Also, a missing bit of documentation needs adding. Jonathan > --- > Changes since v1: > - Use devm_regulator_get() instead of devm_regulator_get_optional() > - Use devm_add_action() for cleaning up the regulator. > - Correct ordering of resume code. > - Add regulator_enabled flag to ensure regulator is not disabled twice, > specifically the case where the device is suspended and then the > driver is removed. > > Original extra changelog from v1: > > 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. > - 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 | 73 +++++++++++++++++++ > drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 3 + > 3 files changed, 77 insertions(+) > > 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..e1fbab4bc0a0 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,46 @@ 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) { > + dev_err(regmap_get_device(st->map), > + "Failed to enable regulator: %d\n", result); > + } else { > + st->regulator_enabled = true; > + > + /* Give the device a little bit of time to start up. */ > + usleep_range(35000, 70000); > + } > + > + return result; > +} > + > +static int inv_mpu_core_disable_regulator(struct inv_mpu6050_state *st) > +{ > + int result; > + > + if (!st->regulator_enabled) > + return 0; > + > + result = regulator_disable(st->vddio_supply); > + if (result) > + dev_err(regmap_get_device(st->map), > + "Failed to disable regulator: %d\n", result); > + > + st->regulator_enabled = false; > + > + return result; > +} > + > +static void inv_mpu_core_disable_regulator_action(void *_data) > +{ > + inv_mpu_core_disable_regulator(_data); > +} > + > 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,6 +1031,28 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, > return -EINVAL; > } > > + st->vddio_supply = devm_regulator_get(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; > + > + result = devm_add_action(dev, inv_mpu_core_disable_regulator_action, > + st); > + if (result) { > + inv_mpu_core_disable_regulator_action(st); > + dev_err(dev, "Failed to setup regulator cleanup action %d\n", > + result); > + return result; > + } > + > /* power is turned on inside check chip type*/ > result = inv_check_and_setup_chip(st); > if (result) > @@ -1049,7 +1112,12 @@ static int inv_mpu_resume(struct device *dev) > int result; > > mutex_lock(&st->lock); > + result = inv_mpu_core_enable_regulator(st); > + if (result) > + goto out_unlock; > + > result = inv_mpu6050_set_power_itg(st, true); > +out_unlock: > mutex_unlock(&st->lock); > > return result; > @@ -1062,6 +1130,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 = inv_mpu_core_disable_regulator(st); > +out_unlock: > mutex_unlock(&st->lock); > > 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 e69a59659dbc..01c8fe9b4fa0 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. Docs missing for regulator_enabled. > */ > struct inv_mpu6050_state { > struct mutex lock; > @@ -149,6 +150,8 @@ struct inv_mpu6050_state { > s64 chip_period; > s64 it_timestamp; > s64 data_timestamp; > + struct regulator *vddio_supply; > + bool regulator_enabled; > }; > > /*register and associated bit definition*/ -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html