Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IMX500: Add support for rotation and image flip #6584

Open
wants to merge 2 commits into
base: rpi-6.6.y
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions drivers/media/i2c/imx500.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,12 @@
#define IMX500_COLOUR_BALANCE_STEP 0x0001
#define IMX500_COLOUR_BALANCE_DEFAULT 0x0100

/* Rotate angle */
#define IMX500_REG_ADDR_ROTATION CCI_REG8(0xD680)

/* Flip vertical/horizontal */
#define IMX500_REG_ADDR_IMG_ORIENTATION CCI_REG8(0x0101)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already defined and used as IMX500_REG_ORIENTATION


/* Embedded sizes */
#define IMX500_MAX_EMBEDDED_SIZE \
(2 * ((((IMX500_PIXEL_ARRAY_WIDTH * 10) >> 3) + 15) & ~15))
Expand All @@ -235,6 +241,8 @@ enum pad_types { IMAGE_PAD, METADATA_PAD, NUM_PADS };

#define V4L2_CID_USER_IMX500_INFERENCE_WINDOW (V4L2_CID_USER_IMX500_BASE + 0)
#define V4L2_CID_USER_IMX500_NETWORK_FW_FD (V4L2_CID_USER_IMX500_BASE + 1)
#define V4L2_CID_USER_IMX500_ROTATION (V4L2_CID_USER_IMX500_BASE + 2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need to be a custom control rather than V4L2_CID_ROTATE? (Documented in https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/control.html)

How does this affect the resolution of the output image? Normally you'd rotate the 4056x3040 image to give a 3040x4056 output, so the output format needs to change.

#define V4L2_CID_USER_IMX500_IMG_FLIP (V4L2_CID_USER_IMX500_BASE + 3)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again why a custom control? V4L2_CID_HFLIP and V4L2_CIF_VFLIP exist and are already implemented.


#define ONE_MIB (1024 * 1024)

Expand Down Expand Up @@ -1974,6 +1982,12 @@ static int imx500_set_ctrl(struct v4l2_ctrl *ctrl)
sizeof(struct v4l2_rect));
ret = imx500_set_inference_window(imx500);
break;
case V4L2_CID_USER_IMX500_ROTATION:
ret = cci_write(imx500->regmap, IMX500_REG_ADDR_ROTATION, ctrl->val, NULL);
break;
case V4L2_CID_USER_IMX500_IMG_FLIP:
ret = cci_write(imx500->regmap, IMX500_REG_ADDR_IMG_ORIENTATION, ctrl->val, NULL);
break;
default:
dev_info(&client->dev,
"ctrl(id:0x%x,val:0x%x) is not handled\n", ctrl->id,
Expand Down Expand Up @@ -2828,6 +2842,32 @@ static const struct v4l2_ctrl_config network_fw_fd = {
.def = -1,
};

/* Custom control for rotation angle */
static const struct v4l2_ctrl_config rotation_angle = {
.name = "IMX500 Rotation Angle",
.id = V4L2_CID_USER_IMX500_ROTATION,
.ops = &imx500_ctrl_ops,
.type = V4L2_CTRL_TYPE_INTEGER,
.flags = V4L2_CTRL_FLAG_EXECUTE_ON_WRITE,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really need to rewrite the register even if setting it to the same value?

.min = 0,
.max = 3,
.step = 1,
.def = 0,
};

/* Custom control for image flip */
static const struct v4l2_ctrl_config img_flip = {
.name = "IMX500 Image Flip",
.id = V4L2_CID_USER_IMX500_IMG_FLIP,
.ops = &imx500_ctrl_ops,
.type = V4L2_CTRL_TYPE_INTEGER,
.flags = V4L2_CTRL_FLAG_EXECUTE_ON_WRITE,
.min = 0,
.max = 3,
.step = 1,
.def = 0,
};

/* Initialize control handlers */
static int imx500_init_controls(struct imx500 *imx500)
{
Expand Down Expand Up @@ -2891,6 +2931,8 @@ static int imx500_init_controls(struct imx500 *imx500)
v4l2_ctrl_new_custom(ctrl_hdlr, &inf_window_ctrl, NULL);
imx500->network_fw_ctrl =
v4l2_ctrl_new_custom(ctrl_hdlr, &network_fw_fd, NULL);
v4l2_ctrl_new_custom(ctrl_hdlr, &rotation_angle, NULL);
v4l2_ctrl_new_custom(ctrl_hdlr, &img_flip, NULL);

if (ctrl_hdlr->error) {
ret = ctrl_hdlr->error;
Expand Down
Loading