Skip to content

Commit 5ff676f

Browse files
DerekSnellkartben
authored andcommitted
drivers: i2c_mcux_flexcomm: adds PM TURN_ON low-power recovery support
Enables Sleep mode (PM3) in RW61x. Signed-off-by: Derek Snell <[email protected]>
1 parent b41806b commit 5ff676f

File tree

1 file changed

+45
-5
lines changed

1 file changed

+45
-5
lines changed

drivers/i2c/i2c_mcux_flexcomm.c

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ LOG_MODULE_REGISTER(mcux_flexcomm);
2525

2626
#include "i2c-priv.h"
2727

28+
#include <zephyr/pm/device.h>
29+
#include <zephyr/pm/policy.h>
30+
2831
#define I2C_TRANSFER_TIMEOUT_MSEC \
2932
COND_CODE_0(CONFIG_I2C_NXP_TRANSFER_TIMEOUT, (K_FOREVER), \
3033
(K_MSEC(CONFIG_I2C_NXP_TRANSFER_TIMEOUT)))
@@ -154,6 +157,10 @@ static int mcux_flexcomm_transfer(const struct device *dev,
154157

155158
k_sem_take(&data->lock, K_FOREVER);
156159

160+
#ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS
161+
pm_policy_device_power_lock_get(dev);
162+
#endif
163+
157164
/* Iterate over all the messages */
158165
for (int i = 0; i < num_msgs; i++) {
159166
if (I2C_MSG_ADDR_10_BITS & msgs->flags) {
@@ -208,6 +215,10 @@ static int mcux_flexcomm_transfer(const struct device *dev,
208215
msgs++;
209216
}
210217

218+
#ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS
219+
pm_policy_device_power_lock_put(dev);
220+
#endif
221+
211222
k_sem_give(&data->lock);
212223

213224
return ret;
@@ -555,7 +566,7 @@ static void mcux_flexcomm_isr(const struct device *dev)
555566
I2C_MasterTransferHandleIRQ(base, &data->handle);
556567
}
557568

558-
static int mcux_flexcomm_init(const struct device *dev)
569+
static int mcux_flexcomm_init_common(const struct device *dev)
559570
{
560571
const struct mcux_flexcomm_config *config = dev->config;
561572
struct mcux_flexcomm_data *data = dev->data;
@@ -579,9 +590,6 @@ static int mcux_flexcomm_init(const struct device *dev)
579590
return error;
580591
}
581592

582-
k_sem_init(&data->lock, 1, 1);
583-
k_sem_init(&data->device_sync_sem, 0, K_SEM_MAX_LIMIT);
584-
585593
if (!device_is_ready(config->clock_dev)) {
586594
LOG_ERR("clock control device not ready");
587595
return -ENODEV;
@@ -611,6 +619,37 @@ static int mcux_flexcomm_init(const struct device *dev)
611619
return 0;
612620
}
613621

622+
static int i2c_mcux_flexcomm_pm_action(const struct device *dev, enum pm_device_action action)
623+
{
624+
switch (action) {
625+
case PM_DEVICE_ACTION_RESUME:
626+
break;
627+
case PM_DEVICE_ACTION_SUSPEND:
628+
break;
629+
case PM_DEVICE_ACTION_TURN_OFF:
630+
return 0;
631+
case PM_DEVICE_ACTION_TURN_ON:
632+
mcux_flexcomm_init_common(dev);
633+
return 0;
634+
default:
635+
return -ENOTSUP;
636+
}
637+
return 0;
638+
}
639+
640+
static int mcux_flexcomm_init(const struct device *dev)
641+
{
642+
struct mcux_flexcomm_data *data = dev->data;
643+
644+
k_sem_init(&data->lock, 1, 1);
645+
k_sem_init(&data->device_sync_sem, 0, K_SEM_MAX_LIMIT);
646+
647+
/* Rest of the init is done from the PM_DEVICE_TURN_ON action
648+
* which is invoked by pm_device_driver_init().
649+
*/
650+
return pm_device_driver_init(dev, i2c_mcux_flexcomm_pm_action);
651+
}
652+
614653
static DEVICE_API(i2c, mcux_flexcomm_driver_api) = {
615654
.configure = mcux_flexcomm_configure,
616655
.transfer = mcux_flexcomm_transfer,
@@ -650,9 +689,10 @@ static DEVICE_API(i2c, mcux_flexcomm_driver_api) = {
650689
.reset = RESET_DT_SPEC_INST_GET(id), \
651690
}; \
652691
static struct mcux_flexcomm_data mcux_flexcomm_data_##id; \
692+
PM_DEVICE_DT_INST_DEFINE(id, i2c_mcux_flexcomm_pm_action); \
653693
I2C_DEVICE_DT_INST_DEFINE(id, \
654694
mcux_flexcomm_init, \
655-
NULL, \
695+
PM_DEVICE_DT_INST_GET(id), \
656696
&mcux_flexcomm_data_##id, \
657697
&mcux_flexcomm_config_##id, \
658698
POST_KERNEL, \

0 commit comments

Comments
 (0)