Skip to content

Commit 138e086

Browse files
committed
gc0308: read current setting values on sensor initialization
1 parent 8de4b62 commit 138e086

File tree

1 file changed

+124
-15
lines changed

1 file changed

+124
-15
lines changed

sensors/gc0308.c

Lines changed: 124 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -617,31 +617,140 @@ static int set_reg(sensor_t *sensor, int reg, int mask, int value)
617617

618618
static int init_status(sensor_t *sensor)
619619
{
620-
write_reg(sensor->slv_addr, 0xfe, 0x00);
621-
sensor->status.brightness = 0;
622-
sensor->status.contrast = 50;
623-
sensor->status.saturation = 0;
624-
sensor->status.sharpness = 0;
620+
int ret;
621+
ret = write_reg(sensor->slv_addr, 0xfe, 0x00);
622+
623+
// Read brightness from LSC_RED_B2 register (0xd6)
624+
// Default is 0x48, map back to level: (reg_val - 0x48) / 0x10
625+
ret = read_reg(sensor->slv_addr, LSC_RED_B2);
626+
if (ret >= 0) {
627+
int brightness_level = (ret - 0x48) / 0x10;
628+
sensor->status.brightness = (brightness_level < -2) ? -2 : (brightness_level > 2) ? 2 : brightness_level;
629+
} else {
630+
sensor->status.brightness = 0;
631+
}
632+
633+
// Read contrast from CONTRAST register (0xb3)
634+
// Default is 0x40, map back to level: (reg_val - 0x40) / 0x10
635+
ret = read_reg(sensor->slv_addr, CONTRAST);
636+
if (ret >= 0) {
637+
int contrast_level = (ret - 0x40) / 0x10;
638+
sensor->status.contrast = (contrast_level < -2) ? -2 : (contrast_level > 2) ? 2 : contrast_level;
639+
} else {
640+
sensor->status.contrast = 0;
641+
}
642+
643+
// Read saturation from SATURATION_CB1 register (0x54)
644+
// Default is 0x40, map back to level: (reg_val - 0x40) / 0x10
645+
ret = read_reg(sensor->slv_addr, SATURATION_CB1);
646+
if (ret >= 0) {
647+
int saturation_level = (ret - 0x40) / 0x10;
648+
sensor->status.saturation = (saturation_level < -2) ? -2 : (saturation_level > 2) ? 2 : saturation_level;
649+
} else {
650+
sensor->status.saturation = 0;
651+
}
652+
653+
// Read sharpness from EDGE_DEC_SA1 register (0x8b)
654+
// Default is 0x20, map back to level: (reg_val - 0x20) / 0x08
655+
ret = read_reg(sensor->slv_addr, EDGE_DEC_SA1);
656+
if (ret >= 0) {
657+
int sharpness_level = (ret - 0x20) / 0x08;
658+
sensor->status.sharpness = (sharpness_level < -2) ? -2 : (sharpness_level > 2) ? 2 : sharpness_level;
659+
} else {
660+
sensor->status.sharpness = 0;
661+
}
662+
663+
// Denoise not supported by GC0308
625664
sensor->status.denoise = 0;
626-
sensor->status.ae_level = 0;
665+
666+
// Read AE level from AEC_TARGET_Y register (Page 1, 0xf7)
667+
ret = write_reg(sensor->slv_addr, 0xfe, 0x01);
668+
ret = read_reg(sensor->slv_addr, AEC_TARGET_Y);
669+
ret = write_reg(sensor->slv_addr, 0xfe, 0x00);
670+
if (ret >= 0) {
671+
int ae_level = (ret - 0x19) / 0x08;
672+
sensor->status.ae_level = (ae_level < -2) ? -2 : (ae_level > 2) ? 2 : ae_level;
673+
} else {
674+
sensor->status.ae_level = 0;
675+
}
676+
677+
// Gainceiling not supported by GC0308
627678
sensor->status.gainceiling = 0;
628-
sensor->status.awb = 0;
679+
680+
// Read AWB, AGC, AEC status from AEC_MODE1 register (0xd2)
681+
sensor->status.awb = check_reg_mask(sensor->slv_addr, AEC_MODE1, AWB_ENABLE);
682+
sensor->status.agc = check_reg_mask(sensor->slv_addr, AEC_MODE1, AGC_ENABLE);
683+
sensor->status.aec = check_reg_mask(sensor->slv_addr, AEC_MODE1, AEC_ENABLE);
684+
685+
// DCW not supported by GC0308
629686
sensor->status.dcw = 0;
630-
sensor->status.agc = 0;
631-
sensor->status.aec = 0;
632-
sensor->status.hmirror = check_reg_mask(sensor->slv_addr, 0x14, 0x01);
633-
sensor->status.vflip = check_reg_mask(sensor->slv_addr, 0x14, 0x02);
634-
sensor->status.colorbar = 0;
687+
688+
// Read hmirror and vflip from CISCTL_MODE1 register (0x14)
689+
sensor->status.hmirror = check_reg_mask(sensor->slv_addr, CISCTL_MODE1, HMIRROR_MASK);
690+
sensor->status.vflip = check_reg_mask(sensor->slv_addr, CISCTL_MODE1, VFLIP_MASK);
691+
692+
// Read colorbar status from OUT_CTRL register (0x2e)
693+
sensor->status.colorbar = check_reg_mask(sensor->slv_addr, OUT_CTRL, 0x01);
694+
695+
// BPC, WPC not specifically tracked by GC0308 driver
635696
sensor->status.bpc = 0;
636697
sensor->status.wpc = 0;
698+
699+
// Raw GMA, LENC not supported by GC0308
637700
sensor->status.raw_gma = 0;
638701
sensor->status.lenc = 0;
702+
703+
// Quality not supported by GC0308
639704
sensor->status.quality = 0;
640-
sensor->status.special_effect = 0;
641-
sensor->status.wb_mode = 0;
705+
706+
// Read special effect from SPECIAL_EFFECT register (0x23)
707+
ret = read_reg(sensor->slv_addr, SPECIAL_EFFECT);
708+
if (ret >= 0) {
709+
// Map hardware register value to effect enum
710+
// Bit[1:0] of SPECIAL_EFFECT register holds the effect mode
711+
uint8_t effect_bits = ret & 0x03;
712+
if (effect_bits == EFFECT_NORMAL) {
713+
sensor->status.special_effect = 0; // Normal
714+
} else if (effect_bits == EFFECT_NEGATIVE) {
715+
sensor->status.special_effect = 1; // Negative
716+
} else if (effect_bits == EFFECT_GRAYSCALE) {
717+
// Could be Grayscale (2) or tint effects (3-6) - requires checking FIXED_CB/CR
718+
// For simplicity, default to Grayscale when in EFFECT_GRAYSCALE mode
719+
sensor->status.special_effect = 2; // Grayscale/B&W
720+
} else {
721+
sensor->status.special_effect = 0; // Default to Normal
722+
}
723+
} else {
724+
sensor->status.special_effect = 0;
725+
}
726+
727+
// Read white balance mode from AWB registers
728+
// This is simplified - full WB mode detection would need to check multiple registers
729+
if (sensor->status.awb) {
730+
sensor->status.wb_mode = 0; // Auto
731+
} else {
732+
// Check if specific preset is active (simplified detection)
733+
sensor->status.wb_mode = 0; // Default to Auto
734+
}
735+
736+
// AWB gain not specifically tracked
642737
sensor->status.awb_gain = 0;
643-
sensor->status.agc_gain = 0;
738+
739+
// Read AGC gain from GLOBAL_GAIN register (0x50)
740+
// Hardware range is 0-63 (6-bit), map to 0-30 for API compatibility
741+
ret = read_reg(sensor->slv_addr, GLOBAL_GAIN);
742+
if (ret >= 0) {
743+
// Reverse map from hardware (0-63) to API (0-30)
744+
sensor->status.agc_gain = (ret * 30) / 63;
745+
if (sensor->status.agc_gain > 30) sensor->status.agc_gain = 30;
746+
} else {
747+
sensor->status.agc_gain = 0;
748+
}
749+
750+
// AEC value not specifically tracked by GC0308
644751
sensor->status.aec_value = 0;
752+
753+
// AEC2 not supported by GC0308
645754
sensor->status.aec2 = 0;
646755

647756
print_regs(sensor->slv_addr);

0 commit comments

Comments
 (0)