drv: BME280 driver power management

Support for the OFF device power state to the BME280 sensor driver.

Signed-off-by: Maciej Kurc <mkurc1234@gmail.com>
This commit is contained in:
Maciej Kurc 2020-12-29 21:16:34 +01:00 committed by Maureen Helm
commit 086503abd5
2 changed files with 75 additions and 1 deletions

View file

@ -76,6 +76,10 @@ struct bme280_data {
int32_t t_fine; int32_t t_fine;
uint8_t chip_id; uint8_t chip_id;
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
uint32_t pm_state; /* Current power state */
#endif
}; };
struct bme280_spi_cfg { struct bme280_spi_cfg {
@ -318,6 +322,12 @@ static int bme280_sample_fetch(const struct device *dev,
__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
/* Do not allow sample fetching from OFF state */
if (data->pm_state == DEVICE_PM_OFF_STATE)
return -EIO;
#endif
#ifdef CONFIG_BME280_MODE_FORCED #ifdef CONFIG_BME280_MODE_FORCED
ret = bme280_reg_write(dev, BME280_REG_CTRL_MEAS, BME280_CTRL_MEAS_VAL); ret = bme280_reg_write(dev, BME280_REG_CTRL_MEAS, BME280_CTRL_MEAS_VAL);
if (ret < 0) { if (ret < 0) {
@ -575,6 +585,11 @@ int bme280_init(const struct device *dev)
rc = 0; rc = 0;
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
/* Set power state to ACTIVE */
data->pm_state = DEVICE_PM_ACTIVE_STATE;
#endif
done: done:
if (rc == 0) { if (rc == 0) {
LOG_DBG("%s OK", name); LOG_DBG("%s OK", name);
@ -584,6 +599,59 @@ done:
return rc; return rc;
} }
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
int bme280_pm_ctrl(const struct device *dev, uint32_t ctrl_command,
void *context, device_pm_cb cb, void *arg)
{
struct bme280_data *data = to_data(dev);
int ret = 0;
/* Set power state */
if (ctrl_command == DEVICE_PM_SET_POWER_STATE) {
uint32_t new_pm_state = *((const uint32_t *)context);
if (new_pm_state != data->pm_state) {
/* Switching from OFF to any */
if (data->pm_state == DEVICE_PM_OFF_STATE) {
/* Re-initialize the chip */
ret = bme280_chip_init(dev);
}
/* Switching to OFF from any */
else if (new_pm_state == DEVICE_PM_OFF_STATE) {
/* Put the chip into sleep mode */
ret = bme280_reg_write(dev,
BME280_REG_CTRL_MEAS,
BME280_CTRL_MEAS_OFF_VAL);
if (ret < 0)
LOG_DBG("CTRL_MEAS write failed: %d",
ret);
}
/* Store the new state */
if (!ret)
data->pm_state = new_pm_state;
}
}
/* Get power state */
else {
__ASSERT_NO_MSG(ctrl_command == DEVICE_PM_GET_POWER_STATE);
*((uint32_t *)context) = data->pm_state;
}
/* Invoke callback if any */
if (cb)
cb(dev, ret, context, arg);
return ret;
}
#endif /* CONFIG_DEVICE_POWER_MANAGEMENT */
/* /*
* Device creation macro, shared by BME280_DEFINE_SPI() and * Device creation macro, shared by BME280_DEFINE_SPI() and
* BME280_DEFINE_I2C(). * BME280_DEFINE_I2C().
@ -592,7 +660,7 @@ done:
#define BME280_DEVICE_INIT(inst) \ #define BME280_DEVICE_INIT(inst) \
DEVICE_DT_INST_DEFINE(inst, \ DEVICE_DT_INST_DEFINE(inst, \
bme280_init, \ bme280_init, \
device_pm_control_nop, \ bme280_pm_ctrl, \
&bme280_data_##inst, \ &bme280_data_##inst, \
&bme280_config_##inst, \ &bme280_config_##inst, \
POST_KERNEL, \ POST_KERNEL, \

View file

@ -25,6 +25,7 @@
#define BMP280_CHIP_ID_SAMPLE_2 0x57 #define BMP280_CHIP_ID_SAMPLE_2 0x57
#define BMP280_CHIP_ID_MP 0x58 #define BMP280_CHIP_ID_MP 0x58
#define BME280_CHIP_ID 0x60 #define BME280_CHIP_ID 0x60
#define BME280_MODE_SLEEP 0x00
#define BME280_MODE_FORCED 0x01 #define BME280_MODE_FORCED 0x01
#define BME280_MODE_NORMAL 0x03 #define BME280_MODE_NORMAL 0x03
#define BME280_SPI_3W_DISABLE 0x00 #define BME280_SPI_3W_DISABLE 0x00
@ -108,4 +109,9 @@
BME280_FILTER | \ BME280_FILTER | \
BME280_SPI_3W_DISABLE) BME280_SPI_3W_DISABLE)
#define BME280_CTRL_MEAS_OFF_VAL (BME280_PRESS_OVER | \
BME280_TEMP_OVER | \
BME280_MODE_SLEEP)
#endif /* ZEPHYR_DRIVERS_SENSOR_BME280_BME280_H_ */ #endif /* ZEPHYR_DRIVERS_SENSOR_BME280_BME280_H_ */