12
12
#include <zephyr/drivers/video-controls.h>
13
13
#include <zephyr/drivers/i2c.h>
14
14
#include <zephyr/drivers/gpio.h>
15
-
16
15
#include <zephyr/logging/log.h>
16
+
17
+ #include "video_common.h"
18
+
17
19
LOG_MODULE_REGISTER (video_gc2145 , CONFIG_VIDEO_LOG_LEVEL );
18
20
19
- #define GC2145_REG_AMODE1 0x17
21
+ #define GC2145_REG8 (addr ) ((addr) | VIDEO_REG_ADDR8_DATA8)
22
+ #define GC2145_REG16 (addr ) ((addr) | VIDEO_REG_ADDR8_DATA16_LE)
23
+
24
+ #define GC2145_REG_AMODE1 GC2145_REG8(0x17)
20
25
#define GC2145_AMODE1_WINDOW_MASK 0xFC
21
- #define GC2145_REG_AMODE1_DEF 0x14
22
- #define GC2145_REG_OUTPUT_FMT 0x84
23
- #define GC2145_REG_OUTPUT_FMT_MASK 0x1F
24
- #define GC2145_REG_OUTPUT_FMT_RGB565 0x06
25
- #define GC2145_REG_OUTPUT_FMT_YCBYCR 0x02
26
- #define GC2145_REG_SYNC_MODE 0x86
27
- #define GC2145_REG_SYNC_MODE_DEF 0x23
28
- #define GC2145_REG_SYNC_MODE_COL_SWITCH 0x10
29
- #define GC2145_REG_SYNC_MODE_ROW_SWITCH 0x20
30
- #define GC2145_REG_RESET 0xFE
31
- #define GC2145_REG_SW_RESET 0x80
26
+ #define GC2145_REG_AMODE1_DEF GC2145_REG8(0x14)
27
+ #define GC2145_REG_OUTPUT_FMT GC2145_REG8(0x84)
28
+ #define GC2145_REG_OUTPUT_FMT_MASK GC2145_REG8(0x1F)
29
+ #define GC2145_REG_OUTPUT_FMT_RGB565 GC2145_REG8(0x06)
30
+ #define GC2145_REG_OUTPUT_FMT_YCBYCR GC2145_REG8(0x02)
31
+ #define GC2145_REG_SYNC_MODE GC2145_REG8(0x86)
32
+ #define GC2145_REG_SYNC_MODE_DEF GC2145_REG8(0x23)
33
+ #define GC2145_REG_SYNC_MODE_COL_SWITCH GC2145_REG8(0x10)
34
+ #define GC2145_REG_SYNC_MODE_ROW_SWITCH GC2145_REG8(0x20)
35
+ #define GC2145_REG_RESET GC2145_REG8(0xFE)
36
+ #define GC2145_REG_SW_RESET GC2145_REG8(0x80)
37
+ #define GC2145_REG_CHIP_ID GC2145_REG8(0xF0)
32
38
#define GC2145_SET_P0_REGS 0x00
33
- #define GC2145_REG_CROP_ENABLE 0x90
39
+ #define GC2145_REG_CROP_ENABLE GC2145_REG8( 0x90)
34
40
#define GC2145_CROP_SET_ENABLE 0x01
35
- #define GC2145_REG_BLANK_WINDOW_BASE 0x09
36
- #define GC2145_REG_WINDOW_BASE 0x91
37
- #define GC2145_REG_SUBSAMPLE 0x99
38
- #define GC2145_REG_SUBSAMPLE_MODE 0x9A
41
+ #define GC2145_REG_BLANK_WINDOW_BASE GC2145_REG8( 0x09)
42
+ #define GC2145_REG_WINDOW_BASE GC2145_REG8( 0x91)
43
+ #define GC2145_REG_SUBSAMPLE GC2145_REG8( 0x99)
44
+ #define GC2145_REG_SUBSAMPLE_MODE GC2145_REG8( 0x9A)
39
45
#define GC2145_SUBSAMPLE_MODE_SMOOTH 0x0E
40
46
41
47
#define UXGA_HSIZE 1600
@@ -103,8 +109,8 @@ static const struct gc2145_reg default_regs[] = {
103
109
{0x81 , 0x26 },
104
110
{0x82 , 0xfa },
105
111
{0x83 , 0x00 },
106
- {GC2145_REG_OUTPUT_FMT , 0x06 },
107
- {GC2145_REG_SYNC_MODE , 0x23 },
112
+ {( uint8_t ) GC2145_REG_OUTPUT_FMT , 0x06 },
113
+ {( uint8_t ) GC2145_REG_SYNC_MODE , 0x23 },
108
114
{0x88 , 0x03 },
109
115
{0x89 , 0x03 },
110
116
{0x85 , 0x08 },
@@ -195,7 +201,7 @@ static const struct gc2145_reg default_regs[] = {
195
201
{0x0c , 0x10 },
196
202
{0x11 , 0x10 },
197
203
{0x13 , 0x68 },
198
- {GC2145_REG_OUTPUT_FMT , 0x00 },
204
+ {( uint8_t ) GC2145_REG_OUTPUT_FMT , 0x00 },
199
205
{0x1c , 0x11 },
200
206
{0x1e , 0x61 },
201
207
{0x1f , 0x35 },
@@ -226,8 +232,8 @@ static const struct gc2145_reg default_regs[] = {
226
232
{0x81 , 0x08 },
227
233
{0x82 , 0x05 },
228
234
{0x83 , 0x08 },
229
- {GC2145_REG_OUTPUT_FMT , 0x0a },
230
- {GC2145_REG_SYNC_MODE , 0xf0 },
235
+ {( uint8_t ) GC2145_REG_OUTPUT_FMT , 0x0a },
236
+ {( uint8_t ) GC2145_REG_SYNC_MODE , 0xf0 },
231
237
{0x87 , 0x50 },
232
238
{0x88 , 0x15 },
233
239
{0x89 , 0xb0 },
@@ -262,7 +268,7 @@ static const struct gc2145_reg default_regs[] = {
262
268
{0x14 , 0x27 },
263
269
{0x15 , 0x37 },
264
270
{0x16 , 0x45 },
265
- {GC2145_REG_OUTPUT_FMT , 0x53 },
271
+ {( uint8_t ) GC2145_REG_OUTPUT_FMT , 0x53 },
266
272
{0x18 , 0x69 },
267
273
{0x19 , 0x7d },
268
274
{0x1a , 0x8f },
@@ -718,54 +724,6 @@ static const struct video_format_cap fmts[] = {
718
724
{0 },
719
725
};
720
726
721
- static int gc2145_write_reg (const struct i2c_dt_spec * spec , uint8_t reg_addr , uint8_t value )
722
- {
723
- int ret ;
724
- uint8_t tries = 3 ;
725
-
726
- /*
727
- * It rarely happens that the camera does not respond with ACK signal.
728
- * In that case it usually responds on 2nd try but there is a 3rd one
729
- * just to be sure that the connection error is not caused by driver
730
- * itself.
731
- */
732
- do {
733
- ret = i2c_reg_write_byte_dt (spec , reg_addr , value );
734
- if (!ret ) {
735
- return 0 ;
736
- }
737
- /* If writing failed wait 5ms before next attempt */
738
- k_msleep (5 );
739
- } while (tries -- > 0 );
740
-
741
- LOG_ERR ("failed to write 0x%x to 0x%x," , value , reg_addr );
742
- return ret ;
743
- }
744
-
745
- static int gc2145_read_reg (const struct i2c_dt_spec * spec , uint8_t reg_addr , uint8_t * value )
746
- {
747
- int ret ;
748
- uint8_t tries = 3 ;
749
-
750
- /*
751
- * It rarely happens that the camera does not respond with ACK signal.
752
- * In that case it usually responds on 2nd try but there is a 3rd one
753
- * just to be sure that the connection error is not caused by driver
754
- * itself.
755
- */
756
- do {
757
- ret = i2c_reg_read_byte_dt (spec , reg_addr , value );
758
- if (!ret ) {
759
- return 0 ;
760
- }
761
- /* If writing failed wait 5ms before next attempt */
762
- k_msleep (5 );
763
- } while (tries -- > 0 );
764
-
765
- LOG_ERR ("failed to read 0x%x register" , reg_addr );
766
- return ret ;
767
- }
768
-
769
727
static int gc2145_write_all (const struct device * dev , const struct gc2145_reg * regs ,
770
728
uint16_t reg_num )
771
729
{
@@ -774,7 +732,7 @@ static int gc2145_write_all(const struct device *dev, const struct gc2145_reg *r
774
732
for (uint16_t i = 0 ; i < reg_num ; i ++ ) {
775
733
int ret ;
776
734
777
- ret = gc2145_write_reg (& cfg -> i2c , regs [i ].addr , regs [i ].value );
735
+ ret = video_write_cci_reg (& cfg -> i2c , GC2145_REG8 ( regs [i ].addr ) , regs [i ].value );
778
736
if (ret < 0 ) {
779
737
return ret ;
780
738
}
@@ -789,7 +747,7 @@ static int gc2145_soft_reset(const struct device *dev)
789
747
const struct gc2145_config * cfg = dev -> config ;
790
748
791
749
/* Initiate system reset */
792
- ret = gc2145_write_reg (& cfg -> i2c , GC2145_REG_RESET , GC2145_REG_SW_RESET );
750
+ ret = video_write_cci_reg (& cfg -> i2c , GC2145_REG_RESET , GC2145_REG_SW_RESET );
793
751
794
752
k_msleep (300 );
795
753
@@ -798,87 +756,49 @@ static int gc2145_soft_reset(const struct device *dev)
798
756
799
757
static int gc2145_set_ctrl_vflip (const struct device * dev , bool enable )
800
758
{
801
- int ret ;
802
759
const struct gc2145_config * cfg = dev -> config ;
803
- uint8_t old_value ;
804
-
805
- ret = gc2145_read_reg (& cfg -> i2c , GC2145_REG_AMODE1 , & old_value );
806
- if (ret < 0 ) {
807
- return ret ;
808
- }
809
760
810
761
/* Set the vertical flip state */
811
- return gc2145_write_reg (& cfg -> i2c , GC2145_REG_AMODE1 ,
812
- ( old_value & GC2145_AMODE1_WINDOW_MASK ) | ( enable << 1 ));
762
+ return video_modify_cci_reg (& cfg -> i2c , GC2145_REG_AMODE1 , GC2145_AMODE1_WINDOW_MASK ,
763
+ FIELD_PREP ( GC2145_AMODE1_WINDOW_MASK , enable << 1 ));
813
764
}
814
765
815
766
static int gc2145_set_ctrl_hmirror (const struct device * dev , bool enable )
816
767
{
817
- int ret ;
818
768
const struct gc2145_config * cfg = dev -> config ;
819
- uint8_t old_value ;
820
-
821
- ret = gc2145_read_reg (& cfg -> i2c , GC2145_REG_AMODE1 , & old_value );
822
- if (ret < 0 ) {
823
- return ret ;
824
- }
825
769
826
770
/* Set the horizontal mirror state */
827
- return gc2145_write_reg (& cfg -> i2c , GC2145_REG_AMODE1 ,
828
- ( old_value & GC2145_AMODE1_WINDOW_MASK ) | enable );
771
+ return video_modify_cci_reg (& cfg -> i2c , GC2145_REG_AMODE1 , GC2145_AMODE1_WINDOW_MASK ,
772
+ FIELD_PREP ( GC2145_AMODE1_WINDOW_MASK , enable ) );
829
773
}
830
774
831
- static int gc2145_set_window (const struct device * dev , uint16_t reg , uint16_t x , uint16_t y ,
832
- uint16_t w , uint16_t h )
775
+ static int gc2145_set_window (const struct device * dev , uint32_t reg , uint32_t x_offset ,
776
+ uint32_t y_offset , uint32_t window_width , uint32_t window_height )
833
777
{
834
778
int ret ;
835
779
const struct gc2145_config * cfg = dev -> config ;
836
780
837
- ret = gc2145_write_reg (& cfg -> i2c , GC2145_REG_RESET , GC2145_SET_P0_REGS );
838
- if (ret < 0 ) {
839
- return ret ;
840
- }
841
-
842
- /* Y/row offset */
843
- ret = gc2145_write_reg (& cfg -> i2c , reg ++ , y >> 8 );
781
+ ret = video_write_cci_reg (& cfg -> i2c , GC2145_REG_RESET , GC2145_SET_P0_REGS );
844
782
if (ret < 0 ) {
845
783
return ret ;
846
784
}
847
785
848
- ret = gc2145_write_reg (& cfg -> i2c , reg ++ , y & 0xff );
786
+ ret = video_write_cci_reg (& cfg -> i2c , GC2145_REG16 ( reg + 0 ), y_offset );
849
787
if (ret < 0 ) {
850
788
return ret ;
851
789
}
852
790
853
- /* X/col offset */
854
- ret = gc2145_write_reg (& cfg -> i2c , reg ++ , x >> 8 );
791
+ ret = video_write_cci_reg (& cfg -> i2c , GC2145_REG16 (reg + 2 ), x_offset );
855
792
if (ret < 0 ) {
856
793
return ret ;
857
794
}
858
795
859
- ret = gc2145_write_reg (& cfg -> i2c , reg ++ , x & 0xff );
796
+ ret = video_write_cci_reg (& cfg -> i2c , GC2145_REG16 ( reg + 4 ), window_height );
860
797
if (ret < 0 ) {
861
798
return ret ;
862
799
}
863
800
864
- /* Window height */
865
- ret = gc2145_write_reg (& cfg -> i2c , reg ++ , h >> 8 );
866
- if (ret < 0 ) {
867
- return ret ;
868
- }
869
-
870
- ret = gc2145_write_reg (& cfg -> i2c , reg ++ , h & 0xff );
871
- if (ret < 0 ) {
872
- return ret ;
873
- }
874
-
875
- /* Window width */
876
- ret = gc2145_write_reg (& cfg -> i2c , reg ++ , w >> 8 );
877
- if (ret < 0 ) {
878
- return ret ;
879
- }
880
-
881
- ret = gc2145_write_reg (& cfg -> i2c , reg ++ , w & 0xff );
801
+ ret = video_write_cci_reg (& cfg -> i2c , GC2145_REG16 (reg + 6 ), window_width );
882
802
if (ret < 0 ) {
883
803
return ret ;
884
804
}
@@ -889,10 +809,9 @@ static int gc2145_set_window(const struct device *dev, uint16_t reg, uint16_t x,
889
809
static int gc2145_set_output_format (const struct device * dev , int output_format )
890
810
{
891
811
int ret ;
892
- uint8_t old_value ;
893
812
const struct gc2145_config * cfg = dev -> config ;
894
813
895
- ret = gc2145_write_reg (& cfg -> i2c , GC2145_REG_RESET , GC2145_SET_P0_REGS );
814
+ ret = video_write_cci_reg (& cfg -> i2c , GC2145_REG_RESET , GC2145_SET_P0_REGS );
896
815
if (ret < 0 ) {
897
816
return ret ;
898
817
}
@@ -907,13 +826,8 @@ static int gc2145_set_output_format(const struct device *dev, int output_format)
907
826
return - ENOTSUP ;
908
827
}
909
828
910
- ret = gc2145_read_reg (& cfg -> i2c , GC2145_REG_OUTPUT_FMT , & old_value );
911
- if (ret < 0 ) {
912
- return ret ;
913
- }
914
-
915
- ret = gc2145_write_reg (& cfg -> i2c , GC2145_REG_OUTPUT_FMT ,
916
- (old_value & ~GC2145_REG_OUTPUT_FMT_MASK ) | output_format );
829
+ ret = video_modify_cci_reg (& cfg -> i2c , GC2145_REG_OUTPUT_FMT , GC2145_REG_OUTPUT_FMT_MASK ,
830
+ output_format );
917
831
if (ret < 0 ) {
918
832
return ret ;
919
833
}
@@ -965,31 +879,32 @@ static int gc2145_set_resolution(const struct device *dev, uint32_t w, uint32_t
965
879
win_y = ((UXGA_VSIZE - win_h ) / 2 );
966
880
967
881
/* Set readout window first. */
968
- ret = gc2145_set_window (dev , GC2145_REG_BLANK_WINDOW_BASE , win_x , win_y , win_w + 16 ,
969
- win_h + 8 );
882
+ ret = gc2145_set_window (dev , ( uint8_t ) GC2145_REG_BLANK_WINDOW_BASE , win_x , win_y ,
883
+ win_w + 16 , win_h + 8 );
970
884
if (ret < 0 ) {
971
885
return ret ;
972
886
}
973
887
974
888
/* Set cropping window next. */
975
- ret = gc2145_set_window (dev , GC2145_REG_WINDOW_BASE , x , y , w , h );
889
+ ret = gc2145_set_window (dev , ( uint8_t ) GC2145_REG_WINDOW_BASE , x , y , w , h );
976
890
if (ret < 0 ) {
977
891
return ret ;
978
892
}
979
893
980
894
/* Enable crop */
981
- ret = gc2145_write_reg (& cfg -> i2c , GC2145_REG_CROP_ENABLE , GC2145_CROP_SET_ENABLE );
895
+ ret = video_write_cci_reg (& cfg -> i2c , GC2145_REG_CROP_ENABLE , GC2145_CROP_SET_ENABLE );
982
896
if (ret < 0 ) {
983
897
return ret ;
984
898
}
985
899
986
900
/* Set Sub-sampling ratio and mode */
987
- ret = gc2145_write_reg (& cfg -> i2c , GC2145_REG_SUBSAMPLE , ((r_ratio << 4 ) | c_ratio ));
901
+ ret = video_write_cci_reg (& cfg -> i2c , GC2145_REG_SUBSAMPLE , ((r_ratio << 4 ) | c_ratio ));
988
902
if (ret < 0 ) {
989
903
return ret ;
990
904
}
991
905
992
- ret = gc2145_write_reg (& cfg -> i2c , GC2145_REG_SUBSAMPLE_MODE , GC2145_SUBSAMPLE_MODE_SMOOTH );
906
+ ret = video_write_cci_reg (& cfg -> i2c , GC2145_REG_SUBSAMPLE_MODE ,
907
+ GC2145_SUBSAMPLE_MODE_SMOOTH );
993
908
if (ret < 0 ) {
994
909
return ret ;
995
910
}
@@ -1008,21 +923,13 @@ static uint8_t gc2145_check_connection(const struct device *dev)
1008
923
{
1009
924
int ret ;
1010
925
const struct gc2145_config * cfg = dev -> config ;
1011
- uint8_t reg_chip_id [2 ];
1012
- uint16_t chip_id ;
926
+ uint32_t chip_id ;
1013
927
1014
- ret = gc2145_read_reg (& cfg -> i2c , 0xf0 , & reg_chip_id [ 0 ] );
928
+ ret = video_read_cci_reg (& cfg -> i2c , GC2145_REG_CHIP_ID , & chip_id );
1015
929
if (ret < 0 ) {
1016
930
return ret ;
1017
931
}
1018
932
1019
- ret = gc2145_read_reg (& cfg -> i2c , 0xf1 , & reg_chip_id [1 ]);
1020
- if (ret < 0 ) {
1021
- return ret ;
1022
- }
1023
-
1024
- chip_id = reg_chip_id [0 ] << 8 | reg_chip_id [1 ];
1025
-
1026
933
if (chip_id != 0x2145 && chip_id != 0x2155 ) {
1027
934
LOG_WRN ("Unexpected GC2145 chip ID: 0x%04x" , chip_id );
1028
935
}
@@ -1089,8 +996,8 @@ static int gc2145_set_stream(const struct device *dev, bool enable)
1089
996
{
1090
997
const struct gc2145_config * cfg = dev -> config ;
1091
998
1092
- return enable ? gc2145_write_reg (& cfg -> i2c , 0xf2 , 0x0f )
1093
- : gc2145_write_reg (& cfg -> i2c , 0xf2 , 0x00 );
999
+ return enable ? video_write_cci_reg (& cfg -> i2c , GC2145_REG8 ( 0xf2 ) , 0x0f )
1000
+ : video_write_cci_reg (& cfg -> i2c , GC2145_REG8 ( 0xf2 ) , 0x00 );
1094
1001
}
1095
1002
1096
1003
static int gc2145_get_caps (const struct device * dev , enum video_endpoint_id ep ,
0 commit comments