Add suport for standard integer menu V4L2_CID_LINK_FREQ control.
The CSI2 link frequency value is specific for each sensor mode so the
sensor mode structure is extended to add this. The control is made
read-only and its value is updated when the sensor mode is changed -
on set_format.

Signed-off-by: Todor Tomov <todor.to...@linaro.org>
---
 drivers/media/i2c/ov5645.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c
index 4583f66..85622e4 100644
--- a/drivers/media/i2c/ov5645.c
+++ b/drivers/media/i2c/ov5645.c
@@ -81,6 +81,7 @@ struct ov5645_mode_info {
        const struct reg_value *data;
        u32 data_size;
        u32 pixel_clock;
+       u32 link_freq;
 };
 
 struct ov5645 {
@@ -101,6 +102,7 @@ struct ov5645 {
 
        struct v4l2_ctrl_handler ctrls;
        struct v4l2_ctrl *pixel_clock;
+       struct v4l2_ctrl *link_freq;
 
        /* Cached register values */
        u8 aec_pk_manual;
@@ -507,27 +509,35 @@ static inline struct ov5645 *to_ov5645(struct v4l2_subdev 
*sd)
        { 0x4202, 0x00 }
 };
 
+static const s64 link_freq[] = {
+       222880000,
+       334320000
+};
+
 static const struct ov5645_mode_info ov5645_mode_info_data[] = {
        {
                .width = 1280,
                .height = 960,
                .data = ov5645_setting_sxga,
                .data_size = ARRAY_SIZE(ov5645_setting_sxga),
-               .pixel_clock = 111440000
+               .pixel_clock = 111440000,
+               .link_freq = 0 /* an index in link_freq[] */
        },
        {
                .width = 1920,
                .height = 1080,
                .data = ov5645_setting_1080p,
                .data_size = ARRAY_SIZE(ov5645_setting_1080p),
-               .pixel_clock = 167160000
+               .pixel_clock = 167160000,
+               .link_freq = 1 /* an index in link_freq[] */
        },
        {
                .width = 2592,
                .height = 1944,
                .data = ov5645_setting_full,
                .data_size = ARRAY_SIZE(ov5645_setting_full),
-               .pixel_clock = 167160000
+               .pixel_clock = 167160000,
+               .link_freq = 1 /* an index in link_freq[] */
        },
 };
 
@@ -990,6 +1000,11 @@ static int ov5645_set_format(struct v4l2_subdev *sd,
                if (ret < 0)
                        return ret;
 
+               ret = v4l2_ctrl_s_ctrl(ov5645->link_freq,
+                                      new_mode->link_freq);
+               if (ret < 0)
+                       return ret;
+
                ov5645->current_mode = new_mode;
        }
 
@@ -1209,7 +1224,7 @@ static int ov5645_probe(struct i2c_client *client,
 
        mutex_init(&ov5645->power_lock);
 
-       v4l2_ctrl_handler_init(&ov5645->ctrls, 8);
+       v4l2_ctrl_handler_init(&ov5645->ctrls, 9);
        v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops,
                          V4L2_CID_SATURATION, -4, 4, 1, 0);
        v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops,
@@ -1231,6 +1246,13 @@ static int ov5645_probe(struct i2c_client *client,
                                                &ov5645_ctrl_ops,
                                                V4L2_CID_PIXEL_RATE,
                                                1, INT_MAX, 1, 1);
+       ov5645->link_freq = v4l2_ctrl_new_int_menu(&ov5645->ctrls,
+                                                  &ov5645_ctrl_ops,
+                                                  V4L2_CID_LINK_FREQ,
+                                                  ARRAY_SIZE(link_freq) - 1,
+                                                  0, link_freq);
+       if(ov5645->link_freq)
+               ov5645->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 
        ov5645->sd.ctrl_handler = &ov5645->ctrls;
 
-- 
1.9.1

Reply via email to