]> git.ipfire.org Git - thirdparty/openwrt.git/blob
e6d03342289f18a17d14a3d7d7656219b6798839
[thirdparty/openwrt.git] /
1 From 3e7d0d9be5353186136c661e551ad442bba50e45 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Thu, 21 Dec 2023 18:03:34 +0000
4 Subject: [PATCH 0814/1085] media: i2c: adv7180: Add support for
5 V4L2_CID_LINK_FREQ
6
7 For CSI2 receivers that need to know the link frequency,
8 add it as a control to the driver.
9 Interlaced modes are 216Mbp/s or 108MHz, whilst going through
10 the I2P to deinterlace gives 432Mb/s or 216MHz.
11
12 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
13 ---
14 drivers/media/i2c/adv7180.c | 32 +++++++++++++++++++++++++++++++-
15 1 file changed, 31 insertions(+), 1 deletion(-)
16
17 --- a/drivers/media/i2c/adv7180.c
18 +++ b/drivers/media/i2c/adv7180.c
19 @@ -188,6 +188,16 @@
20 /* Initial number of frames to skip to avoid possible garbage */
21 #define ADV7180_NUM_OF_SKIP_FRAMES 2
22
23 +enum adv7180_link_freq_idx {
24 + INTERLACED_IDX,
25 + I2P_IDX,
26 +};
27 +
28 +static const s64 adv7180_link_freqs[] = {
29 + [INTERLACED_IDX] = 108000000,
30 + [I2P_IDX] = 216000000,
31 +};
32 +
33 static int dbg_input;
34 module_param(dbg_input, int, 0644);
35 MODULE_PARM_DESC(dbg_input, "Input number (0-31)");
36 @@ -227,6 +237,7 @@ struct adv7180_state {
37 const struct adv7180_chip_info *chip_info;
38 enum v4l2_field field;
39 bool force_bt656_4;
40 + struct v4l2_ctrl *link_freq;
41 };
42 #define to_adv7180_sd(_ctrl) (&container_of(_ctrl->handler, \
43 struct adv7180_state, \
44 @@ -620,6 +631,9 @@ static int adv7180_s_ctrl(struct v4l2_ct
45
46 if (ret)
47 return ret;
48 + if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
49 + goto unlock;
50 +
51 val = ctrl->val;
52 switch (ctrl->id) {
53 case V4L2_CID_BRIGHTNESS:
54 @@ -661,6 +675,7 @@ static int adv7180_s_ctrl(struct v4l2_ct
55 ret = -EINVAL;
56 }
57
58 +unlock:
59 mutex_unlock(&state->mutex);
60 return ret;
61 }
62 @@ -681,7 +696,7 @@ static const struct v4l2_ctrl_config adv
63
64 static int adv7180_init_controls(struct adv7180_state *state)
65 {
66 - v4l2_ctrl_handler_init(&state->ctrl_hdl, 4);
67 + v4l2_ctrl_handler_init(&state->ctrl_hdl, 5);
68
69 v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
70 V4L2_CID_BRIGHTNESS, ADV7180_BRI_MIN,
71 @@ -703,6 +718,17 @@ static int adv7180_init_controls(struct
72 0, ARRAY_SIZE(test_pattern_menu) - 1,
73 test_pattern_menu);
74
75 + if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
76 + state->link_freq =
77 + v4l2_ctrl_new_int_menu(&state->ctrl_hdl,
78 + &adv7180_ctrl_ops,
79 + V4L2_CID_LINK_FREQ,
80 + ARRAY_SIZE(adv7180_link_freqs) - 1,
81 + 0, adv7180_link_freqs);
82 + if (state->link_freq)
83 + state->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
84 + }
85 +
86 state->sd.ctrl_handler = &state->ctrl_hdl;
87 if (state->ctrl_hdl.error) {
88 int err = state->ctrl_hdl.error;
89 @@ -835,6 +861,10 @@ static int adv7180_set_pad_format(struct
90 adv7180_set_power(state, false);
91 adv7180_set_field_mode(state);
92 adv7180_set_power(state, true);
93 + if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2)
94 + __v4l2_ctrl_s_ctrl(state->link_freq,
95 + (state->field == V4L2_FIELD_NONE) ?
96 + I2P_IDX : INTERLACED_IDX);
97 }
98 } else {
99 framefmt = v4l2_subdev_get_try_format(sd, sd_state, 0);