Skip to content

Commit 3fef72a

Browse files
xodus7kartben
authored andcommitted
drivers: sensor: lsm6dsv16x: add device PM support
Adds a device PM handling which will ensure acc/gyro channels are off when the device is suspended. Signed-off-by: Corey Wharton <xodus7@cwharton.com>
1 parent 9a00bc6 commit 3fef72a

File tree

4 files changed

+85
-9
lines changed

4 files changed

+85
-9
lines changed

drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,29 @@
1414
#include <zephyr/kernel.h>
1515
#include <zephyr/device.h>
1616
#include <zephyr/init.h>
17+
#include <zephyr/pm/device.h>
1718
#include <string.h>
1819
#include <zephyr/sys/__assert.h>
1920
#include <zephyr/logging/log.h>
2021

22+
#include <zephyr/dt-bindings/sensor/lsm6dsv16x.h>
2123
#include "lsm6dsv16x.h"
2224
#include "lsm6dsv16x_decoder.h"
2325
#include "lsm6dsv16x_rtio.h"
2426

2527
LOG_MODULE_REGISTER(LSM6DSV16X, CONFIG_SENSOR_LOG_LEVEL);
2628

29+
bool lsm6dsv16x_is_active(const struct device *dev)
30+
{
31+
#if defined(CONFIG_PM_DEVICE)
32+
enum pm_device_state state;
33+
(void)pm_device_state_get(dev, &state);
34+
return (state == PM_DEVICE_STATE_ACTIVE);
35+
#else
36+
return true;
37+
#endif /* CONFIG_PM_DEVICE*/
38+
}
39+
2740
/*
2841
* values taken from lsm6dsv16x_data_rate_t in hal/st module. The mode/accuracy
2942
* should be selected through accel-odr property in DT
@@ -361,6 +374,10 @@ static int lsm6dsv16x_attr_set(const struct device *dev,
361374
struct lsm6dsv16x_data *data = dev->data;
362375
#endif /* CONFIG_LSM6DSV16X_SENSORHUB */
363376

377+
if (!lsm6dsv16x_is_active(dev)) {
378+
return -EBUSY;
379+
}
380+
364381
switch (chan) {
365382
case SENSOR_CHAN_ACCEL_XYZ:
366383
return lsm6dsv16x_accel_config(dev, chan, attr, val);
@@ -517,6 +534,10 @@ static int lsm6dsv16x_attr_get(const struct device *dev,
517534
enum sensor_attribute attr,
518535
struct sensor_value *val)
519536
{
537+
if (!lsm6dsv16x_is_active(dev)) {
538+
return -EBUSY;
539+
}
540+
520541
switch (chan) {
521542
case SENSOR_CHAN_ACCEL_XYZ:
522543
return lsm6dsv16x_accel_get_config(dev, chan, attr, val);
@@ -593,6 +614,10 @@ static int lsm6dsv16x_sample_fetch(const struct device *dev,
593614
struct lsm6dsv16x_data *data = dev->data;
594615
#endif /* CONFIG_LSM6DSV16X_SENSORHUB */
595616

617+
if (!lsm6dsv16x_is_active(dev)) {
618+
return -EBUSY;
619+
}
620+
596621
switch (chan) {
597622
case SENSOR_CHAN_ACCEL_XYZ:
598623
lsm6dsv16x_sample_fetch_accel(dev);
@@ -864,6 +889,10 @@ static int lsm6dsv16x_channel_get(const struct device *dev,
864889
{
865890
struct lsm6dsv16x_data *data = dev->data;
866891

892+
if (!lsm6dsv16x_is_active(dev)) {
893+
return -EBUSY;
894+
}
895+
867896
switch (chan) {
868897
case SENSOR_CHAN_ACCEL_X:
869898
case SENSOR_CHAN_ACCEL_Y:
@@ -1099,6 +1128,46 @@ static int lsm6dsv16x_init(const struct device *dev)
10991128
return 0;
11001129
}
11011130

1131+
#if defined(CONFIG_PM_DEVICE)
1132+
static int lsm6dsv16x_pm_action(const struct device *dev, enum pm_device_action action)
1133+
{
1134+
struct lsm6dsv16x_data *data = dev->data;
1135+
const struct lsm6dsv16x_config *cfg = dev->config;
1136+
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
1137+
int ret = 0;
1138+
1139+
LOG_DBG("PM action: %d", (int)action);
1140+
1141+
switch (action) {
1142+
case PM_DEVICE_ACTION_RESUME:
1143+
if (lsm6dsv16x_xl_data_rate_set(ctx, data->accel_freq) < 0) {
1144+
LOG_ERR("failed to set accelerometer odr %d", (int)data->accel_freq);
1145+
ret = -EIO;
1146+
}
1147+
if (lsm6dsv16x_gy_data_rate_set(ctx, data->gyro_freq) < 0) {
1148+
LOG_ERR("failed to set gyroscope odr %d", (int)data->gyro_freq);
1149+
ret = -EIO;
1150+
}
1151+
break;
1152+
case PM_DEVICE_ACTION_SUSPEND:
1153+
if (lsm6dsv16x_xl_data_rate_set(ctx, LSM6DSV16X_DT_ODR_OFF) < 0) {
1154+
LOG_ERR("failed to disable accelerometer");
1155+
ret = -EIO;
1156+
}
1157+
if (lsm6dsv16x_gy_data_rate_set(ctx, LSM6DSV16X_DT_ODR_OFF) < 0) {
1158+
LOG_ERR("failed to disable gyroscope");
1159+
ret = -EIO;
1160+
}
1161+
break;
1162+
default:
1163+
ret = -ENOTSUP;
1164+
break;
1165+
}
1166+
1167+
return ret;
1168+
}
1169+
#endif /* CONFIG_PM_DEVICE */
1170+
11021171
#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
11031172
#warning "LSM6DSV16X driver enabled without any devices"
11041173
#endif
@@ -1108,15 +1177,12 @@ static int lsm6dsv16x_init(const struct device *dev)
11081177
* LSM6DSV16X_DEFINE_I2C().
11091178
*/
11101179

1111-
#define LSM6DSV16X_DEVICE_INIT(inst) \
1112-
SENSOR_DEVICE_DT_INST_DEFINE(inst, \
1113-
lsm6dsv16x_init, \
1114-
NULL, \
1115-
&lsm6dsv16x_data_##inst, \
1116-
&lsm6dsv16x_config_##inst, \
1117-
POST_KERNEL, \
1118-
CONFIG_SENSOR_INIT_PRIORITY, \
1119-
&lsm6dsv16x_driver_api);
1180+
#define LSM6DSV16X_DEVICE_INIT(inst) \
1181+
PM_DEVICE_DT_INST_DEFINE(inst, lsm6dsv16x_pm_action); \
1182+
SENSOR_DEVICE_DT_INST_DEFINE(inst, lsm6dsv16x_init, PM_DEVICE_DT_INST_GET(inst), \
1183+
&lsm6dsv16x_data_##inst, &lsm6dsv16x_config_##inst, \
1184+
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
1185+
&lsm6dsv16x_driver_api);
11201186

11211187
#ifdef CONFIG_LSM6DSV16X_TRIGGER
11221188
#define LSM6DSV16X_CFG_IRQ(inst) \

drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include <zephyr/drivers/i3c.h>
3131
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c) */
3232

33+
bool lsm6dsv16x_is_active(const struct device *dev);
34+
3335
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c)
3436
#define ON_I3C_BUS(cfg) (cfg->i3c.bus != NULL)
3537
#define I3C_INT_PIN(cfg) (cfg->int_en_i3c)

drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_rtio.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ void lsm6dsv16x_submit_sync(struct rtio_iodev_sqe *iodev_sqe)
153153

154154
void lsm6dsv16x_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe)
155155
{
156+
if (!lsm6dsv16x_is_active(dev)) {
157+
return;
158+
}
159+
156160
struct rtio_work_req *req = rtio_work_req_alloc();
157161

158162
if (req == NULL) {

drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_trigger.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ int lsm6dsv16x_trigger_set(const struct device *dev,
133133
return -EINVAL;
134134
}
135135

136+
if (!lsm6dsv16x_is_active(dev)) {
137+
return -EBUSY;
138+
}
139+
136140
switch (trig->type) {
137141
case SENSOR_TRIG_DATA_READY:
138142
if (trig->chan == SENSOR_CHAN_ACCEL_XYZ) {

0 commit comments

Comments
 (0)