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:
parent
f4b999a389
commit
914daf4ec7
2 changed files with 52 additions and 20 deletions
|
@ -18,6 +18,9 @@ struct i2c_nrfx_twi_data {
|
||||||
struct k_sem completion_sync;
|
struct k_sem completion_sync;
|
||||||
volatile nrfx_err_t res;
|
volatile nrfx_err_t res;
|
||||||
u32_t dev_config;
|
u32_t dev_config;
|
||||||
|
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
|
||||||
|
u32_t pm_state;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct i2c_nrfx_twi_config {
|
struct i2c_nrfx_twi_config {
|
||||||
|
@ -149,6 +152,9 @@ static int init_twi(struct device *dev)
|
||||||
dev->config->name);
|
dev->config->name);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
|
||||||
|
get_dev_data(dev)->pm_state = DEVICE_PM_ACTIVE_STATE;
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
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,
|
static int twi_nrfx_pm_control(struct device *dev, u32_t ctrl_command,
|
||||||
void *context, device_pm_cb cb, void *arg)
|
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) {
|
if (ctrl_command == DEVICE_PM_SET_POWER_STATE) {
|
||||||
u32_t new_state = *((const u32_t *)context);
|
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) {
|
switch (new_state) {
|
||||||
case DEVICE_PM_ACTIVE_STATE:
|
case DEVICE_PM_ACTIVE_STATE:
|
||||||
init_twi(dev);
|
init_twi(dev);
|
||||||
i2c_nrfx_twi_configure(
|
if (get_dev_data(dev)->dev_config) {
|
||||||
dev, 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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
nrfx_twi_uninit(&get_dev_config(dev)->twi);
|
ret = -ENOTSUP;
|
||||||
break;
|
}
|
||||||
|
if (!ret) {
|
||||||
|
get_dev_data(dev)->pm_state = new_state;
|
||||||
}
|
}
|
||||||
current_state = new_state;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(ctrl_command == DEVICE_PM_GET_POWER_STATE);
|
assert(ctrl_command == DEVICE_PM_GET_POWER_STATE);
|
||||||
*((u32_t *)context) = current_state;
|
*((u32_t *)context) = get_dev_data(dev)->pm_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
cb(dev, 0, context, arg);
|
cb(dev, ret, context, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_DEVICE_POWER_MANAGEMENT */
|
#endif /* CONFIG_DEVICE_POWER_MANAGEMENT */
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,9 @@ struct i2c_nrfx_twim_data {
|
||||||
struct k_sem completion_sync;
|
struct k_sem completion_sync;
|
||||||
volatile nrfx_err_t res;
|
volatile nrfx_err_t res;
|
||||||
uint32_t dev_config;
|
uint32_t dev_config;
|
||||||
|
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
|
||||||
|
u32_t pm_state;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct i2c_nrfx_twim_config {
|
struct i2c_nrfx_twim_config {
|
||||||
|
@ -152,6 +155,9 @@ static int init_twim(struct device *dev)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
|
||||||
|
get_dev_data(dev)->pm_state = DEVICE_PM_ACTIVE_STATE;
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
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,
|
static int twim_nrfx_pm_control(struct device *dev, u32_t ctrl_command,
|
||||||
void *context, device_pm_cb cb, void *arg)
|
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) {
|
if (ctrl_command == DEVICE_PM_SET_POWER_STATE) {
|
||||||
u32_t new_state = *((const u32_t *)context);
|
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) {
|
switch (new_state) {
|
||||||
case DEVICE_PM_ACTIVE_STATE:
|
case DEVICE_PM_ACTIVE_STATE:
|
||||||
init_twim(dev);
|
init_twim(dev);
|
||||||
i2c_nrfx_twim_configure(
|
if (get_dev_data(dev)->dev_config) {
|
||||||
dev, 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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
nrfx_twim_uninit(&get_dev_config(dev)->twim);
|
ret = -ENOTSUP;
|
||||||
break;
|
}
|
||||||
|
if (!ret) {
|
||||||
|
get_dev_data(dev)->pm_state = new_state;
|
||||||
}
|
}
|
||||||
current_state = new_state;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(ctrl_command == DEVICE_PM_GET_POWER_STATE);
|
assert(ctrl_command == DEVICE_PM_GET_POWER_STATE);
|
||||||
*((u32_t *)context) = current_state;
|
*((u32_t *)context) = get_dev_data(dev)->pm_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
cb(dev, 0, context, arg);
|
cb(dev, ret, context, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_DEVICE_POWER_MANAGEMENT */
|
#endif /* CONFIG_DEVICE_POWER_MANAGEMENT */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue