1414#include <zephyr/drivers/i2c.h>
1515#include <zephyr/drivers/gpio.h>
1616
17+ #include "video_ctrls.h"
1718#include "video_device.h"
1819
1920LOG_MODULE_REGISTER (video_ov2640 , CONFIG_VIDEO_LOG_LEVEL );
@@ -441,7 +442,21 @@ struct ov2640_config {
441442 uint8_t clock_rate_control ;
442443};
443444
445+ struct ov2640_ctrls {
446+ struct video_ctrl hflip ;
447+ struct video_ctrl vflip ;
448+ struct video_ctrl ae ;
449+ struct video_ctrl awb ;
450+ struct video_ctrl gain ;
451+ struct video_ctrl contrast ;
452+ struct video_ctrl brightness ;
453+ struct video_ctrl saturation ;
454+ struct video_ctrl jpeg ;
455+ struct video_ctrl test_pattern ;
456+ };
457+
444458struct ov2640_data {
459+ struct ov2640_ctrls ctrls ;
445460 struct video_format fmt ;
446461};
447462
@@ -565,10 +580,7 @@ static int ov2640_set_level(const struct device *dev, int level,
565580 int ret = 0 ;
566581 const struct ov2640_config * cfg = dev -> config ;
567582
568- level += (max_level / 2 + 1 );
569- if (level < 0 || level > max_level ) {
570- return - ENOTSUP ;
571- }
583+ level += max_level / 2 + 1 ;
572584
573585 /* Switch to DSP register bank */
574586 ret |= ov2640_write_reg (& cfg -> i2c , BANK_SEL , BANK_SEL_DSP );
@@ -580,48 +592,6 @@ static int ov2640_set_level(const struct device *dev, int level,
580592 return ret ;
581593}
582594
583- static int ov2640_set_brightness (const struct device * dev , int level )
584- {
585- int ret = 0 ;
586-
587- ret = ov2640_set_level (dev , level , NUM_BRIGHTNESS_LEVELS ,
588- ARRAY_SIZE (brightness_regs [0 ]), brightness_regs );
589-
590- if (ret == - ENOTSUP ) {
591- LOG_ERR ("Brightness level %d not supported" , level );
592- }
593-
594- return ret ;
595- }
596-
597- static int ov2640_set_saturation (const struct device * dev , int level )
598- {
599- int ret = 0 ;
600-
601- ret = ov2640_set_level (dev , level , NUM_SATURATION_LEVELS ,
602- ARRAY_SIZE (saturation_regs [0 ]), saturation_regs );
603-
604- if (ret == - ENOTSUP ) {
605- LOG_ERR ("Saturation level %d not supported" , level );
606- }
607-
608- return ret ;
609- }
610-
611- static int ov2640_set_contrast (const struct device * dev , int level )
612- {
613- int ret = 0 ;
614-
615- ret = ov2640_set_level (dev , level , NUM_CONTRAST_LEVELS ,
616- ARRAY_SIZE (contrast_regs [0 ]), contrast_regs );
617-
618- if (ret == - ENOTSUP ) {
619- LOG_ERR ("Contrast level %d not supported" , level );
620- }
621-
622- return ret ;
623- }
624-
625595static int ov2640_set_output_format (const struct device * dev ,
626596 int output_format )
627597{
@@ -925,47 +895,35 @@ static int ov2640_get_caps(const struct device *dev,
925895 return 0 ;
926896}
927897
928- static int ov2640_set_ctrl (const struct device * dev ,
929- unsigned int cid , void * value )
898+ static int ov2640_set_ctrl (const struct device * dev , struct video_control * ctrl )
930899{
931- int ret = 0 ;
932-
933- switch (cid ) {
900+ switch (ctrl -> id ) {
934901 case VIDEO_CID_HFLIP :
935- ret |= ov2640_set_horizontal_mirror (dev , (int )value );
936- break ;
902+ return ov2640_set_horizontal_mirror (dev , ctrl -> val );
937903 case VIDEO_CID_VFLIP :
938- ret |= ov2640_set_vertical_flip (dev , (int )value );
939- break ;
904+ return ov2640_set_vertical_flip (dev , ctrl -> val );
940905 case VIDEO_CID_EXPOSURE :
941- ret |= ov2640_set_exposure_ctrl (dev , (int )value );
942- break ;
906+ return ov2640_set_exposure_ctrl (dev , ctrl -> val );
907+ case VIDEO_CID_WHITE_BALANCE_TEMPERATURE :
908+ return ov2640_set_white_bal (dev , ctrl -> val );
943909 case VIDEO_CID_GAIN :
944- ret |= ov2640_set_gain_ctrl (dev , (int )value );
945- break ;
910+ return ov2640_set_gain_ctrl (dev , ctrl -> val );
946911 case VIDEO_CID_BRIGHTNESS :
947- ret |= ov2640_set_brightness (dev , (int )value );
948- break ;
949- case VIDEO_CID_SATURATION :
950- ret |= ov2640_set_saturation (dev , (int )value );
951- break ;
952- case VIDEO_CID_WHITE_BALANCE_TEMPERATURE :
953- ret |= ov2640_set_white_bal (dev , (int )value );
954- break ;
912+ return ov2640_set_level (dev , ctrl -> val , NUM_BRIGHTNESS_LEVELS ,
913+ ARRAY_SIZE (brightness_regs [0 ]), brightness_regs );
955914 case VIDEO_CID_CONTRAST :
956- ret |= ov2640_set_contrast (dev , ( int ) value );
957- break ;
958- case VIDEO_CID_TEST_PATTERN :
959- ret |= ov2640_set_colorbar (dev , ( int ) value );
960- break ;
915+ return ov2640_set_level (dev , ctrl -> val , NUM_CONTRAST_LEVELS ,
916+ ARRAY_SIZE ( contrast_regs [ 0 ]), contrast_regs ) ;
917+ case VIDEO_CID_SATURATION :
918+ return ov2640_set_level (dev , ctrl -> val , NUM_SATURATION_LEVELS ,
919+ ARRAY_SIZE ( saturation_regs [ 0 ]), saturation_regs ) ;
961920 case VIDEO_CID_JPEG_COMPRESSION_QUALITY :
962- ret |= ov2640_set_quality (dev , (int )value );
963- break ;
921+ return ov2640_set_quality (dev , ctrl -> val );
922+ case VIDEO_CID_TEST_PATTERN :
923+ return ov2640_set_colorbar (dev , ctrl -> val );
964924 default :
965925 return - ENOTSUP ;
966926 }
967-
968- return ret ;
969927}
970928
971929static DEVICE_API (video , ov2640_driver_api ) = {
@@ -976,6 +934,61 @@ static DEVICE_API(video, ov2640_driver_api) = {
976934 .set_ctrl = ov2640_set_ctrl ,
977935};
978936
937+ static int ov2640_init_controls (const struct device * dev )
938+ {
939+ int ret ;
940+ struct ov2640_data * drv_data = dev -> data ;
941+ struct ov2640_ctrls * ctrls = & drv_data -> ctrls ;
942+
943+ ret = video_init_ctrl (& ctrls -> hflip , dev , VIDEO_CID_HFLIP , 0 , 1 , 1 , 0 );
944+ if (ret ) {
945+ return ret ;
946+ }
947+
948+ ret = video_init_ctrl (& ctrls -> vflip , dev , VIDEO_CID_VFLIP , 0 , 1 , 1 , 0 );
949+ if (ret ) {
950+ return ret ;
951+ }
952+
953+ ret = video_init_ctrl (& ctrls -> ae , dev , VIDEO_CID_EXPOSURE , 0 , 1 , 1 , 1 );
954+ if (ret ) {
955+ return ret ;
956+ }
957+
958+ ret = video_init_ctrl (& ctrls -> awb , dev , VIDEO_CID_WHITE_BALANCE_TEMPERATURE , 0 , 1 , 1 , 1 );
959+ if (ret ) {
960+ return ret ;
961+ }
962+
963+ ret = video_init_ctrl (& ctrls -> gain , dev , VIDEO_CID_GAIN , 0 , 1 , 1 , 1 );
964+ if (ret ) {
965+ return ret ;
966+ }
967+
968+ ret = video_init_ctrl (& ctrls -> brightness , dev , VIDEO_CID_BRIGHTNESS , -2 , 2 , 1 , 0 );
969+ if (ret ) {
970+ return ret ;
971+ }
972+
973+ ret = video_init_ctrl (& ctrls -> contrast , dev , VIDEO_CID_CONTRAST , -2 , 2 , 1 , 0 );
974+ if (ret ) {
975+ return ret ;
976+ }
977+
978+ ret = video_init_ctrl (& ctrls -> saturation , dev , VIDEO_CID_SATURATION , -2 , 2 , 1 , 0 );
979+ if (ret ) {
980+ return ret ;
981+ }
982+
983+ ret = video_init_ctrl (& ctrls -> saturation , dev , VIDEO_CID_JPEG_COMPRESSION_QUALITY , 5 , 100 ,
984+ 1 , 50 );
985+ if (ret ) {
986+ return ret ;
987+ }
988+
989+ return video_init_ctrl (& ctrls -> test_pattern , dev , VIDEO_CID_TEST_PATTERN , 0 , 1 , 1 , 0 );
990+ }
991+
979992static int ov2640_init (const struct device * dev )
980993{
981994 struct video_format fmt ;
@@ -1020,7 +1033,12 @@ static int ov2640_init(const struct device *dev)
10201033 ret |= ov2640_set_exposure_ctrl (dev , 1 );
10211034 ret |= ov2640_set_white_bal (dev , 1 );
10221035
1023- return ret ;
1036+ if (ret ) {
1037+ return ret ;
1038+ }
1039+
1040+ /* Initialize controls */
1041+ return ov2640_init_controls (dev );
10241042}
10251043
10261044/* Unique Instance */
0 commit comments