drivers: nrf: Fix PM for TWI and TWIM in case of multi instance

TWI and TWIM used single static variable for multiple instances.
It would cause problems in case of multiple instances of peripheral.

Signed-off-by: Mieszko Mierunski <mieszko.mierunski@nordicsemi.no>
This commit is contained in:
Mieszko Mierunski 2019-07-10 15:09:18 +02:00 committed by Carles Cufí
commit 914daf4ec7
2 changed files with 52 additions and 20 deletions

View file

@ -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);
if (get_dev_data(dev)->dev_config) {
i2c_nrfx_twi_configure(
dev, get_dev_data(dev)->dev_config);
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 */

View file

@ -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);
if (get_dev_data(dev)->dev_config) {
i2c_nrfx_twim_configure(
dev, get_dev_data(dev)->dev_config);
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 */