Skip to content
Permalink
Browse files

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>
  • Loading branch information...
Mierunski authored and carlescufi committed Jul 10, 2019
1 parent f4b999a commit 914daf4ec7ecfffa777e74466ab7abd077ba99d0
Showing with 50 additions and 18 deletions.
  1. +25 −9 drivers/i2c/i2c_nrfx_twi.c
  2. +25 −9 drivers/i2c/i2c_nrfx_twim.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;

default:
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:
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 */

@@ -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;

default:
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:
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 */

0 comments on commit 914daf4

Please sign in to comment.
You can’t perform that action at this time.