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