From 8c8b95ec785500080fdc341256a47df5e551608f Mon Sep 17 00:00:00 2001 From: Luis Ubieda Date: Tue, 8 Apr 2025 14:44:26 -0400 Subject: [PATCH 1/4] drivers: i2c_rtio: Use MCUX variations when using instance number Update the driver to account for variations in the SDK driver when it uses the instance number instead of the base address. Applying 49bdcd2ef2fd5c91ab36f08d29e5183df5437843 on RTIO-version. Co-authored-by: Mahesh Mahadevan Signed-off-by: Luis Ubieda (cherry picked from commit 0f0bb7e6e9c2bc4d42902967445c29e7d6bc10ed) --- drivers/i2c/i2c_mcux_lpi2c_rtio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/i2c/i2c_mcux_lpi2c_rtio.c b/drivers/i2c/i2c_mcux_lpi2c_rtio.c index 6b10994585deb..cbdbebdc706c2 100644 --- a/drivers/i2c/i2c_mcux_lpi2c_rtio.c +++ b/drivers/i2c/i2c_mcux_lpi2c_rtio.c @@ -280,7 +280,11 @@ static void mcux_lpi2c_isr(const struct device *dev) struct mcux_lpi2c_data *data = dev->data; LPI2C_Type *base = (LPI2C_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); +#if CONFIG_HAS_MCUX_FLEXCOMM + LPI2C_MasterTransferHandleIRQ(LPI2C_GetInstance(base), &data->handle); +#else LPI2C_MasterTransferHandleIRQ(base, &data->handle); +#endif } static int mcux_lpi2c_init(const struct device *dev) From fa2742523b176e2af367be75d6e92d2db71b5092 Mon Sep 17 00:00:00 2001 From: Luis Ubieda Date: Tue, 8 Apr 2025 14:50:37 -0400 Subject: [PATCH 2/4] drivers: i2c_rtio: Use flexcomm interface to manage interrupts Some NXP SoC's have a FlexComm interface that manages the interrupts. Applying 482e39ea9556f53adbb7f67d0d0da3d17bbbae90 on RTIO-version. Authored-by: Mahesh Mahadevan Signed-off-by: Luis Ubieda (cherry picked from commit 797772fc41c50b4494f8d03d3d00148f61ee1402) --- drivers/i2c/i2c_mcux_lpi2c_rtio.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/i2c_mcux_lpi2c_rtio.c b/drivers/i2c/i2c_mcux_lpi2c_rtio.c index cbdbebdc706c2..6a2c1143d12d4 100644 --- a/drivers/i2c/i2c_mcux_lpi2c_rtio.c +++ b/drivers/i2c/i2c_mcux_lpi2c_rtio.c @@ -350,6 +350,19 @@ static const struct i2c_driver_api mcux_lpi2c_driver_api = { #define I2C_MCUX_LPI2C_SDA_INIT(n) #endif /* CONFIG_I2C_MCUX_LPI2C_BUS_RECOVERY */ +#define I2C_MCUX_LPI2C_MODULE_IRQ_CONNECT(n) \ + do { \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), \ + mcux_lpi2c_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } while (false) + +#define I2C_MCUX_LPI2C_MODULE_IRQ(n) \ + IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), \ + (I2C_MCUX_LPI2C_MODULE_IRQ_CONNECT(n))) + #define I2C_MCUX_LPI2C_INIT(n) \ PINCTRL_DT_INST_DEFINE(n); \ \ @@ -386,12 +399,7 @@ static const struct i2c_driver_api mcux_lpi2c_driver_api = { \ static void mcux_lpi2c_config_func_##n(const struct device *dev)\ { \ - IRQ_CONNECT(DT_INST_IRQN(n), \ - DT_INST_IRQ(n, priority), \ - mcux_lpi2c_isr, \ - DEVICE_DT_INST_GET(n), 0); \ - \ - irq_enable(DT_INST_IRQN(n)); \ + I2C_MCUX_LPI2C_MODULE_IRQ(n); \ } DT_INST_FOREACH_STATUS_OKAY(I2C_MCUX_LPI2C_INIT) From e9ce89698624bd7255608318ca8582222d493f64 Mon Sep 17 00:00:00 2001 From: Luis Ubieda Date: Tue, 8 Apr 2025 14:56:12 -0400 Subject: [PATCH 3/4] drivers: i2c_rtio: Use the NXP Flexcomm driver for interrupt handling The Low Power Flexcomm driver manages the interrupt handling and provides an API to register interrupt callbacks. Register the NXP LPI2C interrupt handler. Applying dca6e64c93f26db254089f20225854bb1f8fe9b4 on RTIO-version. Authored-by: Mahesh Mahadevan Signed-off-by: Luis Ubieda (cherry picked from commit c7a00248a668dcac699fc01632bfdabe2c4bb769) --- drivers/i2c/i2c_mcux_lpi2c_rtio.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/i2c/i2c_mcux_lpi2c_rtio.c b/drivers/i2c/i2c_mcux_lpi2c_rtio.c index 6a2c1143d12d4..02715aac1f70c 100644 --- a/drivers/i2c/i2c_mcux_lpi2c_rtio.c +++ b/drivers/i2c/i2c_mcux_lpi2c_rtio.c @@ -16,6 +16,9 @@ #include #include #include +#if CONFIG_NXP_LP_FLEXCOMM +#include +#endif #include @@ -40,6 +43,9 @@ LOG_MODULE_REGISTER(mcux_lpi2c); struct mcux_lpi2c_config { DEVICE_MMIO_NAMED_ROM(reg_base); +#ifdef CONFIG_NXP_LP_FLEXCOMM + const struct device *parent_dev; +#endif const struct device *clock_dev; clock_control_subsys_t clock_subsys; void (*irq_config_func)(const struct device *dev); @@ -329,7 +335,15 @@ static int mcux_lpi2c_init(const struct device *dev) return error; } +#if CONFIG_NXP_LP_FLEXCOMM + /* When using LP Flexcomm driver, register the interrupt handler + * so we receive notification from the LP Flexcomm interrupt handler. + */ + nxp_lp_flexcomm_setirqhandler(config->parent_dev, dev, + LP_FLEXCOMM_PERIPH_LPI2C, mcux_lpi2c_isr); +#else config->irq_config_func(dev); +#endif i2c_rtio_init(data->ctx, dev); @@ -363,6 +377,13 @@ static const struct i2c_driver_api mcux_lpi2c_driver_api = { IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), \ (I2C_MCUX_LPI2C_MODULE_IRQ_CONNECT(n))) +#ifdef CONFIG_NXP_LP_FLEXCOMM +#define PARENT_DEV(n) \ + .parent_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), +#else +#define PARENT_DEV(n) +#endif /* CONFIG_NXP_LP_FLEXCOMM */ + #define I2C_MCUX_LPI2C_INIT(n) \ PINCTRL_DT_INST_DEFINE(n); \ \ @@ -370,6 +391,7 @@ static const struct i2c_driver_api mcux_lpi2c_driver_api = { \ static const struct mcux_lpi2c_config mcux_lpi2c_config_##n = { \ DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \ + PARENT_DEV(n) \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = \ (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name),\ From e985efe6589616341a362d146e19f4878176ae90 Mon Sep 17 00:00:00 2001 From: Luis Ubieda Date: Mon, 14 Apr 2025 13:36:45 -0400 Subject: [PATCH 4/4] drivers: i2c_rtio: MCUX LPflexcomm determine by inst Determine if lpflexcomm wrapped lpi2c by instance and connect irq differently dependending on that to support platforms with both flexcomm wrapped and unwrapped lpi2c's. Applying c1286a8d8d425805fcceb3b872325fb4c439a572 to RTIO version. Authored-by: Declan Snyder Signed-off-by: Luis Ubieda (cherry picked from commit d7ebf672bd481164b81919b78c338c2563c7d144) --- drivers/i2c/i2c_mcux_lpi2c_rtio.c | 44 +++++++++++++------------------ 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/drivers/i2c/i2c_mcux_lpi2c_rtio.c b/drivers/i2c/i2c_mcux_lpi2c_rtio.c index 02715aac1f70c..a7d2666413402 100644 --- a/drivers/i2c/i2c_mcux_lpi2c_rtio.c +++ b/drivers/i2c/i2c_mcux_lpi2c_rtio.c @@ -43,9 +43,6 @@ LOG_MODULE_REGISTER(mcux_lpi2c); struct mcux_lpi2c_config { DEVICE_MMIO_NAMED_ROM(reg_base); -#ifdef CONFIG_NXP_LP_FLEXCOMM - const struct device *parent_dev; -#endif const struct device *clock_dev; clock_control_subsys_t clock_subsys; void (*irq_config_func)(const struct device *dev); @@ -335,15 +332,7 @@ static int mcux_lpi2c_init(const struct device *dev) return error; } -#if CONFIG_NXP_LP_FLEXCOMM - /* When using LP Flexcomm driver, register the interrupt handler - * so we receive notification from the LP Flexcomm interrupt handler. - */ - nxp_lp_flexcomm_setirqhandler(config->parent_dev, dev, - LP_FLEXCOMM_PERIPH_LPI2C, mcux_lpi2c_isr); -#else config->irq_config_func(dev); -#endif i2c_rtio_init(data->ctx, dev); @@ -377,21 +366,31 @@ static const struct i2c_driver_api mcux_lpi2c_driver_api = { IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), \ (I2C_MCUX_LPI2C_MODULE_IRQ_CONNECT(n))) -#ifdef CONFIG_NXP_LP_FLEXCOMM -#define PARENT_DEV(n) \ - .parent_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), -#else -#define PARENT_DEV(n) -#endif /* CONFIG_NXP_LP_FLEXCOMM */ +/* When using LP Flexcomm driver, register the interrupt handler + * so we receive notification from the LP Flexcomm interrupt handler. + */ +#define I2C_MCUX_LPI2C_LPFLEXCOMM_IRQ_FUNC(n) \ + nxp_lp_flexcomm_setirqhandler(DEVICE_DT_GET(DT_INST_PARENT(n)), \ + DEVICE_DT_INST_GET(n), \ + LP_FLEXCOMM_PERIPH_LPI2C, \ + mcux_lpi2c_isr) + +#define I2C_MCUX_LPI2C_IRQ_SETUP_FUNC(n) \ + COND_CODE_1(DT_NODE_HAS_COMPAT(DT_INST_PARENT(n), \ + nxp_lp_flexcomm), \ + (I2C_MCUX_LPI2C_LPFLEXCOMM_IRQ_FUNC(n)), \ + (I2C_MCUX_LPI2C_MODULE_IRQ(n))) #define I2C_MCUX_LPI2C_INIT(n) \ PINCTRL_DT_INST_DEFINE(n); \ \ - static void mcux_lpi2c_config_func_##n(const struct device *dev); \ + static void mcux_lpi2c_config_func_##n(const struct device *dev)\ + { \ + I2C_MCUX_LPI2C_IRQ_SETUP_FUNC(n); \ + } \ \ static const struct mcux_lpi2c_config mcux_lpi2c_config_##n = { \ DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \ - PARENT_DEV(n) \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = \ (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name),\ @@ -417,11 +416,6 @@ static const struct i2c_driver_api mcux_lpi2c_driver_api = { &mcux_lpi2c_data_##n, \ &mcux_lpi2c_config_##n, POST_KERNEL, \ CONFIG_I2C_INIT_PRIORITY, \ - &mcux_lpi2c_driver_api); \ - \ - static void mcux_lpi2c_config_func_##n(const struct device *dev)\ - { \ - I2C_MCUX_LPI2C_MODULE_IRQ(n); \ - } + &mcux_lpi2c_driver_api); DT_INST_FOREACH_STATUS_OKAY(I2C_MCUX_LPI2C_INIT)