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
}
@@ -528,9 +555,64 @@ static int stm32_dcmipp_set_fmt(const struct device *dev, struct video_format *f
528
555
return ret ;
529
556
}
530
557
558
+ #if defined(STM32_DCMIPP_HAS_PIXEL_PIPES )
559
+ static void stm32_dcmipp_get_isp_decimation (struct stm32_dcmipp_data * dcmipp )
560
+ {
561
+ DCMIPP_DecimationConfTypeDef ispdec_cfg ;
562
+ uint32_t is_enabled ;
563
+
564
+ is_enabled = HAL_DCMIPP_PIPE_IsEnabledISPDecimation (& dcmipp -> hdcmipp , DCMIPP_PIPE1 );
565
+ if (is_enabled == 0 ) {
566
+ dcmipp -> isp_dec_hratio = 1 ;
567
+ dcmipp -> isp_dec_vratio = 1 ;
568
+ } else {
569
+ HAL_DCMIPP_PIPE_GetISPDecimationConfig (& dcmipp -> hdcmipp , DCMIPP_PIPE1 , & ispdec_cfg );
570
+ dcmipp -> isp_dec_hratio = 1 << (ispdec_cfg .HRatio >> DCMIPP_P1DECR_HDEC_Pos );
571
+ dcmipp -> isp_dec_vratio = 1 << (ispdec_cfg .VRatio >> DCMIPP_P1DECR_VDEC_Pos );
572
+ }
573
+ }
574
+ #endif
575
+
531
576
static int stm32_dcmipp_get_fmt (const struct device * dev , struct video_format * fmt )
532
577
{
533
578
struct stm32_dcmipp_pipe_data * pipe = dev -> data ;
579
+ #if defined(STM32_DCMIPP_HAS_PIXEL_PIPES )
580
+ struct stm32_dcmipp_data * dcmipp = pipe -> dcmipp ;
581
+ const struct stm32_dcmipp_config * config = dev -> config ;
582
+ static atomic_t isp_init_once ;
583
+ int ret ;
584
+
585
+ /* Initialize the external ISP handling stack */
586
+ /*
587
+ * TODO - this is not the right place to do that, however we need to know
588
+ * the source format before calling the isp_init handler hence can't
589
+ * do that within the stm32_dcmipp_init function due to unknown
590
+ * driver initialization order
591
+ *
592
+ * Would need an ops that get called when both side of an endpoint get
593
+ * initiialized
594
+ */
595
+ if (atomic_cas (& isp_init_once , 0 , 1 ) &&
596
+ (pipe -> id == DCMIPP_PIPE1 || pipe -> id == DCMIPP_PIPE2 )) {
597
+ /*
598
+ * It is necessary to perform a dummy configuration here otherwise any
599
+ * ISP related configuration done by the stm32_dcmipp_isp_init will
600
+ * fail due to the HAL DCMIPP driver not being in READY state
601
+ */
602
+ ret = stm32_dcmipp_conf_parallel (dcmipp -> dev , & stm32_dcmipp_input_fmt_desc [0 ]);
603
+ if (ret < 0 ) {
604
+ LOG_ERR ("Failed to perform dummy parallel configuration" );
605
+ return ret ;
606
+ }
607
+
608
+ ret = stm32_dcmipp_isp_init (& dcmipp -> hdcmipp , config -> source_dev );
609
+ if (ret < 0 ) {
610
+ LOG_ERR ("Failed to initialize the ISP" );
611
+ return ret ;
612
+ }
613
+ stm32_dcmipp_get_isp_decimation (dcmipp );
614
+ }
615
+ #endif
534
616
535
617
* fmt = pipe -> fmt ;
536
618
@@ -866,6 +948,12 @@ static int stm32_dcmipp_stream_enable(const struct device *dev)
866
948
}
867
949
#endif
868
950
951
+ /* Initialize the external ISP handling stack */
952
+ ret = stm32_dcmipp_isp_init (& dcmipp -> hdcmipp , config -> source_dev );
953
+ if (ret < 0 ) {
954
+ goto out ;
955
+ }
956
+
869
957
/* Enable the DCMIPP Pipeline */
870
958
if (config -> bus_type == VIDEO_BUS_TYPE_PARALLEL ) {
871
959
ret = HAL_DCMIPP_PIPE_Start (& dcmipp -> hdcmipp , pipe -> id ,
@@ -911,6 +999,12 @@ static int stm32_dcmipp_stream_enable(const struct device *dev)
911
999
}
912
1000
}
913
1001
1002
+ /* Start the external ISP handling */
1003
+ ret = stm32_dcmipp_isp_start ();
1004
+ if (ret < 0 ) {
1005
+ goto out ;
1006
+ }
1007
+
914
1008
pipe -> state = STM32_DCMIPP_RUNNING ;
915
1009
pipe -> is_streaming = true;
916
1010
dcmipp -> enabled_pipe ++ ;
@@ -935,6 +1029,12 @@ static int stm32_dcmipp_stream_disable(const struct device *dev)
935
1029
goto out ;
936
1030
}
937
1031
1032
+ /* Stop the external ISP handling */
1033
+ ret = stm32_dcmipp_isp_stop ();
1034
+ if (ret < 0 ) {
1035
+ goto out ;
1036
+ }
1037
+
938
1038
/* Disable the DCMIPP Pipeline */
939
1039
if (config -> bus_type == VIDEO_BUS_TYPE_PARALLEL ) {
940
1040
ret = HAL_DCMIPP_PIPE_Stop (& dcmipp -> hdcmipp , pipe -> id );
0 commit comments