mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-27 01:11:14 +00:00
235 lines
6.9 KiB
Diff
235 lines
6.9 KiB
Diff
|
From 65e773354de288401a6c498d006b47b7f87e0936 Mon Sep 17 00:00:00 2001
|
||
|
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
||
|
Date: Thu, 17 Feb 2022 17:00:27 +0000
|
||
|
Subject: [PATCH] media: i2c: ov7251: Separate modes from frame
|
||
|
intervals
|
||
|
|
||
|
The modes and frame intervals are independent, therefore
|
||
|
separate them into 2 structures.
|
||
|
|
||
|
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
||
|
---
|
||
|
drivers/media/i2c/ov7251.c | 85 ++++++++++++++++++--------------------
|
||
|
1 file changed, 41 insertions(+), 44 deletions(-)
|
||
|
|
||
|
--- a/drivers/media/i2c/ov7251.c
|
||
|
+++ b/drivers/media/i2c/ov7251.c
|
||
|
@@ -79,14 +79,17 @@ struct reg_value {
|
||
|
u8 val;
|
||
|
};
|
||
|
|
||
|
+struct ov7251_frame_ival_info {
|
||
|
+ u16 vts;
|
||
|
+ struct v4l2_fract timeperframe;
|
||
|
+};
|
||
|
+
|
||
|
struct ov7251_mode_info {
|
||
|
u32 width;
|
||
|
u32 height;
|
||
|
const struct reg_value *data;
|
||
|
u32 data_size;
|
||
|
u16 exposure_def;
|
||
|
- u16 vts;
|
||
|
- struct v4l2_fract timeperframe;
|
||
|
};
|
||
|
|
||
|
struct ov7251_pll1_config {
|
||
|
@@ -128,6 +131,7 @@ struct ov7251 {
|
||
|
struct regulator *analog_regulator;
|
||
|
|
||
|
const struct ov7251_mode_info *current_mode;
|
||
|
+ const struct ov7251_frame_ival_info *current_ival;
|
||
|
|
||
|
struct v4l2_ctrl_handler ctrls;
|
||
|
struct v4l2_ctrl *exposure;
|
||
|
@@ -343,13 +347,8 @@ static const s64 link_freq[] = {
|
||
|
240000000,
|
||
|
};
|
||
|
|
||
|
-static const struct ov7251_mode_info ov7251_mode_info_data[] = {
|
||
|
+static const struct ov7251_frame_ival_info ov7251_frame_ival_info_data[] = {
|
||
|
{
|
||
|
- .width = 640,
|
||
|
- .height = 480,
|
||
|
- .data = ov7251_setting_vga,
|
||
|
- .data_size = ARRAY_SIZE(ov7251_setting_vga),
|
||
|
- .exposure_def = 504,
|
||
|
.vts = 0x6bc,
|
||
|
.timeperframe = {
|
||
|
.numerator = 100,
|
||
|
@@ -357,11 +356,6 @@ static const struct ov7251_mode_info ov7
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
- .width = 640,
|
||
|
- .height = 480,
|
||
|
- .data = ov7251_setting_vga,
|
||
|
- .data_size = ARRAY_SIZE(ov7251_setting_vga),
|
||
|
- .exposure_def = 504,
|
||
|
.vts = 0x35c,
|
||
|
.timeperframe = {
|
||
|
.numerator = 100,
|
||
|
@@ -369,11 +363,6 @@ static const struct ov7251_mode_info ov7
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
- .width = 640,
|
||
|
- .height = 480,
|
||
|
- .data = ov7251_setting_vga,
|
||
|
- .data_size = ARRAY_SIZE(ov7251_setting_vga),
|
||
|
- .exposure_def = 504,
|
||
|
.vts = 0x23c,
|
||
|
.timeperframe = {
|
||
|
.numerator = 100,
|
||
|
@@ -382,6 +371,16 @@ static const struct ov7251_mode_info ov7
|
||
|
},
|
||
|
};
|
||
|
|
||
|
+static const struct ov7251_mode_info ov7251_mode_info_data[] = {
|
||
|
+ {
|
||
|
+ .width = 640,
|
||
|
+ .height = 480,
|
||
|
+ .data = ov7251_setting_vga,
|
||
|
+ .data_size = ARRAY_SIZE(ov7251_setting_vga),
|
||
|
+ .exposure_def = 504,
|
||
|
+ },
|
||
|
+};
|
||
|
+
|
||
|
static int ov7251_regulators_enable(struct ov7251 *ov7251)
|
||
|
{
|
||
|
int ret;
|
||
|
@@ -789,13 +788,13 @@ static int ov7251_enum_frame_ival(struct
|
||
|
unsigned int index = fie->index;
|
||
|
unsigned int i;
|
||
|
|
||
|
- for (i = 0; i < ARRAY_SIZE(ov7251_mode_info_data); i++) {
|
||
|
- if (fie->width != ov7251_mode_info_data[i].width ||
|
||
|
- fie->height != ov7251_mode_info_data[i].height)
|
||
|
+ for (i = 0; i < ARRAY_SIZE(ov7251_frame_ival_info_data); i++) {
|
||
|
+ if (fie->width != ov7251_mode_info_data[0].width ||
|
||
|
+ fie->height != ov7251_mode_info_data[0].height)
|
||
|
continue;
|
||
|
|
||
|
if (index-- == 0) {
|
||
|
- fie->interval = ov7251_mode_info_data[i].timeperframe;
|
||
|
+ fie->interval = ov7251_frame_ival_info_data[i].timeperframe;
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
@@ -854,23 +853,18 @@ static inline u32 avg_fps(const struct v
|
||
|
return (t->denominator + (t->numerator >> 1)) / t->numerator;
|
||
|
}
|
||
|
|
||
|
-static const struct ov7251_mode_info *
|
||
|
-ov7251_find_mode_by_ival(struct ov7251 *ov7251, struct v4l2_fract *timeperframe)
|
||
|
+static const struct ov7251_frame_ival_info *
|
||
|
+ov7251_find_frame_ival_by_ival(struct ov7251 *ov7251, struct v4l2_fract *timeperframe)
|
||
|
{
|
||
|
- const struct ov7251_mode_info *mode = ov7251->current_mode;
|
||
|
unsigned int fps_req = avg_fps(timeperframe);
|
||
|
unsigned int max_dist_match = (unsigned int) -1;
|
||
|
unsigned int i, n = 0;
|
||
|
|
||
|
- for (i = 0; i < ARRAY_SIZE(ov7251_mode_info_data); i++) {
|
||
|
+ for (i = 0; i < ARRAY_SIZE(ov7251_frame_ival_info_data); i++) {
|
||
|
unsigned int dist;
|
||
|
unsigned int fps_tmp;
|
||
|
|
||
|
- if (mode->width != ov7251_mode_info_data[i].width ||
|
||
|
- mode->height != ov7251_mode_info_data[i].height)
|
||
|
- continue;
|
||
|
-
|
||
|
- fps_tmp = avg_fps(&ov7251_mode_info_data[i].timeperframe);
|
||
|
+ fps_tmp = avg_fps(&ov7251_frame_ival_info_data[i].timeperframe);
|
||
|
|
||
|
dist = abs(fps_req - fps_tmp);
|
||
|
|
||
|
@@ -880,7 +874,7 @@ ov7251_find_mode_by_ival(struct ov7251 *
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- return &ov7251_mode_info_data[n];
|
||
|
+ return &ov7251_frame_ival_info_data[n];
|
||
|
}
|
||
|
|
||
|
static int ov7251_set_format(struct v4l2_subdev *sd,
|
||
|
@@ -914,7 +908,8 @@ static int ov7251_set_format(struct v4l2
|
||
|
__v4l2_ctrl_s_ctrl(ov7251->hblank, h_blank);
|
||
|
|
||
|
ret = __v4l2_ctrl_modify_range(ov7251->exposure, 1,
|
||
|
- new_mode->vts - OV7251_EXPOSURE_OFFSET,
|
||
|
+ ov7251->current_ival->vts -
|
||
|
+ OV7251_EXPOSURE_OFFSET,
|
||
|
1, new_mode->exposure_def);
|
||
|
if (ret < 0)
|
||
|
goto exit;
|
||
|
@@ -1036,11 +1031,11 @@ static int ov7251_s_stream(struct v4l2_s
|
||
|
goto err_power_down;
|
||
|
}
|
||
|
ret = ov7251_write_reg(ov7251, OV7251_VTS_HIGH,
|
||
|
- ov7251->current_mode->vts >> 8);
|
||
|
+ ov7251->current_ival->vts >> 8);
|
||
|
if (ret)
|
||
|
goto err_power_down;
|
||
|
ret = ov7251_write_reg(ov7251, OV7251_VTS_LOW,
|
||
|
- ov7251->current_mode->vts & 0xff);
|
||
|
+ ov7251->current_ival->vts & 0xff);
|
||
|
if (ret)
|
||
|
goto err_power_down;
|
||
|
ret = __v4l2_ctrl_handler_setup(&ov7251->ctrls);
|
||
|
@@ -1073,7 +1068,7 @@ static int ov7251_get_frame_interval(str
|
||
|
struct ov7251 *ov7251 = to_ov7251(subdev);
|
||
|
|
||
|
mutex_lock(&ov7251->lock);
|
||
|
- fi->interval = ov7251->current_mode->timeperframe;
|
||
|
+ fi->interval = ov7251->current_ival->timeperframe;
|
||
|
mutex_unlock(&ov7251->lock);
|
||
|
|
||
|
return 0;
|
||
|
@@ -1083,28 +1078,29 @@ static int ov7251_set_frame_interval(str
|
||
|
struct v4l2_subdev_frame_interval *fi)
|
||
|
{
|
||
|
struct ov7251 *ov7251 = to_ov7251(subdev);
|
||
|
- const struct ov7251_mode_info *new_mode;
|
||
|
+ const struct ov7251_frame_ival_info *new_ival;
|
||
|
int ret = 0;
|
||
|
|
||
|
mutex_lock(&ov7251->lock);
|
||
|
- new_mode = ov7251_find_mode_by_ival(ov7251, &fi->interval);
|
||
|
+ new_ival = ov7251_find_frame_ival_by_ival(ov7251, &fi->interval);
|
||
|
|
||
|
- if (new_mode != ov7251->current_mode) {
|
||
|
+ if (new_ival != ov7251->current_ival) {
|
||
|
ret = __v4l2_ctrl_modify_range(ov7251->exposure, 1,
|
||
|
- new_mode->vts - OV7251_EXPOSURE_OFFSET,
|
||
|
- 1, new_mode->exposure_def);
|
||
|
+ new_ival->vts -
|
||
|
+ OV7251_EXPOSURE_OFFSET,
|
||
|
+ 1, ov7251->current_mode->exposure_def);
|
||
|
if (ret < 0)
|
||
|
goto exit;
|
||
|
|
||
|
ret = __v4l2_ctrl_s_ctrl(ov7251->exposure,
|
||
|
- new_mode->exposure_def);
|
||
|
+ ov7251->current_mode->exposure_def);
|
||
|
if (ret < 0)
|
||
|
goto exit;
|
||
|
|
||
|
- ov7251->current_mode = new_mode;
|
||
|
+ ov7251->current_ival = new_ival;
|
||
|
}
|
||
|
|
||
|
- fi->interval = ov7251->current_mode->timeperframe;
|
||
|
+ fi->interval = ov7251->current_ival->timeperframe;
|
||
|
|
||
|
exit:
|
||
|
mutex_unlock(&ov7251->lock);
|
||
|
@@ -1316,6 +1312,7 @@ static int ov7251_probe(struct i2c_clien
|
||
|
mutex_init(&ov7251->lock);
|
||
|
|
||
|
ov7251->current_mode = &ov7251_mode_info_data[0];
|
||
|
+ ov7251->current_ival = &ov7251_frame_ival_info_data[0];
|
||
|
|
||
|
v4l2_ctrl_handler_init(&ov7251->ctrls, 10);
|
||
|
ov7251->ctrls.lock = &ov7251->lock;
|