diff options
author | Álvaro Fernández Rojas <noltari@gmail.com> | 2022-05-16 23:40:32 +0200 |
---|---|---|
committer | Álvaro Fernández Rojas <noltari@gmail.com> | 2022-05-17 15:11:22 +0200 |
commit | 20ea6adbf199097c4f5f591ffee088340630dae4 (patch) | |
tree | d6719d95e136611a1c25bbf7789652d6d402779d /target/linux/bcm27xx/patches-5.15/950-0573-media-i2c-ov5647-Support-HFLIP-and-VFLIP.patch | |
parent | bca05bd072180dc38ef740b37ded9572a6db1981 (diff) | |
download | upstream-20ea6adbf199097c4f5f591ffee088340630dae4.tar.gz upstream-20ea6adbf199097c4f5f591ffee088340630dae4.tar.bz2 upstream-20ea6adbf199097c4f5f591ffee088340630dae4.zip |
bcm27xx: add support for linux v5.15
Build system: x86_64
Build-tested: bcm2708, bcm2709, bcm2710, bcm2711
Run-tested: bcm2708/RPiB+, bcm2709/RPi3B, bcm2710/RPi3B, bcm2711/RPi4B
Signed-off-by: Marty Jones <mj8263788@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx/patches-5.15/950-0573-media-i2c-ov5647-Support-HFLIP-and-VFLIP.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.15/950-0573-media-i2c-ov5647-Support-HFLIP-and-VFLIP.patch | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.15/950-0573-media-i2c-ov5647-Support-HFLIP-and-VFLIP.patch b/target/linux/bcm27xx/patches-5.15/950-0573-media-i2c-ov5647-Support-HFLIP-and-VFLIP.patch new file mode 100644 index 0000000000..6cf661b4dd --- /dev/null +++ b/target/linux/bcm27xx/patches-5.15/950-0573-media-i2c-ov5647-Support-HFLIP-and-VFLIP.patch @@ -0,0 +1,189 @@ +From 08cc1dcf1437d65dbb36dda27db29ec3a689101f Mon Sep 17 00:00:00 2001 +From: David Plowman <david.plowman@raspberrypi.com> +Date: Mon, 22 Nov 2021 13:10:39 +0000 +Subject: [PATCH] media: i2c: ov5647: Support HFLIP and VFLIP + +Add these missing V4L2 controls. Tested binned and full resolution +modes in all four orientations using Raspberry Pi running libcamera. + +Signed-off-by: David Plowman <david.plowman@raspberrypi.com> +--- + drivers/media/i2c/ov5647.c | 76 +++++++++++++++++++++++++++++++++++--- + 1 file changed, 70 insertions(+), 6 deletions(-) + +--- a/drivers/media/i2c/ov5647.c ++++ b/drivers/media/i2c/ov5647.c +@@ -54,6 +54,8 @@ + #define OV5647_REG_GAIN_LO 0x350b + #define OV5647_REG_VTS_HI 0x380e + #define OV5647_REG_VTS_LO 0x380f ++#define OV5647_REG_VFLIP 0x3820 ++#define OV5647_REG_HFLIP 0x3821 + #define OV5647_REG_FRAME_OFF_NUMBER 0x4202 + #define OV5647_REG_MIPI_CTRL00 0x4800 + #define OV5647_REG_MIPI_CTRL14 0x4814 +@@ -108,6 +110,8 @@ struct ov5647 { + struct v4l2_ctrl *hblank; + struct v4l2_ctrl *vblank; + struct v4l2_ctrl *exposure; ++ struct v4l2_ctrl *hflip; ++ struct v4l2_ctrl *vflip; + bool streaming; + }; + +@@ -136,7 +140,7 @@ static struct regval_list ov5647_2592x19 + {0x3036, 0x69}, + {0x303c, 0x11}, + {0x3106, 0xf5}, +- {0x3821, 0x06}, ++ {0x3821, 0x00}, + {0x3820, 0x00}, + {0x3827, 0xec}, + {0x370c, 0x03}, +@@ -225,7 +229,7 @@ static struct regval_list ov5647_1080p30 + {0x3036, 0x62}, + {0x303c, 0x11}, + {0x3106, 0xf5}, +- {0x3821, 0x06}, ++ {0x3821, 0x00}, + {0x3820, 0x00}, + {0x3827, 0xec}, + {0x370c, 0x03}, +@@ -389,7 +393,7 @@ static struct regval_list ov5647_2x2binn + {0x4800, 0x24}, + {0x3503, 0x03}, + {0x3820, 0x41}, +- {0x3821, 0x07}, ++ {0x3821, 0x01}, + {0x350a, 0x00}, + {0x350b, 0x10}, + {0x3500, 0x00}, +@@ -405,7 +409,7 @@ static struct regval_list ov5647_640x480 + {0x3035, 0x11}, + {0x3036, 0x46}, + {0x303c, 0x11}, +- {0x3821, 0x07}, ++ {0x3821, 0x01}, + {0x3820, 0x41}, + {0x370c, 0x03}, + {0x3612, 0x59}, +@@ -946,6 +950,25 @@ static const struct v4l2_subdev_video_op + .s_stream = ov5647_s_stream, + }; + ++/* This function returns the mbus code for the current settings of the ++ HFLIP and VFLIP controls. */ ++ ++static u32 ov5647_get_mbus_code(struct v4l2_subdev *sd) ++{ ++ struct ov5647 *sensor = to_sensor(sd); ++ /* The control values are only 0 or 1. */ ++ int index = sensor->hflip->val | (sensor->vflip->val << 1); ++ ++ static const u32 codes[4] = { ++ MEDIA_BUS_FMT_SGBRG10_1X10, ++ MEDIA_BUS_FMT_SBGGR10_1X10, ++ MEDIA_BUS_FMT_SRGGB10_1X10, ++ MEDIA_BUS_FMT_SGRBG10_1X10 ++ }; ++ ++ return codes[index]; ++} ++ + static int ov5647_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_mbus_code_enum *code) +@@ -953,7 +976,7 @@ static int ov5647_enum_mbus_code(struct + if (code->index > 0) + return -EINVAL; + +- code->code = MEDIA_BUS_FMT_SBGGR10_1X10; ++ code->code = ov5647_get_mbus_code(sd); + + return 0; + } +@@ -964,7 +987,7 @@ static int ov5647_enum_frame_size(struct + { + const struct v4l2_mbus_framefmt *fmt; + +- if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10 || ++ if (fse->code != ov5647_get_mbus_code(sd) || + fse->index >= ARRAY_SIZE(ov5647_modes)) + return -EINVAL; + +@@ -997,6 +1020,8 @@ static int ov5647_get_pad_fmt(struct v4l + } + + *fmt = *sensor_format; ++ /* The code we pass back must reflect the current h/vflips. */ ++ fmt->code = ov5647_get_mbus_code(sd); + mutex_unlock(&sensor->lock); + + return 0; +@@ -1044,6 +1069,8 @@ static int ov5647_set_pad_fmt(struct v4l + exposure_def); + } + *fmt = mode->format; ++ /* The code we pass back must reflect the current h/vflips. */ ++ fmt->code = ov5647_get_mbus_code(sd); + mutex_unlock(&sensor->lock); + + return 0; +@@ -1219,6 +1246,25 @@ static int ov5647_s_exposure(struct v4l2 + return ov5647_write(sd, OV5647_REG_EXP_LO, (val & 0xf) << 4); + } + ++static int ov5647_s_flip( struct v4l2_subdev *sd, u16 reg, u32 ctrl_val) ++{ ++ int ret; ++ u8 reg_val; ++ ++ /* Set or clear bit 1 and leave everything else alone. */ ++ ret = ov5647_read(sd, reg, ®_val); ++ if (ret == 0) { ++ if (ctrl_val) ++ reg_val |= 2; ++ else ++ reg_val &= ~2; ++ ++ ret = ov5647_write(sd, reg, reg_val); ++ } ++ ++ return ret; ++} ++ + static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl) + { + struct ov5647 *sensor = container_of(ctrl->handler, +@@ -1277,6 +1323,14 @@ static int ov5647_s_ctrl(struct v4l2_ctr + /* Read-only, but we adjust it based on mode. */ + break; + ++ case V4L2_CID_HFLIP: ++ /* There's an in-built hflip in the sensor, so account for that here. */ ++ ov5647_s_flip(sd, OV5647_REG_HFLIP, !ctrl->val); ++ break; ++ case V4L2_CID_VFLIP: ++ ov5647_s_flip(sd, OV5647_REG_VFLIP, ctrl->val); ++ break; ++ + default: + dev_info(&client->dev, + "Control (id:0x%x, val:0x%x) not supported\n", +@@ -1343,6 +1397,16 @@ static int ov5647_init_controls(struct o + sensor->mode->vts - + sensor->mode->format.height); + ++ sensor->hflip = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, ++ V4L2_CID_HFLIP, 0, 1, 1, 0); ++ if (sensor->hflip) ++ sensor->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; ++ ++ sensor->vflip = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, ++ V4L2_CID_VFLIP, 0, 1, 1, 0); ++ if (sensor->vflip) ++ sensor->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; ++ + v4l2_fwnode_device_parse(dev, &props); + + v4l2_ctrl_new_fwnode_properties(&sensor->ctrls, &ov5647_ctrl_ops, |