media: ov2680: Add link-freq and pixel-rate controls
authorHans de Goede <hdegoede@redhat.com>
Thu, 3 Aug 2023 09:33:43 +0000 (11:33 +0200)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Mon, 14 Aug 2023 18:27:57 +0000 (20:27 +0200)
Add read-only link-freq and pixel-rate controls. This is necessary for
the sensor to work with the ipu3-cio2 driver and for libcamera.

Acked-by: Rui Miguel Silva <rmfrfs@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/i2c/ov2680.c

index 1f59013e440c0d876bc13be46cf70d74ba3bbb07..83ec034b53075aec2cc63092d797e6bdbd324770 100644 (file)
 #define OV2680_MIN_CROP_WIDTH                  2
 #define OV2680_MIN_CROP_HEIGHT                 2
 
+/* Fixed pre-div of 1/2 */
+#define OV2680_PLL_PREDIV0                     2
+
+/* Pre-div configurable through reg 0x3080, left at its default of 0x02 : 1/2 */
+#define OV2680_PLL_PREDIV                      2
+
 /* 66MHz pixel clock: 66MHz / 1704 * 1294 = 30fps */
 #define OV2680_PIXELS_PER_LINE                 1704
 #define OV2680_LINES_PER_FRAME                 1294
@@ -121,6 +127,8 @@ struct ov2680_ctrls {
        struct v4l2_ctrl *hflip;
        struct v4l2_ctrl *vflip;
        struct v4l2_ctrl *test_pattern;
+       struct v4l2_ctrl *link_freq;
+       struct v4l2_ctrl *pixel_rate;
 };
 
 struct ov2680_mode {
@@ -147,6 +155,8 @@ struct ov2680_dev {
        struct clk                      *xvclk;
        u32                             xvclk_freq;
        u8                              pll_mult;
+       s64                             link_freq[1];
+       u64                             pixel_rate;
        struct regulator_bulk_data      supplies[OV2680_NUM_SUPPLIES];
 
        struct gpio_desc                *pwdn_gpio;
@@ -931,6 +941,12 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor)
        ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN,
                                        0, 1023, 1, 250);
 
+       ctrls->link_freq = v4l2_ctrl_new_int_menu(hdl, NULL, V4L2_CID_LINK_FREQ,
+                                                 0, 0, sensor->link_freq);
+       ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, NULL, V4L2_CID_PIXEL_RATE,
+                                             0, sensor->pixel_rate,
+                                             1, sensor->pixel_rate);
+
        if (hdl->error) {
                ret = hdl->error;
                goto cleanup_entity;
@@ -938,6 +954,7 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor)
 
        ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
        ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+       ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 
        sensor->sd.ctrl_handler = hdl;
 
@@ -1067,6 +1084,13 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
 
        sensor->pll_mult = ov2680_pll_multipliers[i];
 
+       sensor->link_freq[0] = sensor->xvclk_freq / OV2680_PLL_PREDIV0 /
+                              OV2680_PLL_PREDIV * sensor->pll_mult;
+
+       /* CSI-2 is double data rate, bus-format is 10 bpp */
+       sensor->pixel_rate = sensor->link_freq[0] * 2;
+       do_div(sensor->pixel_rate, 10);
+
        return 0;
 }