From 2b46cc0b78e28daa1a5c1b89d22f30e96c9ae37e Mon Sep 17 00:00:00 2001 From: Phi Bang Nguyen Date: Wed, 19 Mar 2025 14:13:17 +0100 Subject: [PATCH] drivers: video: Introduce video device structure Introduce a new video device structure representing a device in a video pipeline. Each video device embeds a pointer to its "source" device and other "video" characteristics. This structure give the video framework an access to all video features of the device and a hierachical view of the video pipeline that the device belongs to. Signed-off-by: Phi Bang Nguyen --- cmake/linker_script/common/common-ram.cmake | 3 ++ drivers/video/CMakeLists.txt | 3 ++ drivers/video/gc2145.c | 5 +++ drivers/video/mt9m114.c | 5 +++ drivers/video/ov2640.c | 4 +++ drivers/video/ov5640.c | 6 +++- drivers/video/ov7670.c | 6 +++- drivers/video/ov7725.c | 4 +++ drivers/video/video.ld | 3 ++ drivers/video/video_device.c | 22 ++++++++++++ drivers/video/video_device.h | 25 +++++++++++++ drivers/video/video_emul_imager.c | 6 +++- drivers/video/video_emul_rx.c | 6 +++- drivers/video/video_esp32_dvp.c | 5 +++ drivers/video/video_mcux_csi.c | 5 +++ drivers/video/video_mcux_mipi_csi2rx.c | 7 +++- drivers/video/video_mcux_smartdma.c | 40 +++++++++++---------- drivers/video/video_stm32_dcmi.c | 4 +++ drivers/video/video_sw_generator.c | 4 +++ 19 files changed, 139 insertions(+), 24 deletions(-) create mode 100644 drivers/video/video.ld create mode 100644 drivers/video/video_device.c create mode 100644 drivers/video/video_device.h diff --git a/cmake/linker_script/common/common-ram.cmake b/cmake/linker_script/common/common-ram.cmake index 0dda1ee3c0a..d46376edd03 100644 --- a/cmake/linker_script/common/common-ram.cmake +++ b/cmake/linker_script/common/common-ram.cmake @@ -125,6 +125,9 @@ if(CONFIG_UVB) zephyr_iterable_section(NAME uvb_node GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) endif() +if(CONFIG_VIDEO) + zephyr_iterable_section(NAME video_device GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) +endif() if(CONFIG_LOG) zephyr_iterable_section(NAME log_mpsc_pbuf GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN}) diff --git a/drivers/video/CMakeLists.txt b/drivers/video/CMakeLists.txt index 6210f8d881d..c9c617f1a0b 100644 --- a/drivers/video/CMakeLists.txt +++ b/drivers/video/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_library() zephyr_library_sources(video_common.c) +zephyr_library_sources(video_device.c) zephyr_library_sources_ifdef(CONFIG_VIDEO_MCUX_CSI video_mcux_csi.c) zephyr_library_sources_ifdef(CONFIG_VIDEO_MCUX_MIPI_CSI2RX video_mcux_mipi_csi2rx.c) @@ -18,3 +19,5 @@ zephyr_library_sources_ifdef(CONFIG_VIDEO_ESP32 video_esp32_dvp.c) zephyr_library_sources_ifdef(CONFIG_VIDEO_MCUX_SDMA video_mcux_smartdma.c) zephyr_library_sources_ifdef(CONFIG_VIDEO_EMUL_IMAGER video_emul_imager.c) zephyr_library_sources_ifdef(CONFIG_VIDEO_EMUL_RX video_emul_rx.c) + +zephyr_linker_sources(DATA_SECTIONS video.ld) diff --git a/drivers/video/gc2145.c b/drivers/video/gc2145.c index 8ac3cc24033..676ba48d61b 100644 --- a/drivers/video/gc2145.c +++ b/drivers/video/gc2145.c @@ -14,6 +14,9 @@ #include #include + +#include "video_device.h" + LOG_MODULE_REGISTER(video_gc2145, CONFIG_VIDEO_LOG_LEVEL); #define GC2145_REG_AMODE1 0x17 @@ -1208,3 +1211,5 @@ static int gc2145_init_0(const struct device *dev) DEVICE_DT_INST_DEFINE(0, &gc2145_init_0, NULL, &gc2145_data_0, &gc2145_cfg_0, POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &gc2145_driver_api); + +VIDEO_DEVICE_DEFINE(gc2145, DEVICE_DT_INST_GET(0), NULL); diff --git a/drivers/video/mt9m114.c b/drivers/video/mt9m114.c index 663fa422201..e7536a6d951 100644 --- a/drivers/video/mt9m114.c +++ b/drivers/video/mt9m114.c @@ -15,6 +15,8 @@ #include #include +#include "video_device.h" + LOG_MODULE_REGISTER(video_mt9m114, CONFIG_VIDEO_LOG_LEVEL); #define MT9M114_CHIP_ID_VAL 0x2481 @@ -569,4 +571,7 @@ static int mt9m114_init_0(const struct device *dev) DEVICE_DT_INST_DEFINE(0, &mt9m114_init_0, NULL, &mt9m114_data_0, &mt9m114_cfg_0, POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &mt9m114_driver_api); + +VIDEO_DEVICE_DEFINE(mt9m114, DEVICE_DT_INST_GET(0), NULL); + #endif diff --git a/drivers/video/ov2640.c b/drivers/video/ov2640.c index f89e73dbd9f..128979864f5 100644 --- a/drivers/video/ov2640.c +++ b/drivers/video/ov2640.c @@ -14,6 +14,8 @@ #include #include +#include "video_device.h" + LOG_MODULE_REGISTER(video_ov2640, CONFIG_VIDEO_LOG_LEVEL); /* DSP register bank FF=0x00*/ @@ -1062,3 +1064,5 @@ DEVICE_DT_INST_DEFINE(0, &ov2640_init_0, NULL, &ov2640_data_0, &ov2640_cfg_0, POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &ov2640_driver_api); + +VIDEO_DEVICE_DEFINE(ov2640, DEVICE_DT_INST_GET(0), NULL); diff --git a/drivers/video/ov5640.c b/drivers/video/ov5640.c index cb567bd48bc..334c5e36454 100644 --- a/drivers/video/ov5640.c +++ b/drivers/video/ov5640.c @@ -19,6 +19,8 @@ #include #include +#include "video_device.h" + LOG_MODULE_REGISTER(video_ov5640, CONFIG_VIDEO_LOG_LEVEL); #define CHIP_ID_REG 0x300a @@ -1333,6 +1335,8 @@ static int ov5640_init(const struct device *dev) }; \ \ DEVICE_DT_INST_DEFINE(n, &ov5640_init, NULL, &ov5640_data_##n, &ov5640_cfg_##n, \ - POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &ov5640_driver_api); + POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &ov5640_driver_api); \ + \ + VIDEO_DEVICE_DEFINE(ov5640_##n, DEVICE_DT_INST_GET(n), NULL); DT_INST_FOREACH_STATUS_OKAY(OV5640_INIT) diff --git a/drivers/video/ov7670.c b/drivers/video/ov7670.c index 37be06a7625..0e37cdda3e4 100644 --- a/drivers/video/ov7670.c +++ b/drivers/video/ov7670.c @@ -12,6 +12,8 @@ #include #include +#include "video_device.h" + LOG_MODULE_REGISTER(video_ov7670, CONFIG_VIDEO_LOG_LEVEL); /* Initialization register structure */ @@ -598,6 +600,8 @@ static DEVICE_API(video, ov7670_api) = { struct ov7670_data ov7670_data_##inst; \ \ DEVICE_DT_INST_DEFINE(inst, ov7670_init, NULL, &ov7670_data_##inst, &ov7670_config_##inst, \ - POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &ov7670_api); + POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &ov7670_api); \ + \ + VIDEO_DEVICE_DEFINE(ov7670_##inst, DEVICE_DT_INST_GET(inst), NULL); DT_INST_FOREACH_STATUS_OKAY(OV7670_INIT) diff --git a/drivers/video/ov7725.c b/drivers/video/ov7725.c index 74d1d834017..9297d4a401d 100644 --- a/drivers/video/ov7725.c +++ b/drivers/video/ov7725.c @@ -14,6 +14,8 @@ #include #include +#include "video_device.h" + LOG_MODULE_REGISTER(video_ov7725, CONFIG_VIDEO_LOG_LEVEL); #define OV7725_REVISION 0x7721U @@ -639,3 +641,5 @@ DEVICE_DT_INST_DEFINE(0, &ov7725_init_0, NULL, &ov7725_data_0, &ov7725_cfg_0, POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &ov7725_driver_api); + +VIDEO_DEVICE_DEFINE(ov7725, DEVICE_DT_INST_GET(0), NULL); diff --git a/drivers/video/video.ld b/drivers/video/video.ld new file mode 100644 index 00000000000..935ee1ed302 --- /dev/null +++ b/drivers/video/video.ld @@ -0,0 +1,3 @@ +#include + +ITERABLE_SECTION_RAM(video_device, Z_LINK_ITERABLE_SUBALIGN) diff --git a/drivers/video/video_device.c b/drivers/video/video_device.c new file mode 100644 index 00000000000..a895fed42f1 --- /dev/null +++ b/drivers/video/video_device.c @@ -0,0 +1,22 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "video_device.h" + +struct video_device *video_find_vdev(const struct device *dev) +{ + if (!dev) { + return NULL; + } + + STRUCT_SECTION_FOREACH(video_device, vdev) { + if (vdev->dev == dev) { + return vdev; + } + } + + return NULL; +} diff --git a/drivers/video/video_device.h b/drivers/video/video_device.h new file mode 100644 index 00000000000..130a35b8733 --- /dev/null +++ b/drivers/video/video_device.h @@ -0,0 +1,25 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_VIDEO_VIDEO_DEVICE_H_ +#define ZEPHYR_INCLUDE_DRIVERS_VIDEO_VIDEO_DEVICE_H_ + +#include + +struct video_device { + const struct device *dev; + const struct device *src_dev; +}; + +#define VIDEO_DEVICE_DEFINE(name, device, source) \ + static STRUCT_SECTION_ITERABLE(video_device, name) = { \ + .dev = device, \ + .src_dev = source, \ + } + +struct video_device *video_find_vdev(const struct device *dev); + +#endif /* ZEPHYR_INCLUDE_DRIVERS_VIDEO_VIDEO_DEVICE_H_ */ diff --git a/drivers/video/video_emul_imager.c b/drivers/video/video_emul_imager.c index c7e26a9ff54..90cec728ae0 100644 --- a/drivers/video/video_emul_imager.c +++ b/drivers/video/video_emul_imager.c @@ -17,6 +17,8 @@ #include #include +#include "video_device.h" + LOG_MODULE_REGISTER(video_emul_imager, CONFIG_VIDEO_LOG_LEVEL); #define EMUL_IMAGER_REG_SENSOR_ID 0x0000 @@ -427,6 +429,8 @@ int emul_imager_init(const struct device *dev) \ DEVICE_DT_INST_DEFINE(inst, &emul_imager_init, NULL, &emul_imager_data_##inst, \ &emul_imager_cfg_##inst, POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, \ - &emul_imager_driver_api); + &emul_imager_driver_api); \ + \ + VIDEO_DEVICE_DEFINE(emul_imager_##inst, DEVICE_DT_INST_GET(inst), NULL); DT_INST_FOREACH_STATUS_OKAY(EMUL_IMAGER_DEFINE) diff --git a/drivers/video/video_emul_rx.c b/drivers/video/video_emul_rx.c index 2abb6fef32a..31d8c84d450 100644 --- a/drivers/video/video_emul_rx.c +++ b/drivers/video/video_emul_rx.c @@ -15,6 +15,8 @@ #include #include +#include "video_device.h" + LOG_MODULE_REGISTER(video_emul_rx, CONFIG_VIDEO_LOG_LEVEL); struct emul_rx_config { @@ -296,6 +298,8 @@ int emul_rx_init(const struct device *dev) }; \ \ DEVICE_DT_INST_DEFINE(n, &emul_rx_init, NULL, &emul_rx_data_##n, &emul_rx_cfg_##n, \ - POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &emul_rx_driver_api); + POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &emul_rx_driver_api); \ + \ + VIDEO_DEVICE_DEFINE(emul_rx_##n, DEVICE_DT_INST_GET(n), emul_rx_cfg_##n.source_dev); DT_INST_FOREACH_STATUS_OKAY(EMUL_RX_DEFINE) diff --git a/drivers/video/video_esp32_dvp.c b/drivers/video/video_esp32_dvp.c index 4c93f24bcd1..94cd8266fe6 100644 --- a/drivers/video/video_esp32_dvp.c +++ b/drivers/video/video_esp32_dvp.c @@ -21,6 +21,9 @@ #include #include + +#include "video_device.h" + LOG_MODULE_REGISTER(video_esp32_lcd_cam, CONFIG_VIDEO_LOG_LEVEL); #define VIDEO_ESP32_DMA_BUFFER_MAX_SIZE 4095 @@ -463,6 +466,8 @@ static struct video_esp32_data esp32_data = {0}; DEVICE_DT_INST_DEFINE(0, video_esp32_init, NULL, &esp32_data, &esp32_config, POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &esp32_driver_api); +VIDEO_DEVICE_DEFINE(esp32, DEVICE_DT_INST_GET(0), esp32_config.source_dev); + static int video_esp32_cam_init_master_clock(void) { int ret = 0; diff --git a/drivers/video/video_mcux_csi.c b/drivers/video/video_mcux_csi.c index 34f80b8e2c0..ba2d18cf08f 100644 --- a/drivers/video/video_mcux_csi.c +++ b/drivers/video/video_mcux_csi.c @@ -18,6 +18,8 @@ #include #endif +#include "video_device.h" + struct video_mcux_csi_config { CSI_Type *base; const struct device *source_dev; @@ -506,4 +508,7 @@ static int video_mcux_csi_init_0(const struct device *dev) DEVICE_DT_INST_DEFINE(0, &video_mcux_csi_init_0, NULL, &video_mcux_csi_data_0, &video_mcux_csi_config_0, POST_KERNEL, CONFIG_VIDEO_MCUX_CSI_INIT_PRIORITY, &video_mcux_csi_driver_api); + +VIDEO_DEVICE_DEFINE(csi, DEVICE_DT_INST_GET(0), video_mcux_csi_config_0.source_dev); + #endif diff --git a/drivers/video/video_mcux_mipi_csi2rx.c b/drivers/video/video_mcux_mipi_csi2rx.c index 4c9dfa6135e..275b16b2ea9 100644 --- a/drivers/video/video_mcux_mipi_csi2rx.c +++ b/drivers/video/video_mcux_mipi_csi2rx.c @@ -15,6 +15,8 @@ #include +#include "video_device.h" + LOG_MODULE_REGISTER(video_mipi_csi2rx, CONFIG_VIDEO_LOG_LEVEL); #define MAX_SUPPORTED_PIXEL_RATE MHZ(96) @@ -352,6 +354,9 @@ static int mipi_csi2rx_init(const struct device *dev) \ DEVICE_DT_INST_DEFINE(n, &mipi_csi2rx_init, NULL, &mipi_csi2rx_data_##n, \ &mipi_csi2rx_config_##n, POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, \ - &mipi_csi2rx_driver_api); + &mipi_csi2rx_driver_api); \ + \ + VIDEO_DEVICE_DEFINE(mipi_csi2rx_##n, DEVICE_DT_INST_GET(n), \ + mipi_csi2rx_config_##n.sensor_dev); DT_INST_FOREACH_STATUS_OKAY(MIPI_CSI2RX_INIT) diff --git a/drivers/video/video_mcux_smartdma.c b/drivers/video/video_mcux_smartdma.c index d6f04ad81d3..9081bcb5967 100644 --- a/drivers/video/video_mcux_smartdma.c +++ b/drivers/video/video_mcux_smartdma.c @@ -18,6 +18,8 @@ #include LOG_MODULE_REGISTER(nxp_video_sdma); +#include "video_device.h" + struct nxp_video_sdma_config { const struct device *dma_dev; const struct device *sensor_dev; @@ -363,24 +365,24 @@ static DEVICE_API(video, nxp_video_sdma_api) = { .flush = nxp_video_sdma_flush }; -#define NXP_VIDEO_SDMA_INIT(inst) \ - PINCTRL_DT_INST_DEFINE(inst); \ - const struct nxp_video_sdma_config sdma_config_##inst = { \ - .dma_dev = DEVICE_DT_GET(DT_INST_PARENT(inst)), \ - .sensor_dev = DEVICE_DT_GET(DT_INST_PHANDLE(inst, sensor)), \ - .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ - .vsync_pin = DT_INST_PROP(inst, vsync_pin), \ - .hsync_pin = DT_INST_PROP(inst, hsync_pin), \ - .pclk_pin = DT_INST_PROP(inst, pclk_pin), \ - }; \ - struct nxp_video_sdma_data sdma_data_##inst = { \ - .config = &sdma_config_##inst, \ - }; \ - \ - DEVICE_DT_INST_DEFINE(inst, nxp_video_sdma_init, NULL, \ - &sdma_data_##inst, &sdma_config_##inst, \ - POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ - &nxp_video_sdma_api); +#define NXP_VIDEO_SDMA_INIT(inst) \ + PINCTRL_DT_INST_DEFINE(inst); \ + const struct nxp_video_sdma_config sdma_config_##inst = { \ + .dma_dev = DEVICE_DT_GET(DT_INST_PARENT(inst)), \ + .sensor_dev = DEVICE_DT_GET(DT_INST_PHANDLE(inst, sensor)), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ + .vsync_pin = DT_INST_PROP(inst, vsync_pin), \ + .hsync_pin = DT_INST_PROP(inst, hsync_pin), \ + .pclk_pin = DT_INST_PROP(inst, pclk_pin), \ + }; \ + struct nxp_video_sdma_data sdma_data_##inst = { \ + .config = &sdma_config_##inst, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, nxp_video_sdma_init, NULL, &sdma_data_##inst, \ + &sdma_config_##inst, POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &nxp_video_sdma_api); \ + \ + VIDEO_DEVICE_DEFINE(sdma_##inst, DEVICE_DT_INST_GET(inst), sdma_config_##inst.sensor_dev); DT_INST_FOREACH_STATUS_OKAY(NXP_VIDEO_SDMA_INIT) diff --git a/drivers/video/video_stm32_dcmi.c b/drivers/video/video_stm32_dcmi.c index 7369b3a39f5..4f3415ca87f 100644 --- a/drivers/video/video_stm32_dcmi.c +++ b/drivers/video/video_stm32_dcmi.c @@ -20,6 +20,8 @@ #include +#include "video_device.h" + LOG_MODULE_REGISTER(video_stm32_dcmi, CONFIG_VIDEO_LOG_LEVEL); #if CONFIG_VIDEO_BUFFER_POOL_NUM_MAX < 2 @@ -521,3 +523,5 @@ DEVICE_DT_INST_DEFINE(0, &video_stm32_dcmi_init, &video_stm32_dcmi_config_0, POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &video_stm32_dcmi_driver_api); + +VIDEO_DEVICE_DEFINE(dcmi, DEVICE_DT_INST_GET(0), video_stm32_dcmi_config_0.sensor_dev); diff --git a/drivers/video/video_sw_generator.c b/drivers/video/video_sw_generator.c index d9f0d90e8e0..b912dffa3da 100644 --- a/drivers/video/video_sw_generator.c +++ b/drivers/video/video_sw_generator.c @@ -11,6 +11,8 @@ #include #include +#include "video_device.h" + LOG_MODULE_REGISTER(video_sw_generator, CONFIG_VIDEO_LOG_LEVEL); #define VIDEO_PATTERN_COLOR_BAR 0 @@ -372,3 +374,5 @@ static int video_sw_generator_init(const struct device *dev) DEVICE_DEFINE(video_sw_generator, "VIDEO_SW_GENERATOR", &video_sw_generator_init, NULL, &video_sw_generator_data_0, NULL, POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &video_sw_generator_driver_api); + +VIDEO_DEVICE_DEFINE(video_sw_generator, DEVICE_GET(video_sw_generator), NULL);