16
16
#include <zephyr/drivers/video-controls.h>
17
17
#include <zephyr/dt-bindings/video/video-interfaces.h>
18
18
#include <zephyr/logging/log.h>
19
+ #include <zephyr/video/stm32_dcmipp.h>
19
20
20
21
#include "video_ctrls.h"
21
22
#include "video_device.h"
33
34
#define STM32_DCMIPP_HAS_PIXEL_PIPES
34
35
#endif
35
36
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
+
36
57
LOG_MODULE_REGISTER (stm32_dcmipp , CONFIG_VIDEO_LOG_LEVEL );
37
58
38
59
typedef void (* irq_config_func_t )(const struct device * dev );
@@ -148,6 +169,12 @@ void HAL_DCMIPP_PIPE_VsyncEventCallback(DCMIPP_HandleTypeDef *hdcmipp, uint32_t
148
169
struct stm32_dcmipp_pipe_data * pipe = dcmipp -> pipe [Pipe ];
149
170
int ret ;
150
171
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
+
151
178
if (pipe -> state != STM32_DCMIPP_RUNNING ) {
152
179
return ;
153
180
}
@@ -526,9 +553,64 @@ static int stm32_dcmipp_set_fmt(const struct device *dev, struct video_format *f
526
553
return ret ;
527
554
}
528
555
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
+
529
574
static int stm32_dcmipp_get_fmt (const struct device * dev , struct video_format * fmt )
530
575
{
531
576
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
532
614
533
615
* fmt = pipe -> fmt ;
534
616
@@ -864,6 +946,12 @@ static int stm32_dcmipp_stream_enable(const struct device *dev)
864
946
}
865
947
#endif
866
948
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
+
867
955
/* Enable the DCMIPP Pipeline */
868
956
if (config -> bus_type == VIDEO_BUS_TYPE_PARALLEL ) {
869
957
ret = HAL_DCMIPP_PIPE_Start (& dcmipp -> hdcmipp , pipe -> id ,
@@ -909,6 +997,12 @@ static int stm32_dcmipp_stream_enable(const struct device *dev)
909
997
}
910
998
}
911
999
1000
+ /* Start the external ISP handling */
1001
+ ret = stm32_dcmipp_isp_start ();
1002
+ if (ret < 0 ) {
1003
+ goto out ;
1004
+ }
1005
+
912
1006
pipe -> state = STM32_DCMIPP_RUNNING ;
913
1007
pipe -> is_streaming = true;
914
1008
dcmipp -> enabled_pipe ++ ;
@@ -933,6 +1027,12 @@ static int stm32_dcmipp_stream_disable(const struct device *dev)
933
1027
goto out ;
934
1028
}
935
1029
1030
+ /* Stop the external ISP handling */
1031
+ ret = stm32_dcmipp_isp_stop ();
1032
+ if (ret < 0 ) {
1033
+ goto out ;
1034
+ }
1035
+
936
1036
/* Disable the DCMIPP Pipeline */
937
1037
if (config -> bus_type == VIDEO_BUS_TYPE_PARALLEL ) {
938
1038
ret = HAL_DCMIPP_PIPE_Stop (& dcmipp -> hdcmipp , pipe -> id );
0 commit comments