mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
Merge "drivers: iio: imu: asm330 regulators"
This commit is contained in:
commit
403f8234a5
@ -210,6 +210,8 @@ struct st_asm330lhh_hw {
|
||||
|
||||
const struct st_asm330lhh_transfer_function *tf;
|
||||
struct st_asm330lhh_transfer_buffer tb;
|
||||
struct regulator *vdd;
|
||||
struct regulator *vio;
|
||||
};
|
||||
|
||||
extern const struct dev_pm_ops st_asm330lhh_pm_ops;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <linux/pm.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <linux/platform_data/st_sensors_pdata.h>
|
||||
|
||||
@ -707,11 +708,115 @@ static struct iio_dev *st_asm330lhh_alloc_iiodev(struct st_asm330lhh_hw *hw,
|
||||
return iio_dev;
|
||||
}
|
||||
|
||||
static void st_asm330lhh_regulator_power_down(struct st_asm330lhh_hw *hw)
|
||||
{
|
||||
regulator_disable(hw->vdd);
|
||||
regulator_set_voltage(hw->vdd, 0, INT_MAX);
|
||||
regulator_set_load(hw->vdd, 0);
|
||||
regulator_disable(hw->vio);
|
||||
regulator_set_voltage(hw->vio, 0, INT_MAX);
|
||||
regulator_set_load(hw->vio, 0);
|
||||
}
|
||||
|
||||
static int st_asm330lhh_regulator_init(struct st_asm330lhh_hw *hw)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
hw->vdd = devm_regulator_get(hw->dev, "vdd");
|
||||
if (IS_ERR(hw->vdd)) {
|
||||
err = PTR_ERR(hw->vdd);
|
||||
if (err != -EPROBE_DEFER)
|
||||
dev_err(hw->dev, "Error %d to get vdd\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
hw->vio = devm_regulator_get(hw->dev, "vio");
|
||||
if (IS_ERR(hw->vio)) {
|
||||
err = PTR_ERR(hw->vio);
|
||||
if (err != -EPROBE_DEFER)
|
||||
dev_err(hw->dev, "Error %d to get vio\n", err);
|
||||
return err;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int st_asm330lhh_regulator_power_up(struct st_asm330lhh_hw *hw)
|
||||
{
|
||||
u32 vdd_voltage[2] = {3000000, 3600000};
|
||||
u32 vio_voltage[2] = {1620000, 3600000};
|
||||
u32 vdd_current = 30000;
|
||||
u32 vio_current = 30000;
|
||||
int err = 0;
|
||||
|
||||
/* Enable VDD for ASM330 */
|
||||
if (vdd_voltage[0] > 0 && vdd_voltage[0] <= vdd_voltage[1]) {
|
||||
err = regulator_set_voltage(hw->vdd, vdd_voltage[0],
|
||||
vdd_voltage[1]);
|
||||
if (err) {
|
||||
pr_err("Error %d during vdd set_voltage\n", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (vdd_current > 0) {
|
||||
err = regulator_set_load(hw->vdd, vdd_current);
|
||||
if (err < 0) {
|
||||
pr_err("vdd regulator_set_load failed,err=%d\n", err);
|
||||
goto remove_vdd_voltage;
|
||||
}
|
||||
}
|
||||
|
||||
err = regulator_enable(hw->vdd);
|
||||
if (err) {
|
||||
dev_err(hw->dev, "vdd enable failed with error %d\n", err);
|
||||
goto remove_vdd_current;
|
||||
}
|
||||
|
||||
/* Enable VIO for ASM330 */
|
||||
if (vio_voltage[0] > 0 && vio_voltage[0] <= vio_voltage[1]) {
|
||||
err = regulator_set_voltage(hw->vio, vio_voltage[0],
|
||||
vio_voltage[1]);
|
||||
if (err) {
|
||||
pr_err("Error %d during vio set_voltage\n", err);
|
||||
goto disable_vdd;
|
||||
}
|
||||
}
|
||||
|
||||
if (vio_current > 0) {
|
||||
err = regulator_set_load(hw->vio, vio_current);
|
||||
if (err < 0) {
|
||||
pr_err("vio regulator_set_load failed,err=%d\n", err);
|
||||
goto remove_vio_voltage;
|
||||
}
|
||||
}
|
||||
|
||||
err = regulator_enable(hw->vio);
|
||||
if (err) {
|
||||
dev_err(hw->dev, "vio enable failed with error %d\n", err);
|
||||
goto remove_vio_current;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
remove_vio_current:
|
||||
regulator_set_load(hw->vio, 0);
|
||||
remove_vio_voltage:
|
||||
regulator_set_voltage(hw->vio, 0, INT_MAX);
|
||||
disable_vdd:
|
||||
regulator_disable(hw->vdd);
|
||||
remove_vdd_current:
|
||||
regulator_set_load(hw->vdd, 0);
|
||||
remove_vdd_voltage:
|
||||
regulator_set_voltage(hw->vdd, 0, INT_MAX);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int st_asm330lhh_probe(struct device *dev, int irq,
|
||||
const struct st_asm330lhh_transfer_function *tf_ops)
|
||||
{
|
||||
struct st_asm330lhh_hw *hw;
|
||||
int i, err;
|
||||
int i = 0, err = 0;
|
||||
|
||||
hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
|
||||
if (!hw)
|
||||
@ -727,24 +832,42 @@ int st_asm330lhh_probe(struct device *dev, int irq,
|
||||
hw->tf = tf_ops;
|
||||
|
||||
dev_info(hw->dev, "Ver: %s\n", ST_ASM330LHH_VERSION);
|
||||
|
||||
err = st_asm330lhh_regulator_init(hw);
|
||||
if (err < 0) {
|
||||
dev_err(hw->dev, "regulator init failed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
err = st_asm330lhh_regulator_power_up(hw);
|
||||
if (err < 0) {
|
||||
dev_err(hw->dev, "regulator power up failed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* allow time for enabling regulators */
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
err = st_asm330lhh_check_whoami(hw);
|
||||
if (err < 0)
|
||||
return err;
|
||||
goto regulator_shutdown;
|
||||
|
||||
err = st_asm330lhh_init_device(hw);
|
||||
if (err < 0)
|
||||
return err;
|
||||
goto regulator_shutdown;
|
||||
|
||||
for (i = 0; i < ST_ASM330LHH_ID_MAX; i++) {
|
||||
hw->iio_devs[i] = st_asm330lhh_alloc_iiodev(hw, i);
|
||||
if (!hw->iio_devs[i])
|
||||
return -ENOMEM;
|
||||
if (!hw->iio_devs[i]) {
|
||||
err = -ENOMEM;
|
||||
goto regulator_shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
if (hw->irq > 0) {
|
||||
err = st_asm330lhh_fifo_setup(hw);
|
||||
if (err < 0)
|
||||
return err;
|
||||
goto regulator_shutdown;
|
||||
}
|
||||
|
||||
for (i = 0; i < ST_ASM330LHH_ID_MAX; i++) {
|
||||
@ -753,12 +876,17 @@ int st_asm330lhh_probe(struct device *dev, int irq,
|
||||
|
||||
err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
|
||||
if (err)
|
||||
return err;
|
||||
goto regulator_shutdown;
|
||||
}
|
||||
|
||||
dev_info(hw->dev, "probe ok\n");
|
||||
|
||||
return 0;
|
||||
|
||||
regulator_shutdown:
|
||||
st_asm330lhh_regulator_power_down(hw);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(st_asm330lhh_probe);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user