From bebfaf8bb487a66469906a15ca3319d72ed8f5f1 Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Tue, 7 Apr 2026 11:21:11 +0800 Subject: [PATCH] video/gc0308: implement V4L2 horizontal flip control Implement get_supported_value, get_value and set_value callbacks for IMGSENSOR_ID_HFLIP_VIDEO / IMGSENSOR_ID_HFLIP_STILL. This allows applications to mirror the camera preview horizontally at runtime via VIDIOC_S_CTRL + V4L2_CID_HFLIP. The hardware mirror is controlled by register 0x14 (CISCTL_MODE1) bit[0], which reverses the pixel readout order with zero CPU cost. Signed-off-by: wangjianyu3 --- drivers/video/gc0308.c | 56 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/drivers/video/gc0308.c b/drivers/video/gc0308.c index 768b21e46ca..5c6533f0962 100644 --- a/drivers/video/gc0308.c +++ b/drivers/video/gc0308.c @@ -134,9 +134,9 @@ #define GC0308_NATIVE_WIDTH 640 #define GC0308_NATIVE_HEIGHT 480 -/* Mirror/flip */ +/* Mirror/flip: register 0x14 (CISCTL_MODE1) bit[0] = horizontal mirror */ -#define GC0308_REG_CISCTL_MODE1_MIRROR 0x14 +#define GC0308_REG_CISCTL_MODE1_HMIRROR_BIT (1 << 0) /**************************************************************************** * Private Types @@ -839,7 +839,20 @@ static int gc0308_get_supported_value(struct imgsensor_s *sensor, uint32_t id, imgsensor_supported_value_t *value) { - return -ENOTTY; + switch (id) + { + case IMGSENSOR_ID_HFLIP_VIDEO: + case IMGSENSOR_ID_HFLIP_STILL: + value->type = IMGSENSOR_CTRL_TYPE_BOOLEAN; + value->u.range.minimum = 0; + value->u.range.maximum = 1; + value->u.range.step = 1; + value->u.range.default_value = 0; + return OK; + + default: + return -ENOTTY; + } } /**************************************************************************** @@ -850,7 +863,27 @@ static int gc0308_get_value(struct imgsensor_s *sensor, uint32_t id, uint32_t size, imgsensor_value_t *value) { - return -ENOTTY; + struct gc0308_dev_s *priv = (struct gc0308_dev_s *)sensor; + uint8_t regval; + int ret; + + switch (id) + { + case IMGSENSOR_ID_HFLIP_VIDEO: + case IMGSENSOR_ID_HFLIP_STILL: + ret = gc0308_getreg(priv->i2c, GC0308_REG_CISCTL_MODE1, ®val); + if (ret < 0) + { + return ret; + } + + value->value32 = + (regval & GC0308_REG_CISCTL_MODE1_HMIRROR_BIT) ? 1 : 0; + return OK; + + default: + return -ENOTTY; + } } /**************************************************************************** @@ -861,7 +894,20 @@ static int gc0308_set_value(struct imgsensor_s *sensor, uint32_t id, uint32_t size, imgsensor_value_t value) { - return -ENOTTY; + struct gc0308_dev_s *priv = (struct gc0308_dev_s *)sensor; + + switch (id) + { + case IMGSENSOR_ID_HFLIP_VIDEO: + case IMGSENSOR_ID_HFLIP_STILL: + return gc0308_modreg(priv->i2c, GC0308_REG_CISCTL_MODE1, + GC0308_REG_CISCTL_MODE1_HMIRROR_BIT, + value.value32 ? + GC0308_REG_CISCTL_MODE1_HMIRROR_BIT : 0); + + default: + return -ENOTTY; + } } /****************************************************************************