1616#include <zephyr/drivers/video-controls.h>
1717#include <zephyr/dt-bindings/video/video-interfaces.h>
1818#include <zephyr/logging/log.h>
19+ #include <zephyr/video/stm32_dcmipp.h>
1920
2021#include "video_ctrls.h"
2122#include "video_device.h"
3334#define STM32_DCMIPP_HAS_PIXEL_PIPES
3435#endif
3536
37+ /* Weak function declaration in order to interface with external ISP handler */
38+ void __weak stm32_dcmipp_isp_vsync_update (DCMIPP_HandleTypeDef * hdcmipp , uint32_t Pipe )
39+ {
40+ }
41+
42+ int __weak stm32_dcmipp_isp_init (DCMIPP_HandleTypeDef * hdcmipp , const struct device * source )
43+ {
44+ return 0 ;
45+ }
46+
47+ int __weak stm32_dcmipp_isp_start (void )
48+ {
49+ return 0 ;
50+ }
51+
52+ int __weak stm32_dcmipp_isp_stop (void )
53+ {
54+ return 0 ;
55+ }
56+
3657LOG_MODULE_REGISTER (stm32_dcmipp , CONFIG_VIDEO_LOG_LEVEL );
3758
3859typedef void (* irq_config_func_t )(const struct device * dev );
@@ -148,6 +169,12 @@ void HAL_DCMIPP_PIPE_VsyncEventCallback(DCMIPP_HandleTypeDef *hdcmipp, uint32_t
148169 struct stm32_dcmipp_pipe_data * pipe = dcmipp -> pipe [Pipe ];
149170 int ret ;
150171
172+ /*
173+ * Let the external ISP handler know that a VSYNC happened a new statistics are
174+ * thus available
175+ */
176+ stm32_dcmipp_isp_vsync_update (hdcmipp , Pipe );
177+
151178 if (pipe -> state != STM32_DCMIPP_RUNNING ) {
152179 return ;
153180 }
@@ -526,9 +553,64 @@ static int stm32_dcmipp_set_fmt(const struct device *dev, struct video_format *f
526553 return ret ;
527554}
528555
556+ #if defined(STM32_DCMIPP_HAS_PIXEL_PIPES )
557+ static void stm32_dcmipp_get_isp_decimation (struct stm32_dcmipp_data * dcmipp )
558+ {
559+ DCMIPP_DecimationConfTypeDef ispdec_cfg ;
560+ uint32_t is_enabled ;
561+
562+ is_enabled = HAL_DCMIPP_PIPE_IsEnabledISPDecimation (& dcmipp -> hdcmipp , DCMIPP_PIPE1 );
563+ if (is_enabled == 0 ) {
564+ dcmipp -> isp_dec_hratio = 1 ;
565+ dcmipp -> isp_dec_vratio = 1 ;
566+ } else {
567+ HAL_DCMIPP_PIPE_GetISPDecimationConfig (& dcmipp -> hdcmipp , DCMIPP_PIPE1 , & ispdec_cfg );
568+ dcmipp -> isp_dec_hratio = 1 << (ispdec_cfg .HRatio >> DCMIPP_P1DECR_HDEC_Pos );
569+ dcmipp -> isp_dec_vratio = 1 << (ispdec_cfg .VRatio >> DCMIPP_P1DECR_VDEC_Pos );
570+ }
571+ }
572+ #endif
573+
529574static int stm32_dcmipp_get_fmt (const struct device * dev , struct video_format * fmt )
530575{
531576 struct stm32_dcmipp_pipe_data * pipe = dev -> data ;
577+ #if defined(STM32_DCMIPP_HAS_PIXEL_PIPES )
578+ struct stm32_dcmipp_data * dcmipp = pipe -> dcmipp ;
579+ const struct stm32_dcmipp_config * config = dev -> config ;
580+ static atomic_t isp_init_once ;
581+ int ret ;
582+
583+ /* Initialize the external ISP handling stack */
584+ /*
585+ * TODO - this is not the right place to do that, however we need to know
586+ * the source format before calling the isp_init handler hence can't
587+ * do that within the stm32_dcmipp_init function due to unknown
588+ * driver initialization order
589+ *
590+ * Would need an ops that get called when both side of an endpoint get
591+ * initiialized
592+ */
593+ if (atomic_cas (& isp_init_once , 0 , 1 ) &&
594+ (pipe -> id == DCMIPP_PIPE1 || pipe -> id == DCMIPP_PIPE2 )) {
595+ /*
596+ * It is necessary to perform a dummy configuration here otherwise any
597+ * ISP related configuration done by the stm32_dcmipp_isp_init will
598+ * fail due to the HAL DCMIPP driver not being in READY state
599+ */
600+ ret = stm32_dcmipp_conf_parallel (dcmipp -> dev , & stm32_dcmipp_input_fmt_desc [0 ]);
601+ if (ret < 0 ) {
602+ LOG_ERR ("Failed to perform dummy parallel configuration" );
603+ return ret ;
604+ }
605+
606+ ret = stm32_dcmipp_isp_init (& dcmipp -> hdcmipp , config -> source_dev );
607+ if (ret < 0 ) {
608+ LOG_ERR ("Failed to initialize the ISP" );
609+ return ret ;
610+ }
611+ stm32_dcmipp_get_isp_decimation (dcmipp );
612+ }
613+ #endif
532614
533615 * fmt = pipe -> fmt ;
534616
@@ -864,6 +946,12 @@ static int stm32_dcmipp_stream_enable(const struct device *dev)
864946 }
865947#endif
866948
949+ /* Initialize the external ISP handling stack */
950+ ret = stm32_dcmipp_isp_init (& dcmipp -> hdcmipp , config -> source_dev );
951+ if (ret < 0 ) {
952+ goto out ;
953+ }
954+
867955 /* Enable the DCMIPP Pipeline */
868956 if (config -> bus_type == VIDEO_BUS_TYPE_PARALLEL ) {
869957 ret = HAL_DCMIPP_PIPE_Start (& dcmipp -> hdcmipp , pipe -> id ,
@@ -909,6 +997,12 @@ static int stm32_dcmipp_stream_enable(const struct device *dev)
909997 }
910998 }
911999
1000+ /* Start the external ISP handling */
1001+ ret = stm32_dcmipp_isp_start ();
1002+ if (ret < 0 ) {
1003+ goto out ;
1004+ }
1005+
9121006 pipe -> state = STM32_DCMIPP_RUNNING ;
9131007 pipe -> is_streaming = true;
9141008 dcmipp -> enabled_pipe ++ ;
@@ -933,6 +1027,12 @@ static int stm32_dcmipp_stream_disable(const struct device *dev)
9331027 goto out ;
9341028 }
9351029
1030+ /* Stop the external ISP handling */
1031+ ret = stm32_dcmipp_isp_stop ();
1032+ if (ret < 0 ) {
1033+ goto out ;
1034+ }
1035+
9361036 /* Disable the DCMIPP Pipeline */
9371037 if (config -> bus_type == VIDEO_BUS_TYPE_PARALLEL ) {
9381038 ret = HAL_DCMIPP_PIPE_Stop (& dcmipp -> hdcmipp , pipe -> id );
0 commit comments