mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 15:32:33 +00:00
135 lines
4.3 KiB
Diff
135 lines
4.3 KiB
Diff
|
From 0dd7e12bb7dc81e09440f3330465c31349497dc3 Mon Sep 17 00:00:00 2001
|
||
|
From: Jacopo Mondi <jacopo+renesas@jmondi.org>
|
||
|
Date: Tue, 16 Jun 2020 16:12:38 +0200
|
||
|
Subject: [PATCH]_mbus_config
|
||
|
ops
|
||
|
|
||
|
Upstream https://patchwork.linuxtv.org/patch/64674/
|
||
|
|
||
|
Use the new get_mbus_config and set_mbus_config pad operations in place
|
||
|
of the video operations currently in use.
|
||
|
|
||
|
Compared to other drivers where the same conversion has been performed,
|
||
|
ov6650 proved to be a bit more tricky, as the existing g_mbus_config
|
||
|
implementation did not report the currently applied configuration but
|
||
|
the set of all possible configuration options.
|
||
|
|
||
|
Adapt the driver to support the semantic of the two newly introduced
|
||
|
operations:
|
||
|
- get_mbus_config reports the current media bus configuration
|
||
|
- set_mbus_config applies only changes explicitly requested and updates
|
||
|
the provided cfg parameter to report what has actually been applied to
|
||
|
the hardware.
|
||
|
|
||
|
Compile-tested only.
|
||
|
|
||
|
Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
|
||
|
---
|
||
|
drivers/media/i2c/ov6650.c | 56 ++++++++++++++++++++++++++------------
|
||
|
1 file changed, 39 insertions(+), 17 deletions(-)
|
||
|
|
||
|
--- a/drivers/media/i2c/ov6650.c
|
||
|
+++ b/drivers/media/i2c/ov6650.c
|
||
|
@@ -909,46 +909,68 @@ static const struct v4l2_subdev_core_ops
|
||
|
};
|
||
|
|
||
|
/* Request bus settings on camera side */
|
||
|
-static int ov6650_g_mbus_config(struct v4l2_subdev *sd,
|
||
|
- struct v4l2_mbus_config *cfg)
|
||
|
+static int ov6650_get_mbus_config(struct v4l2_subdev *sd,
|
||
|
+ unsigned int pad,
|
||
|
+ struct v4l2_mbus_config *cfg)
|
||
|
{
|
||
|
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||
|
+ u8 comj, comf;
|
||
|
+ int ret;
|
||
|
+
|
||
|
+ ret = ov6650_reg_read(client, REG_COMJ, &comj);
|
||
|
+ if (ret)
|
||
|
+ return ret;
|
||
|
+
|
||
|
+ ret = ov6650_reg_read(client, REG_COMF, &comf);
|
||
|
+ if (ret)
|
||
|
+ return ret;
|
||
|
|
||
|
- cfg->flags = V4L2_MBUS_MASTER |
|
||
|
- V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
|
||
|
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
|
||
|
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
|
||
|
- V4L2_MBUS_DATA_ACTIVE_HIGH;
|
||
|
+ cfg->flags = V4L2_MBUS_MASTER
|
||
|
+ | ((comj & COMJ_VSYNC_HIGH) ? V4L2_MBUS_VSYNC_ACTIVE_HIGH
|
||
|
+ : V4L2_MBUS_VSYNC_ACTIVE_LOW)
|
||
|
+ | ((comf & COMF_HREF_LOW) ? V4L2_MBUS_HSYNC_ACTIVE_LOW
|
||
|
+ : V4L2_MBUS_HSYNC_ACTIVE_HIGH)
|
||
|
+ | ((comj & COMJ_PCLK_RISING) ? V4L2_MBUS_PCLK_SAMPLE_RISING
|
||
|
+ : V4L2_MBUS_PCLK_SAMPLE_FALLING);
|
||
|
cfg->type = V4L2_MBUS_PARALLEL;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* Alter bus settings on camera side */
|
||
|
-static int ov6650_s_mbus_config(struct v4l2_subdev *sd,
|
||
|
- const struct v4l2_mbus_config *cfg)
|
||
|
+static int ov6650_set_mbus_config(struct v4l2_subdev *sd,
|
||
|
+ unsigned int pad,
|
||
|
+ struct v4l2_mbus_config *cfg)
|
||
|
{
|
||
|
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||
|
- int ret;
|
||
|
+ int ret = 0;
|
||
|
|
||
|
if (cfg->flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
|
||
|
ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0);
|
||
|
- else
|
||
|
+ else if (cfg->flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
|
||
|
ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING);
|
||
|
if (ret)
|
||
|
- return ret;
|
||
|
+ goto error;
|
||
|
|
||
|
if (cfg->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
|
||
|
ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0);
|
||
|
- else
|
||
|
+ else if (cfg->flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
|
||
|
ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW);
|
||
|
if (ret)
|
||
|
- return ret;
|
||
|
+ goto error;
|
||
|
|
||
|
if (cfg->flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
|
||
|
ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0);
|
||
|
- else
|
||
|
+ else if (cfg->flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
|
||
|
ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH);
|
||
|
|
||
|
+error:
|
||
|
+ /*
|
||
|
+ * Update the configuration to report what is actually applied to
|
||
|
+ * the hardware.
|
||
|
+ */
|
||
|
+ ov6650_get_mbus_config(sd, pad, cfg);
|
||
|
+
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
@@ -956,8 +978,6 @@ static const struct v4l2_subdev_video_op
|
||
|
.s_stream = ov6650_s_stream,
|
||
|
.g_frame_interval = ov6650_g_frame_interval,
|
||
|
.s_frame_interval = ov6650_s_frame_interval,
|
||
|
- .g_mbus_config = ov6650_g_mbus_config,
|
||
|
- .s_mbus_config = ov6650_s_mbus_config,
|
||
|
};
|
||
|
|
||
|
static const struct v4l2_subdev_pad_ops ov6650_pad_ops = {
|
||
|
@@ -966,6 +986,8 @@ static const struct v4l2_subdev_pad_ops
|
||
|
.set_selection = ov6650_set_selection,
|
||
|
.get_fmt = ov6650_get_fmt,
|
||
|
.set_fmt = ov6650_set_fmt,
|
||
|
+ .get_mbus_config = ov6650_get_mbus_config,
|
||
|
+ .set_mbus_config = ov6650_set_mbus_config,
|
||
|
};
|
||
|
|
||
|
static const struct v4l2_subdev_ops ov6650_subdev_ops = {
|