diff --git a/drivers/i2c/CMakeLists.txt b/drivers/i2c/CMakeLists.txt index 2825364994b..414e2a2fa64 100644 --- a/drivers/i2c/CMakeLists.txt +++ b/drivers/i2c/CMakeLists.txt @@ -31,6 +31,7 @@ zephyr_library_sources_ifdef(CONFIG_I2C_SAM0 i2c_sam0.c) zephyr_library_sources_ifdef(CONFIG_I2C_LITEX i2c_litex.c) zephyr_library_sources_ifdef(CONFIG_I2C_NPCX i2c_npcx_controller.c) zephyr_library_sources_ifdef(CONFIG_I2C_NPCX i2c_npcx_port.c) +zephyr_library_sources_ifdef(CONFIG_I2C_DW i2c_dw.c) zephyr_library_sources_ifdef(CONFIG_I2C_STM32_V1 i2c_ll_stm32_v1.c @@ -41,19 +42,6 @@ zephyr_library_sources_ifdef(CONFIG_I2C_STM32_V2 i2c_ll_stm32.c ) -if(CONFIG_I2C_DW) - zephyr_library_sources(i2c_dw.c) - math(EXPR max_index "${CONFIG_I2C_DW_MAX_INSTANCES} - 1") - foreach(NUM RANGE 0 ${max_index}) - math(EXPR NEXT_NUM "${NUM} + 1") - configure_file( - i2c_dw_port_x.h - ${PROJECT_BINARY_DIR}/include/generated/i2c_dw_port_${NUM}.h - @ONLY - ) - endforeach(NUM) -endif() - zephyr_library_sources_ifdef(CONFIG_I2C_TEST i2c_test.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE i2c_handlers.c) diff --git a/drivers/i2c/Kconfig.dw b/drivers/i2c/Kconfig.dw index 68f91cbe905..0042bdd42bd 100644 --- a/drivers/i2c/Kconfig.dw +++ b/drivers/i2c/Kconfig.dw @@ -12,17 +12,7 @@ menuconfig I2C_DW help Enable the Design Ware I2C driver -if I2C_DW - config I2C_DW_CLOCK_SPEED int "Set the clock speed for I2C" + depends on I2C_DW default 32 - -config I2C_DW_MAX_INSTANCES - int "Maximum number of supported driver instances" - range 1 32 - default 12 - help - The maximum number of supported driver instances in device tree. - -endif # I2C_DW diff --git a/drivers/i2c/i2c_dw.c b/drivers/i2c/i2c_dw.c index 232755f8685..41b51ad9587 100644 --- a/drivers/i2c/i2c_dw.c +++ b/drivers/i2c/i2c_dw.c @@ -671,8 +671,66 @@ static int i2c_dw_initialize(const struct device *dev) return 0; } -/* The instance-specific header files are chained together (each instance - * includes the next one, unless it's the last instance) so we only need to - * include the first instance. - */ -#include +#define I2C_DW_INIT_PCIE0(n) +#define I2C_DW_INIT_PCIE1(n) \ + .pcie = true, \ + .pcie_bdf = DT_INST_REG_ADDR(n), \ + .pcie_id = DT_INST_REG_SIZE(n), +#define I2C_DW_INIT_PCIE(n) \ + _CONCAT(I2C_DW_INIT_PCIE, DT_INST_ON_BUS(n, pcie))(n) + +#define I2C_DW_IRQ_FLAGS_SENSE0(n) 0 +#define I2C_DW_IRQ_FLAGS_SENSE1(n) DT_INST_IRQ(n, sense) +#define I2C_DW_IRQ_FLAGS(n) \ + _CONCAT(I2C_DW_IRQ_FLAGS_SENSE, DT_INST_IRQ_HAS_CELL(n, sense))(n) + +/* not PCI(e) */ +#define I2C_DW_IRQ_CONFIG_PCIE0(n) \ + static void i2c_config_##n(const struct device *port) \ + { \ + ARG_UNUSED(port); \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + i2c_dw_isr, DEVICE_DT_INST_GET(n), \ + I2C_DW_IRQ_FLAGS(n)); \ + irq_enable(DT_INST_IRQN(n)); \ + } + +/* PCI(e) with auto IRQ detection */ +#define I2C_DW_IRQ_CONFIG_PCIE1(n) \ + static void i2c_config_##n(const struct device *port) \ + { \ + ARG_UNUSED(port); \ + BUILD_ASSERT(DT_INST_IRQN(n) == PCIE_IRQ_DETECT, \ + "Only runtime IRQ configuration is supported"); \ + BUILD_ASSERT(IS_ENABLED(CONFIG_DYNAMIC_INTERRUPTS), \ + "DW I2C PCI needs CONFIG_DYNAMIC_INTERRUPTS"); \ + unsigned int irq = pcie_alloc_irq(DT_INST_REG_ADDR(n)); \ + if (irq == PCIE_CONF_INTR_IRQ_NONE) { \ + return; \ + } \ + irq_connect_dynamic(irq, DT_INST_IRQ(n, priority), \ + (void (*)(const void *))i2c_dw_isr, \ + DEVICE_DT_INST_GET(n), \ + I2C_DW_IRQ_FLAGS(n)); \ + pcie_irq_enable(DT_INST_REG_ADDR(n), irq); \ + } + +#define I2C_DW_IRQ_CONFIG(n) \ + _CONCAT(I2C_DW_IRQ_CONFIG_PCIE, DT_INST_ON_BUS(n, pcie))(n) + +#define I2C_DEVICE_INIT_DW(n) \ + static void i2c_config_##n(const struct device *port); \ + static const struct i2c_dw_rom_config i2c_config_dw_##n = { \ + DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), \ + .config_func = i2c_config_##n, \ + .bitrate = DT_INST_PROP(n, clock_frequency), \ + I2C_DW_INIT_PCIE(n) \ + }; \ + static struct i2c_dw_dev_config i2c_##n##_runtime; \ + DEVICE_DT_INST_DEFINE(n, &i2c_dw_initialize, device_pm_control_nop, \ + &i2c_##n##_runtime, &i2c_config_dw_##n, \ + POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \ + &funcs); \ + I2C_DW_IRQ_CONFIG(n) + +DT_INST_FOREACH_STATUS_OKAY(I2C_DEVICE_INIT_DW) diff --git a/drivers/i2c/i2c_dw_port_x.h b/drivers/i2c/i2c_dw_port_x.h deleted file mode 100644 index 02da6e70467..00000000000 --- a/drivers/i2c/i2c_dw_port_x.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2019 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - * - * This file is a template for cmake and is not meant to be used directly! - */ - -#if DT_NODE_HAS_STATUS(DT_DRV_INST(@NUM@), okay) - -static void i2c_config_@NUM@(const struct device *port); - -static const struct i2c_dw_rom_config i2c_config_dw_@NUM@ = { - DEVICE_MMIO_ROM_INIT(DT_DRV_INST(@NUM@)), - .config_func = i2c_config_@NUM@, - .bitrate = DT_INST_PROP(@NUM@, clock_frequency), - -#if DT_INST_ON_BUS(@NUM@, pcie) - .pcie = true, - .pcie_bdf = DT_INST_REG_ADDR(@NUM@), - .pcie_id = DT_INST_REG_SIZE(@NUM@), -#endif -}; - -static struct i2c_dw_dev_config i2c_@NUM@_runtime; - -DEVICE_DT_INST_DEFINE(@NUM@, &i2c_dw_initialize, device_pm_control_nop, - &i2c_@NUM@_runtime, &i2c_config_dw_@NUM@, - POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, - &funcs); - -#if DT_INST_IRQ_HAS_CELL(@NUM@, sense) -#define INST_@NUM@_IRQ_FLAGS DT_INST_IRQ(@NUM@, sense) -#else -#define INST_@NUM@_IRQ_FLAGS 0 -#endif -static void i2c_config_@NUM@(const struct device *port) -{ - ARG_UNUSED(port); - -#if DT_INST_ON_BUS(@NUM@, pcie) - /* PCI(e) with auto IRQ detection */ - BUILD_ASSERT(DT_INST_IRQN(@NUM@) == PCIE_IRQ_DETECT, - "Only runtime IRQ configuration is supported"); - BUILD_ASSERT(IS_ENABLED(CONFIG_DYNAMIC_INTERRUPTS), - "DW I2C PCI auto-IRQ needs CONFIG_DYNAMIC_INTERRUPTS"); - - unsigned int irq; - - irq = pcie_alloc_irq(DT_INST_REG_ADDR(@NUM@)); - - if (irq == PCIE_CONF_INTR_IRQ_NONE) { - return; - } - - irq_connect_dynamic(irq, - DT_INST_IRQ(@NUM@, priority), - (void (*)(const void *))i2c_dw_isr, - DEVICE_DT_INST_GET(@NUM@), INST_@NUM@_IRQ_FLAGS); - pcie_irq_enable(DT_INST_REG_ADDR(@NUM@), irq); -#else - /* not PCI(e) */ - IRQ_CONNECT(DT_INST_IRQN(@NUM@), - DT_INST_IRQ(@NUM@, priority), - i2c_dw_isr, DEVICE_DT_INST_GET(@NUM@), - INST_@NUM@_IRQ_FLAGS); - irq_enable(DT_INST_IRQN(@NUM@)); - -#endif -} - -#endif /* DT_NODE_HAS_STATUS(DT_DRV_INST(@NUM@), okay) */ - -/* Include subsequent instances */ -#if @NEXT_NUM@ < CONFIG_I2C_DW_MAX_INSTANCES -#include -#endif diff --git a/soc/x86/apollo_lake/Kconfig.defconfig b/soc/x86/apollo_lake/Kconfig.defconfig index a3cedf6095d..b6852168397 100644 --- a/soc/x86/apollo_lake/Kconfig.defconfig +++ b/soc/x86/apollo_lake/Kconfig.defconfig @@ -49,10 +49,6 @@ config I2C_DW default y depends on I2C -config I2C_DW_MAX_INSTANCES - default 8 - depends on I2C_DW - config GPIO_INTEL_APL default y depends on GPIO diff --git a/soc/x86/elkhart_lake/Kconfig.defconfig b/soc/x86/elkhart_lake/Kconfig.defconfig index 7f7e232dea6..11d3914630e 100644 --- a/soc/x86/elkhart_lake/Kconfig.defconfig +++ b/soc/x86/elkhart_lake/Kconfig.defconfig @@ -49,10 +49,6 @@ config I2C_DW default y depends on I2C -config I2C_DW_MAX_INSTANCES - default 15 - depends on I2C_DW - config UART_NS16550_MAX_INSTANCES default 11 depends on UART_NS16550