/* Default register values */
struct imx219_reg_list reg_list;
+
+ /* Relative pixel clock rate factor for the mode. */
+ unsigned int rate_factor;
};
/*
.num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
.regs = mode_3280x2464_regs,
},
+ .rate_factor = 1,
},
{
/* 1080P 30fps cropped */
.num_of_regs = ARRAY_SIZE(mode_1920_1080_regs),
.regs = mode_1920_1080_regs,
},
+ .rate_factor = 1,
},
{
/* 2x2 binned 30fps mode */
.num_of_regs = ARRAY_SIZE(mode_1640_1232_regs),
.regs = mode_1640_1232_regs,
},
+ .rate_factor = 1,
},
{
/* 640x480 30fps mode */
.num_of_regs = ARRAY_SIZE(mode_640_480_regs),
.regs = mode_640_480_regs,
},
+ /*
+ * This mode uses a special 2x2 binning that doubles the
+ * the internal pixel clock rate.
+ */
+ .rate_factor = 2,
},
};
break;
case V4L2_CID_EXPOSURE:
ret = imx219_write_reg(imx219, IMX219_REG_EXPOSURE,
- IMX219_REG_VALUE_16BIT, ctrl->val);
+ IMX219_REG_VALUE_16BIT,
+ ctrl->val / imx219->mode->rate_factor);
break;
case V4L2_CID_DIGITAL_GAIN:
ret = imx219_write_reg(imx219, IMX219_REG_DIGITAL_GAIN,
case V4L2_CID_VBLANK:
ret = imx219_write_reg(imx219, IMX219_REG_VTS,
IMX219_REG_VALUE_16BIT,
- imx219->mode->height + ctrl->val);
+ (imx219->mode->height + ctrl->val) /
+ imx219->mode->rate_factor);
break;
case V4L2_CID_TEST_PATTERN_RED:
ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED,
struct imx219 *imx219 = to_imx219(sd);
const struct imx219_mode *mode;
struct v4l2_mbus_framefmt *framefmt;
- int exposure_max, exposure_def, hblank;
+ int exposure_max, exposure_def, hblank, pixel_rate;
unsigned int i;
if (fmt->pad >= NUM_PADS)
hblank = IMX219_PPL_DEFAULT - mode->width;
__v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank,
1, hblank);
+
+ /* Scale the pixel rate based on the mode specific factor */
+ pixel_rate =
+ IMX219_PIXEL_RATE * imx219->mode->rate_factor;
+ __v4l2_ctrl_modify_range(imx219->pixel_rate, pixel_rate,
+ pixel_rate, 1, pixel_rate);
}
} else {
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_ctrl_handler *ctrl_hdlr;
unsigned int height = imx219->mode->height;
struct v4l2_fwnode_device_properties props;
- int exposure_max, exposure_def, hblank;
+ int exposure_max, exposure_def, hblank, pixel_rate;
int i, ret;
ctrl_hdlr = &imx219->ctrl_handler;
ctrl_hdlr->lock = &imx219->mutex;
/* By default, PIXEL_RATE is read only */
+ pixel_rate = IMX219_PIXEL_RATE * imx219->mode->rate_factor;
imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
V4L2_CID_PIXEL_RATE,
- IMX219_PIXEL_RATE,
- IMX219_PIXEL_RATE, 1,
- IMX219_PIXEL_RATE);
+ pixel_rate, pixel_rate,
+ 1, pixel_rate);
imx219->link_freq =
v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops,