Add support for the VDD and VDDIO regulators using the regulator framework. Signed-off-by: Dan Robertson <dan@xxxxxxxxxxxxxxx> --- drivers/iio/accel/Kconfig | 1 + drivers/iio/accel/bma400_core.c | 49 +++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index 670e60568033..9cfe9c790190 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -116,6 +116,7 @@ config BMA400 tristate "Bosch BMA400 3-Axis Accelerometer Driver" select REGMAP select BMA400_I2C if I2C + select REGULATOR help Say Y here if you want to build a driver for the Bosch BMA400 triaxial acceleration sensor. diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index b97b8ea7fbb7..dd1edecc46f6 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -19,6 +19,7 @@ #include <linux/module.h> #include <linux/mutex.h> #include <linux/regmap.h> +#include <linux/regulator/consumer.h> #include "bma400.h" @@ -53,6 +54,8 @@ struct bma400_sample_freq { struct bma400_data { struct device *dev; struct regmap *regmap; + struct regulator *vdd_supply; + struct regulator *vddio_supply; struct mutex mutex; /* data register lock */ struct iio_mount_matrix orientation; enum bma400_power_mode power_mode; @@ -574,17 +577,46 @@ static int bma400_init(struct bma400_data *data) goto out; } + data->vdd_supply = devm_regulator_get(data->dev, "vdd"); + if (IS_ERR(data->vdd_supply)) { + ret = PTR_ERR(data->vdd_supply); + if (ret != -EPROBE_DEFER) + dev_err(data->dev, "Failed to get VDD regulator %d\n", + ret); + goto out; + } + ret = regulator_enable(data->vdd_supply); + if (ret) { + dev_err(data->dev, "Failed to enable VDD regulator: %d\n", ret); + goto err_vdd; + } + + data->vddio_supply = devm_regulator_get(data->dev, "vddio"); + if (IS_ERR(data->vddio_supply)) { + ret = PTR_ERR(data->vddio_supply); + if (ret != -EPROBE_DEFER) + dev_err(data->dev, "Failed to get VDDIO regulator %d\n", + ret); + goto err_vdd; + } + ret = regulator_enable(data->vddio_supply); + if (ret) { + dev_err(data->dev, "Failed to enable VDDIO regulator: %d\n", + ret); + goto err_vdd; + } + ret = bma400_get_power_mode(data); if (ret < 0) { dev_err(data->dev, "Failed to get the initial power-mode\n"); - goto out; + goto err_vddio; } if (data->power_mode != POWER_MODE_NORMAL) { ret = bma400_set_power_mode(data, POWER_MODE_NORMAL); if (ret < 0) { dev_err(data->dev, "Failed to wake up the device\n"); - goto out; + goto err_vddio; } /* * TODO: The datasheet waits 1500us here in the example, but @@ -597,15 +629,15 @@ static int bma400_init(struct bma400_data *data) ret = bma400_get_accel_output_data_rate(data); if (ret < 0) - goto out; + goto err_vddio; ret = bma400_get_accel_oversampling_ratio(data); if (ret < 0) - goto out; + goto err_vddio; ret = bma400_get_accel_scale(data); if (ret < 0) - goto out; + goto err_vddio; /* * Once the interrupt engine is supported we might use the @@ -615,6 +647,10 @@ static int bma400_init(struct bma400_data *data) */ return regmap_write(data->regmap, BMA400_ACC_CONFIG2_REG, 0x00); +err_vddio: + regulator_disable(data->vddio_supply); +err_vdd: + regulator_disable(data->vdd_supply); out: return ret; } @@ -810,6 +846,9 @@ int bma400_remove(struct device *dev) ret = bma400_set_power_mode(data, POWER_MODE_SLEEP); mutex_unlock(&data->mutex); + regulator_disable(data->vddio_supply); + regulator_disable(data->vdd_supply); + iio_device_unregister(indio_dev); return ret;