14
14
#include <zephyr/kernel.h>
15
15
#include <zephyr/device.h>
16
16
#include <zephyr/init.h>
17
+ #include <zephyr/pm/device.h>
17
18
#include <string.h>
18
19
#include <zephyr/sys/__assert.h>
19
20
#include <zephyr/logging/log.h>
20
21
22
+ #include <zephyr/dt-bindings/sensor/lsm6dsv16x.h>
21
23
#include "lsm6dsv16x.h"
22
24
#include "lsm6dsv16x_decoder.h"
23
25
#include "lsm6dsv16x_rtio.h"
24
26
25
27
LOG_MODULE_REGISTER (LSM6DSV16X , CONFIG_SENSOR_LOG_LEVEL );
26
28
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
+
27
40
/*
28
41
* values taken from lsm6dsv16x_data_rate_t in hal/st module. The mode/accuracy
29
42
* should be selected through accel-odr property in DT
@@ -361,6 +374,10 @@ static int lsm6dsv16x_attr_set(const struct device *dev,
361
374
struct lsm6dsv16x_data * data = dev -> data ;
362
375
#endif /* CONFIG_LSM6DSV16X_SENSORHUB */
363
376
377
+ if (!lsm6dsv16x_is_active (dev )) {
378
+ return - EBUSY ;
379
+ }
380
+
364
381
switch (chan ) {
365
382
case SENSOR_CHAN_ACCEL_XYZ :
366
383
return lsm6dsv16x_accel_config (dev , chan , attr , val );
@@ -517,6 +534,10 @@ static int lsm6dsv16x_attr_get(const struct device *dev,
517
534
enum sensor_attribute attr ,
518
535
struct sensor_value * val )
519
536
{
537
+ if (!lsm6dsv16x_is_active (dev )) {
538
+ return - EBUSY ;
539
+ }
540
+
520
541
switch (chan ) {
521
542
case SENSOR_CHAN_ACCEL_XYZ :
522
543
return lsm6dsv16x_accel_get_config (dev , chan , attr , val );
@@ -593,6 +614,10 @@ static int lsm6dsv16x_sample_fetch(const struct device *dev,
593
614
struct lsm6dsv16x_data * data = dev -> data ;
594
615
#endif /* CONFIG_LSM6DSV16X_SENSORHUB */
595
616
617
+ if (!lsm6dsv16x_is_active (dev )) {
618
+ return - EBUSY ;
619
+ }
620
+
596
621
switch (chan ) {
597
622
case SENSOR_CHAN_ACCEL_XYZ :
598
623
lsm6dsv16x_sample_fetch_accel (dev );
@@ -864,6 +889,10 @@ static int lsm6dsv16x_channel_get(const struct device *dev,
864
889
{
865
890
struct lsm6dsv16x_data * data = dev -> data ;
866
891
892
+ if (!lsm6dsv16x_is_active (dev )) {
893
+ return - EBUSY ;
894
+ }
895
+
867
896
switch (chan ) {
868
897
case SENSOR_CHAN_ACCEL_X :
869
898
case SENSOR_CHAN_ACCEL_Y :
@@ -1099,6 +1128,46 @@ static int lsm6dsv16x_init(const struct device *dev)
1099
1128
return 0 ;
1100
1129
}
1101
1130
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
+
1102
1171
#if DT_NUM_INST_STATUS_OKAY (DT_DRV_COMPAT ) == 0
1103
1172
#warning "LSM6DSV16X driver enabled without any devices"
1104
1173
#endif
@@ -1108,15 +1177,12 @@ static int lsm6dsv16x_init(const struct device *dev)
1108
1177
* LSM6DSV16X_DEFINE_I2C().
1109
1178
*/
1110
1179
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);
1120
1186
1121
1187
#ifdef CONFIG_LSM6DSV16X_TRIGGER
1122
1188
#define LSM6DSV16X_CFG_IRQ (inst ) \
0 commit comments