diff --git a/drivers/i2c/i2c_nrfx_twi.c b/drivers/i2c/i2c_nrfx_twi.c index 08aee9d34dd..3600c100dc1 100644 --- a/drivers/i2c/i2c_nrfx_twi.c +++ b/drivers/i2c/i2c_nrfx_twi.c @@ -18,6 +18,9 @@ struct i2c_nrfx_twi_data { struct k_sem completion_sync; volatile nrfx_err_t res; u32_t dev_config; +#ifdef CONFIG_DEVICE_POWER_MANAGEMENT + u32_t pm_state; +#endif }; struct i2c_nrfx_twi_config { @@ -149,6 +152,9 @@ static int init_twi(struct device *dev) dev->config->name); return -EBUSY; } +#ifdef CONFIG_DEVICE_POWER_MANAGEMENT + get_dev_data(dev)->pm_state = DEVICE_PM_ACTIVE_STATE; +#endif return 0; } @@ -157,35 +163,45 @@ static int init_twi(struct device *dev) static int twi_nrfx_pm_control(struct device *dev, u32_t ctrl_command, void *context, device_pm_cb cb, void *arg) { - static u32_t current_state = DEVICE_PM_ACTIVE_STATE; + int ret = 0; if (ctrl_command == DEVICE_PM_SET_POWER_STATE) { u32_t new_state = *((const u32_t *)context); - if (new_state != current_state) { + if (new_state != get_dev_data(dev)->pm_state) { switch (new_state) { case DEVICE_PM_ACTIVE_STATE: init_twi(dev); - i2c_nrfx_twi_configure( - dev, get_dev_data(dev)->dev_config); + if (get_dev_data(dev)->dev_config) { + i2c_nrfx_twi_configure( + dev, + get_dev_data(dev)->dev_config); + } + break; + + case DEVICE_PM_LOW_POWER_STATE: + case DEVICE_PM_SUSPEND_STATE: + case DEVICE_PM_OFF_STATE: + nrfx_twi_uninit(&get_dev_config(dev)->twi); break; default: - nrfx_twi_uninit(&get_dev_config(dev)->twi); - break; + ret = -ENOTSUP; + } + if (!ret) { + get_dev_data(dev)->pm_state = new_state; } - current_state = new_state; } } else { assert(ctrl_command == DEVICE_PM_GET_POWER_STATE); - *((u32_t *)context) = current_state; + *((u32_t *)context) = get_dev_data(dev)->pm_state; } if (cb) { - cb(dev, 0, context, arg); + cb(dev, ret, context, arg); } - return 0; + return ret; } #endif /* CONFIG_DEVICE_POWER_MANAGEMENT */ diff --git a/drivers/i2c/i2c_nrfx_twim.c b/drivers/i2c/i2c_nrfx_twim.c index c687f1fd48c..11fd210880a 100644 --- a/drivers/i2c/i2c_nrfx_twim.c +++ b/drivers/i2c/i2c_nrfx_twim.c @@ -19,6 +19,9 @@ struct i2c_nrfx_twim_data { struct k_sem completion_sync; volatile nrfx_err_t res; uint32_t dev_config; +#ifdef CONFIG_DEVICE_POWER_MANAGEMENT + u32_t pm_state; +#endif }; struct i2c_nrfx_twim_config { @@ -152,6 +155,9 @@ static int init_twim(struct device *dev) return -EBUSY; } +#ifdef CONFIG_DEVICE_POWER_MANAGEMENT + get_dev_data(dev)->pm_state = DEVICE_PM_ACTIVE_STATE; +#endif return 0; } @@ -160,35 +166,45 @@ static int init_twim(struct device *dev) static int twim_nrfx_pm_control(struct device *dev, u32_t ctrl_command, void *context, device_pm_cb cb, void *arg) { - static u32_t current_state = DEVICE_PM_ACTIVE_STATE; + int ret = 0; if (ctrl_command == DEVICE_PM_SET_POWER_STATE) { u32_t new_state = *((const u32_t *)context); - if (new_state != current_state) { + if (new_state != get_dev_data(dev)->pm_state) { switch (new_state) { case DEVICE_PM_ACTIVE_STATE: init_twim(dev); - i2c_nrfx_twim_configure( - dev, get_dev_data(dev)->dev_config); + if (get_dev_data(dev)->dev_config) { + i2c_nrfx_twim_configure( + dev, + get_dev_data(dev)->dev_config); + } + break; + + case DEVICE_PM_LOW_POWER_STATE: + case DEVICE_PM_SUSPEND_STATE: + case DEVICE_PM_OFF_STATE: + nrfx_twim_uninit(&get_dev_config(dev)->twim); break; default: - nrfx_twim_uninit(&get_dev_config(dev)->twim); - break; + ret = -ENOTSUP; + } + if (!ret) { + get_dev_data(dev)->pm_state = new_state; } - current_state = new_state; } } else { assert(ctrl_command == DEVICE_PM_GET_POWER_STATE); - *((u32_t *)context) = current_state; + *((u32_t *)context) = get_dev_data(dev)->pm_state; } if (cb) { - cb(dev, 0, context, arg); + cb(dev, ret, context, arg); } - return 0; + return ret; } #endif /* CONFIG_DEVICE_POWER_MANAGEMENT */