sensor: bmm150: support power domains

Support the BMM150 being on a power domain, which may not be powered at
boot. For example, Nordic Thingy53.

Signed-off-by: Jordan Yates <jordan@embeint.com>
This commit is contained in:
Jordan Yates 2024-07-16 11:17:05 +10:00 committed by Carles Cufí
commit 5d3d78e9cb
3 changed files with 52 additions and 32 deletions

View file

@ -552,6 +552,7 @@ static int bmm150_init_chip(const struct device *dev)
struct bmm150_data *data = dev->data;
struct bmm150_preset preset;
uint8_t chip_id;
int ret = -EIO;
if (bmm150_full_por(dev) != 0) {
goto err_poweroff;
@ -615,20 +616,24 @@ static int bmm150_init_chip(const struct device *dev)
data->tregs.z3 = sys_le16_to_cpu(data->tregs.z3);
data->tregs.z4 = sys_le16_to_cpu(data->tregs.z4);
return 0;
ret = 0;
err_poweroff:
(void)bmm150_power_control(dev, 0); /* Suspend */
return -EIO;
return ret;
}
#ifdef CONFIG_PM_DEVICE
static int pm_action(const struct device *dev, enum pm_device_action action)
{
int ret;
int ret = 0;
switch (action) {
case PM_DEVICE_ACTION_TURN_ON:
ret = bmm150_init_chip(dev);
if (ret != 0) {
LOG_ERR("failed to initialize chip: %d", ret);
}
break;
case PM_DEVICE_ACTION_RESUME:
/* Need to enter sleep mode before setting OpMode to normal */
ret = bmm150_power_control(dev, 1);
@ -642,20 +647,33 @@ static int pm_action(const struct device *dev, enum pm_device_action action)
if (ret != 0) {
LOG_ERR("failed to enter normal mode: %d", ret);
}
#ifdef CONFIG_BMM150_TRIGGER
else {
ret = bmm150_trigger_mode_power_ctrl(dev, true);
}
break;
#endif
#ifdef CONFIG_PM_DEVICE
case PM_DEVICE_ACTION_SUSPEND:
ret = bmm150_power_control(dev, 0); /* Suspend */
if (ret != 0) {
LOG_ERR("failed to enter suspend mode: %d", ret);
}
#ifdef CONFIG_BMM150_TRIGGER
else {
ret = bmm150_trigger_mode_power_ctrl(dev, false);
}
#endif
break;
case PM_DEVICE_ACTION_TURN_OFF:
break;
#endif /* CONFIG_PM_DEVICE */
default:
return -ENOTSUP;
}
return ret;
}
#endif
static int bmm150_init(const struct device *dev)
{
@ -667,11 +685,6 @@ static int bmm150_init(const struct device *dev)
return err;
}
if (bmm150_init_chip(dev) < 0) {
LOG_ERR("failed to initialize chip");
return -EIO;
}
#ifdef CONFIG_BMM150_TRIGGER
if (bmm150_trigger_mode_init(dev) < 0) {
LOG_ERR("Cannot set up trigger mode.");
@ -679,7 +692,7 @@ static int bmm150_init(const struct device *dev)
}
#endif
return 0;
return pm_device_driver_init(dev, pm_action);
}
/* Initializes a struct bmm150_config for an instance on a SPI bus. */

View file

@ -225,6 +225,8 @@ enum bmm150_presets {
int bmm150_trigger_mode_init(const struct device *dev);
int bmm150_trigger_mode_power_ctrl(const struct device *dev, bool enable);
int bmm150_trigger_set(const struct device *dev,
const struct sensor_trigger *trig,
sensor_trigger_handler_t handler);

View file

@ -122,7 +122,6 @@ int bmm150_trigger_mode_init(const struct device *dev)
{
struct bmm150_data *data = dev->data;
const struct bmm150_config *cfg = dev->config;
int ret;
if (!device_is_ready(cfg->drdy_int.port)) {
LOG_ERR("INT device is not ready");
@ -151,25 +150,31 @@ int bmm150_trigger_mode_init(const struct device *dev)
data->dev = dev;
#endif
ret = gpio_pin_configure_dt(&cfg->drdy_int, GPIO_INPUT);
if (ret < 0) {
return ret;
}
gpio_init_callback(&data->gpio_cb,
bmm150_gpio_callback,
BIT(cfg->drdy_int.pin));
bmm150_gpio_callback,
BIT(cfg->drdy_int.pin));
ret = gpio_add_callback(cfg->drdy_int.port, &data->gpio_cb);
if (ret < 0) {
return ret;
}
ret = gpio_pin_interrupt_configure_dt(&cfg->drdy_int,
GPIO_INT_EDGE_TO_ACTIVE);
if (ret < 0) {
return ret;
}
return 0;
return gpio_add_callback(cfg->drdy_int.port, &data->gpio_cb);
}
int bmm150_trigger_mode_power_ctrl(const struct device *dev, bool enable)
{
const struct bmm150_config *cfg = dev->config;
int ret;
if (enable) {
ret = gpio_pin_configure_dt(&cfg->drdy_int, GPIO_INPUT);
if (ret < 0) {
return ret;
}
ret = gpio_pin_interrupt_configure_dt(&cfg->drdy_int,
GPIO_INT_EDGE_TO_ACTIVE);
} else {
ret = gpio_pin_interrupt_configure_dt(&cfg->drdy_int, GPIO_INT_DISABLE);
if (ret < 0) {
return ret;
}
ret = gpio_pin_configure_dt(&cfg->drdy_int, GPIO_DISCONNECTED);
}
return ret;
}