drivers: iio: imu: Regulator changes for st sensor

The sensors are powered on through the
regulator by passing 3.3V to the sensor. These changes
provide regulator support for the asm330lhhx sensor.

Change-Id: Ia28d3caafb3d0900552cf01b30f4441357202eca
Signed-off-by: Raghava Chowdam <quic_rchowdam@quicinc.com>
This commit is contained in:
Raghava Chowdam 2024-03-12 12:42:21 +05:30
parent c54417a8db
commit cfc56e5ac8
6 changed files with 120 additions and 11 deletions

View File

@ -97,6 +97,7 @@ source "drivers/iio/imu/inv_icm42600/Kconfig"
source "drivers/iio/imu/inv_mpu6050/Kconfig"
source "drivers/iio/imu/st_lsm6dsx/Kconfig"
source "drivers/iio/imu/st_lsm9ds0/Kconfig"
source "drivers/iio/imu/st_asm330lhhx/Kconfig"
endmenu

View File

@ -28,3 +28,4 @@ obj-$(CONFIG_KMX61) += kmx61.o
obj-y += st_lsm6dsx/
obj-y += st_lsm9ds0/
obj-y += st_asm330lhhx/

View File

@ -21,7 +21,7 @@
#include <linux/regmap.h>
#include <linux/spinlock.h>
#include "../../common/stm_iio_types.h"
#include "stm_iio_types.h"
#define ST_ASM330LHHX_DEBUG_DISCHARGE
@ -751,6 +751,8 @@ struct st_asm330lhhx_hw {
s64 ts;
u8 i2c_master_pu;
u32 module_id;
struct regulator *vdd;
struct regulator *vio;
const struct st_asm330lhhx_odr_table_entry *odr_table_entry;
struct iio_dev *iio_devs[ST_ASM330LHHX_ID_MAX];

View File

@ -2314,11 +2314,108 @@ static int st_asm330lhhx_power_enable(struct st_asm330lhhx_hw *hw)
return 0;
}
static int st_asm330lhh_regulator_init(struct st_asm330lhhx_hw *hw)
{
hw->vdd = devm_regulator_get(hw->dev, "vdd");
if (IS_ERR(hw->vdd))
return dev_err_probe(hw->dev, PTR_ERR(hw->vdd), "Failed to get vdd");
hw->vio = devm_regulator_get(hw->dev, "vio");
if (IS_ERR(hw->vio))
return dev_err_probe(hw->dev, PTR_ERR(hw->vio), "Failed to get vio");
return 0;
}
static int st_asm330lhh_regulator_power_up(struct st_asm330lhhx_hw *hw)
{
struct device_node *np;
u32 vdd_voltage[2];
u32 vio_voltage[2];
u32 vdd_current = 30000;
u32 vio_current = 30000;
int err = 0;
np = hw->dev->of_node;
if (of_property_read_u32(np, "vio-min-voltage", &vio_voltage[0]))
vio_voltage[0] = 1620000;
if (of_property_read_u32(np, "vio-max-voltage", &vio_voltage[1]))
vio_voltage[1] = 3600000;
if (of_property_read_u32(np, "vdd-min-voltage", &vdd_voltage[0]))
vdd_voltage[0] = 3000000;
if (of_property_read_u32(np, "vdd-max-voltage", &vdd_voltage[1]))
vdd_voltage[1] = 3600000;
/* 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;
}
}
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;
}
}
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_asm330lhhx_probe(struct device *dev, int irq, int hw_id,
struct regmap *regmap)
{
struct st_asm330lhhx_hw *hw;
int i, err;
struct device_node *np;
int i = 0, err = 0;
hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
if (!hw)
@ -2336,6 +2433,23 @@ int st_asm330lhhx_probe(struct device *dev, int irq, int hw_id,
hw->odr_table_entry = st_asm330lhhx_odr_table;
hw->hw_timestamp_global = 0;
np = hw->dev->of_node;
/* use qtimer if property is enabled */
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_asm330lhhx_power_enable(hw);
if (err != 0)
return err;

View File

@ -626,15 +626,6 @@ int st_asm330lhhx_probe_event(struct st_asm330lhhx_hw *hw)
iio_dev->trig = iio_trigger_get(sensor->trig);
}
for (i = ST_ASM330LHHX_ID_EVENT; i < ST_ASM330LHHX_ID_MAX; i++) {
if (!hw->iio_devs[i])
continue;
err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
if (err)
return err;
}
return 0;
}
#endif /* CONFIG_IIO_ST_ASM330LHHX_EN_BASIC_FEATURES */