sensor: lps22hh: add device power management support

Registers driver with pm_device_driver_init(); implements TURN_ON,
SUSPEND and RESUME.  Sets ODR = 0 on suspend per datasheet

Signed-off-by: Van Petrosyan <van.petrosyan@sensirion.com>
This commit is contained in:
Van Petrosyan 2025-06-04 16:57:48 +02:00 committed by Anas Nashif
commit 1aa07db0ae

View file

@ -12,8 +12,7 @@
#include <zephyr/drivers/sensor.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/pm/device.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/logging/log.h>
@ -180,26 +179,11 @@ static DEVICE_API(sensor, lps22hh_driver_api) = {
static int lps22hh_init_chip(const struct device *dev)
{
const struct lps22hh_config * const cfg = dev->config;
struct lps22hh_data *data = dev->data;
const struct lps22hh_config *const cfg = dev->config;
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
uint8_t chip_id;
int ret;
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c)
if (cfg->i3c.bus != NULL) {
/*
* Need to grab the pointer to the I3C device descriptor
* before we can talk to the sensor.
*/
data->i3c_dev = i3c_device_find(cfg->i3c.bus, &cfg->i3c.dev_id);
if (data->i3c_dev == NULL) {
LOG_ERR("Cannot find I3C device descriptor");
return -ENODEV;
}
}
#endif
if (lps22hh_device_id_get(ctx, &chip_id) < 0) {
LOG_ERR("%s: Not able to read dev id", dev->name);
return -EIO;
@ -232,8 +216,6 @@ static int lps22hh_init_chip(const struct device *dev)
return ret;
}
}
#else
ARG_UNUSED(data);
#endif
/* set sensor default odr */
@ -252,13 +234,64 @@ static int lps22hh_init_chip(const struct device *dev)
return 0;
}
static int lps22hh_init(const struct device *dev)
static int lps22hh_pm_action(const struct device* dev, enum pm_device_action action)
{
if (lps22hh_init_chip(dev) < 0) {
LOG_DBG("Failed to initialize chip");
return -EIO;
const struct lps22hh_config* cfg = dev->config;
int ret = 0;
switch (action) {
case PM_DEVICE_ACTION_TURN_ON:
/* Full chip bringup */
ret = lps22hh_init_chip(dev);
if (ret != 0) {
LOG_ERR("%s: failed to initialise chip: %d", dev->name, ret);
}
break;
case PM_DEVICE_ACTION_RESUME:
ret = lps22hh_set_odr_raw(dev, cfg->odr);
if (ret != 0) {
LOG_ERR("%s: Failed to set odr %d", dev->name, cfg->odr);
}
break;
case PM_DEVICE_ACTION_SUSPEND:
/* set odr to 0 for power-down mode */
ret = lps22hh_set_odr_raw(dev, 0);
if (ret != 0) {
LOG_ERR("%s: Failed to reset odr", dev->name);
}
break;
case PM_DEVICE_ACTION_TURN_OFF:
break;
default:
ret = -ENOTSUP;
break;
}
return ret;
}
static int lps22hh_init(const struct device *dev)
{
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c)
const struct lps22hh_config *const cfg = dev->config;
struct lps22hh_data *data = dev->data;
if (cfg->i3c.bus != NULL) {
/*
* Need to grab the pointer to the I3C device descriptor
* before we can talk to the sensor.
*/
data->i3c_dev = i3c_device_find(cfg->i3c.bus, &cfg->i3c.dev_id);
if (data->i3c_dev == NULL) {
LOG_ERR("Cannot find I3C device descriptor");
return -ENODEV;
}
}
#endif
#ifdef CONFIG_LPS22HH_TRIGGER
if (lps22hh_init_interrupt(dev) < 0) {
LOG_ERR("Failed to initialize interrupt.");
@ -266,7 +299,7 @@ static int lps22hh_init(const struct device *dev)
}
#endif
return 0;
return pm_device_driver_init(dev, lps22hh_pm_action);
}
#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
@ -351,7 +384,8 @@ static int lps22hh_init(const struct device *dev)
(COND_CODE_1(DT_INST_ON_BUS(inst, i3c), \
(LPS22HH_CONFIG_I3C_OR_I2C(inst)), \
(LPS22HH_CONFIG_I2C(inst))))); \
SENSOR_DEVICE_DT_INST_DEFINE(inst, lps22hh_init, NULL, &lps22hh_data_##inst, \
PM_DEVICE_DT_INST_DEFINE(inst, lps22hh_pm_action); \
SENSOR_DEVICE_DT_INST_DEFINE(inst, lps22hh_init, PM_DEVICE_DT_INST_GET(inst), &lps22hh_data_##inst, \
&lps22hh_config_##inst, POST_KERNEL, \
CONFIG_SENSOR_INIT_PRIORITY, &lps22hh_driver_api);