ImmortalWrt/target/linux/bcm27xx/patches-5.15/950-0736-media-i2c-ov7251-Separate-modes-from-frame-intervals.patch
Álvaro Fernández Rojas 20ea6adbf1 bcm27xx: add support for linux v5.15
Build system: x86_64
Build-tested: bcm2708, bcm2709, bcm2710, bcm2711
Run-tested: bcm2708/RPiB+, bcm2709/RPi3B, bcm2710/RPi3B, bcm2711/RPi4B

Signed-off-by: Marty Jones <mj8263788@gmail.com>
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2022-05-17 15:11:22 +02:00

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;