* [PATCH v1 0/4] Add OV5640 parallel interface and RGB565/YUYV support
@ 2017-11-16 13:41 Hugues Fruchet
2017-11-16 13:41 ` [PATCH v1 1/4] media: ov5640: switch to gpiod_set_value_cansleep() Hugues Fruchet
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Hugues Fruchet @ 2017-11-16 13:41 UTC (permalink / raw)
To: Steve Longerbeam, Hans Verkuil, Mauro Carvalho Chehab
Cc: linux-media, Hugues Fruchet, Benjamin Gaignard
Enhance OV5640 CSI driver to support also DVP parallel interface.
Add RGB565 (LE & BE) and YUV422 YUYV format in addition to existing
YUV422 UYVY format.
Some other improvements on chip identifier check and removal
of warnings in powering phase around gpio handling.
Hugues Fruchet (4):
media: ov5640: switch to gpiod_set_value_cansleep()
media: ov5640: check chip id
media: ov5640: add support of DVP parallel interface
media: ov5640: add support of RGB565 and YUYV formats
drivers/media/i2c/ov5640.c | 229 +++++++++++++++++++++++++++++++++++++++------
1 file changed, 198 insertions(+), 31 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v1 1/4] media: ov5640: switch to gpiod_set_value_cansleep()
2017-11-16 13:41 [PATCH v1 0/4] Add OV5640 parallel interface and RGB565/YUYV support Hugues Fruchet
@ 2017-11-16 13:41 ` Hugues Fruchet
2017-11-16 13:41 ` [PATCH v1 2/4] media: ov5640: check chip id Hugues Fruchet
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: Hugues Fruchet @ 2017-11-16 13:41 UTC (permalink / raw)
To: Steve Longerbeam, Hans Verkuil, Mauro Carvalho Chehab
Cc: linux-media, Hugues Fruchet, Benjamin Gaignard
Switch gpiod_set_value to gpiod_set_value_cansleep to avoid
warnings when powering sensor.
Signed-off-by: Hugues Fruchet <hugues.fruchet@st.com>
---
drivers/media/i2c/ov5640.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index c89ed66..61071f5 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -1524,7 +1524,7 @@ static int ov5640_restore_mode(struct ov5640_dev *sensor)
static void ov5640_power(struct ov5640_dev *sensor, bool enable)
{
- gpiod_set_value(sensor->pwdn_gpio, enable ? 0 : 1);
+ gpiod_set_value_cansleep(sensor->pwdn_gpio, enable ? 0 : 1);
}
static void ov5640_reset(struct ov5640_dev *sensor)
@@ -1532,7 +1532,7 @@ static void ov5640_reset(struct ov5640_dev *sensor)
if (!sensor->reset_gpio)
return;
- gpiod_set_value(sensor->reset_gpio, 0);
+ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
/* camera power cycle */
ov5640_power(sensor, false);
@@ -1540,10 +1540,10 @@ static void ov5640_reset(struct ov5640_dev *sensor)
ov5640_power(sensor, true);
usleep_range(5000, 10000);
- gpiod_set_value(sensor->reset_gpio, 1);
+ gpiod_set_value_cansleep(sensor->reset_gpio, 1);
usleep_range(1000, 2000);
- gpiod_set_value(sensor->reset_gpio, 0);
+ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
usleep_range(5000, 10000);
}
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v1 2/4] media: ov5640: check chip id
2017-11-16 13:41 [PATCH v1 0/4] Add OV5640 parallel interface and RGB565/YUYV support Hugues Fruchet
2017-11-16 13:41 ` [PATCH v1 1/4] media: ov5640: switch to gpiod_set_value_cansleep() Hugues Fruchet
@ 2017-11-16 13:41 ` Hugues Fruchet
2017-11-16 13:41 ` [PATCH v1 3/4] media: ov5640: add support of DVP parallel interface Hugues Fruchet
2017-11-16 13:41 ` [PATCH v1 4/4] media: ov5640: add support of RGB565 and YUYV formats Hugues Fruchet
3 siblings, 0 replies; 9+ messages in thread
From: Hugues Fruchet @ 2017-11-16 13:41 UTC (permalink / raw)
To: Steve Longerbeam, Hans Verkuil, Mauro Carvalho Chehab
Cc: linux-media, Hugues Fruchet, Benjamin Gaignard
Verify that chip identifier is correct before starting streaming
Signed-off-by: Hugues Fruchet <hugues.fruchet@st.com>
---
drivers/media/i2c/ov5640.c | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index 61071f5..a576d11 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -34,7 +34,8 @@
#define OV5640_DEFAULT_SLAVE_ID 0x3c
-#define OV5640_REG_CHIP_ID 0x300a
+#define OV5640_REG_CHIP_ID_HIGH 0x300a
+#define OV5640_REG_CHIP_ID_LOW 0x300b
#define OV5640_REG_PAD_OUTPUT00 0x3019
#define OV5640_REG_SC_PLL_CTRL0 0x3034
#define OV5640_REG_SC_PLL_CTRL1 0x3035
@@ -926,6 +927,29 @@ static int ov5640_load_regs(struct ov5640_dev *sensor,
return ret;
}
+static int ov5640_check_chip_id(struct ov5640_dev *sensor)
+{
+ struct i2c_client *client = sensor->i2c_client;
+ int ret;
+ u8 chip_id_h, chip_id_l;
+
+ ret = ov5640_read_reg(sensor, OV5640_REG_CHIP_ID_HIGH, &chip_id_h);
+ if (ret)
+ return ret;
+
+ ret = ov5640_read_reg(sensor, OV5640_REG_CHIP_ID_LOW, &chip_id_l);
+ if (ret)
+ return ret;
+
+ if (!(chip_id_h == 0x56 && chip_id_l == 0x40)) {
+ dev_err(&client->dev, "%s: wrong chip identifier, expected 0x5640, got 0x%x%x\n",
+ __func__, chip_id_h, chip_id_l);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/* read exposure, in number of line periods */
static int ov5640_get_exposure(struct ov5640_dev *sensor)
{
@@ -1562,6 +1586,10 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
ov5640_reset(sensor);
ov5640_power(sensor, true);
+ ret = ov5640_check_chip_id(sensor);
+ if (ret)
+ goto power_off;
+
ret = ov5640_init_slave_id(sensor);
if (ret)
goto power_off;
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v1 3/4] media: ov5640: add support of DVP parallel interface
2017-11-16 13:41 [PATCH v1 0/4] Add OV5640 parallel interface and RGB565/YUYV support Hugues Fruchet
2017-11-16 13:41 ` [PATCH v1 1/4] media: ov5640: switch to gpiod_set_value_cansleep() Hugues Fruchet
2017-11-16 13:41 ` [PATCH v1 2/4] media: ov5640: check chip id Hugues Fruchet
@ 2017-11-16 13:41 ` Hugues Fruchet
2017-11-24 14:06 ` Sakari Ailus
2017-11-16 13:41 ` [PATCH v1 4/4] media: ov5640: add support of RGB565 and YUYV formats Hugues Fruchet
3 siblings, 1 reply; 9+ messages in thread
From: Hugues Fruchet @ 2017-11-16 13:41 UTC (permalink / raw)
To: Steve Longerbeam, Hans Verkuil, Mauro Carvalho Chehab
Cc: linux-media, Hugues Fruchet, Benjamin Gaignard
Add support of DVP parallel mode in addition of
existing MIPI CSI mode. The choice between two modes
and configuration is made through device tree.
Signed-off-by: Hugues Fruchet <hugues.fruchet@st.com>
---
drivers/media/i2c/ov5640.c | 112 +++++++++++++++++++++++++++++++++++++--------
1 file changed, 94 insertions(+), 18 deletions(-)
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index a576d11..fb519ad 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -34,14 +34,20 @@
#define OV5640_DEFAULT_SLAVE_ID 0x3c
+#define OV5640_REG_SYS_CTRL0 0x3008
#define OV5640_REG_CHIP_ID_HIGH 0x300a
#define OV5640_REG_CHIP_ID_LOW 0x300b
+#define OV5640_REG_IO_MIPI_CTRL00 0x300e
+#define OV5640_REG_PAD_OUTPUT_ENABLE01 0x3017
+#define OV5640_REG_PAD_OUTPUT_ENABLE02 0x3018
#define OV5640_REG_PAD_OUTPUT00 0x3019
+#define OV5640_REG_SYSTEM_CONTROL1 0x302e
#define OV5640_REG_SC_PLL_CTRL0 0x3034
#define OV5640_REG_SC_PLL_CTRL1 0x3035
#define OV5640_REG_SC_PLL_CTRL2 0x3036
#define OV5640_REG_SC_PLL_CTRL3 0x3037
#define OV5640_REG_SLAVE_ID 0x3100
+#define OV5640_REG_SCCB_SYS_CTRL1 0x3103
#define OV5640_REG_SYS_ROOT_DIVIDER 0x3108
#define OV5640_REG_AWB_R_GAIN 0x3400
#define OV5640_REG_AWB_G_GAIN 0x3402
@@ -1006,7 +1012,71 @@ static int ov5640_get_gain(struct ov5640_dev *sensor)
return gain & 0x3ff;
}
-static int ov5640_set_stream(struct ov5640_dev *sensor, bool on)
+static int ov5640_set_stream_dvp(struct ov5640_dev *sensor)
+{
+ int ret;
+
+ /*
+ * MIPI CONTROL 00
+ * 6:mipi lane debug
+ * 4:PWDN PHY TX
+ * 3:PWDN PHY RX
+ */
+ ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x58);
+ if (ret)
+ return ret;
+
+ /* SYSTEM CONTROL, not recommended... */
+ ret = ov5640_write_reg(sensor, OV5640_REG_SYSTEM_CONTROL1, 0x00);
+ if (ret)
+ return ret;
+
+ /* SCCB SYSTEM CTRL1 1:system input clk from PLL, 0:debug enable */
+ ret = ov5640_write_reg(sensor, OV5640_REG_SCCB_SYS_CTRL1, 0x03);
+ if (ret)
+ return ret;
+
+ /* SYSTEM CTRL0 1:debug enable */
+ ret = ov5640_write_reg(sensor, OV5640_REG_SYS_CTRL0, 0x02);
+ if (ret)
+ return ret;
+
+ /*
+ * SC PLL CONTRL1 0
+ * - [7..4]: System clock divider = 4
+ * - [3..0]: MIPI PCLK/SERCLK divider = 1
+ */
+ ret = ov5640_write_reg(sensor, OV5640_REG_SC_PLL_CTRL1, 0x41);
+ if (ret)
+ return ret;
+
+ /* OV5640_REG_SC_PLL_CTRL2 [7:0]: PLL multiplier (4~252) = 0x60 */
+ ret = ov5640_write_reg(sensor, OV5640_REG_SC_PLL_CTRL2, 0x60);
+ if (ret)
+ return ret;
+
+ /*
+ * PAD OUTPUT ENABLE 01:
+ * - 6: VSYNC output enable
+ * - 5: HREF output enable
+ * - 4: PCLK output enable
+ * - [3:0]: D[9:6] output enable
+ */
+ ret = ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE01, 0x7f);
+ if (ret)
+ return ret;
+
+ /*
+ * PAD OUTPUT ENABLE 02:
+ * - [7:4]: D[5:2] output enable
+ * 0:1 are unused with 8 bits
+ * parallel mode (8 bits output
+ * are on D[9:2])
+ */
+ return ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE02, 0xf0);
+}
+
+static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on)
{
int ret;
@@ -1598,17 +1668,24 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
if (ret)
goto power_off;
- /*
- * start streaming briefly followed by stream off in
- * order to coax the clock lane into LP-11 state.
- */
- ret = ov5640_set_stream(sensor, true);
- if (ret)
- goto power_off;
- usleep_range(1000, 2000);
- ret = ov5640_set_stream(sensor, false);
- if (ret)
- goto power_off;
+ if (sensor->ep.bus_type == V4L2_MBUS_CSI2) {
+ /*
+ * start streaming briefly followed by stream off in
+ * order to coax the clock lane into LP-11 state.
+ */
+ ret = ov5640_set_stream_mipi(sensor, true);
+ if (ret)
+ goto power_off;
+ usleep_range(1000, 2000);
+ ret = ov5640_set_stream_mipi(sensor, false);
+ if (ret)
+ goto power_off;
+ } else {
+ ret = ov5640_set_stream_dvp(sensor);
+ if (ret)
+ goto power_off;
+ usleep_range(40000, 60000);
+ }
return 0;
}
@@ -2185,7 +2262,11 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
goto out;
}
- ret = ov5640_set_stream(sensor, enable);
+ if (sensor->ep.bus_type == V4L2_MBUS_CSI2)
+ ret = ov5640_set_stream_mipi(sensor, enable);
+ else
+ ret = ov5640_set_stream_dvp(sensor);
+
if (!ret)
sensor->streaming = enable;
}
@@ -2270,11 +2351,6 @@ static int ov5640_probe(struct i2c_client *client,
return ret;
}
- if (sensor->ep.bus_type != V4L2_MBUS_CSI2) {
- dev_err(dev, "invalid bus type, must be MIPI CSI2\n");
- return -EINVAL;
- }
-
/* get system clock (xclk) */
sensor->xclk = devm_clk_get(dev, "xclk");
if (IS_ERR(sensor->xclk)) {
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v1 4/4] media: ov5640: add support of RGB565 and YUYV formats
2017-11-16 13:41 [PATCH v1 0/4] Add OV5640 parallel interface and RGB565/YUYV support Hugues Fruchet
` (2 preceding siblings ...)
2017-11-16 13:41 ` [PATCH v1 3/4] media: ov5640: add support of DVP parallel interface Hugues Fruchet
@ 2017-11-16 13:41 ` Hugues Fruchet
2017-11-24 14:09 ` Sakari Ailus
3 siblings, 1 reply; 9+ messages in thread
From: Hugues Fruchet @ 2017-11-16 13:41 UTC (permalink / raw)
To: Steve Longerbeam, Hans Verkuil, Mauro Carvalho Chehab
Cc: linux-media, Hugues Fruchet, Benjamin Gaignard
Add RGB565 (LE & BE) and YUV422 YUYV format in addition
to existing YUV422 UYVY format.
Signed-off-by: Hugues Fruchet <hugues.fruchet@st.com>
---
drivers/media/i2c/ov5640.c | 79 +++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 71 insertions(+), 8 deletions(-)
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index fb519ad..086a451 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -77,8 +77,10 @@
#define OV5640_REG_HZ5060_CTRL01 0x3c01
#define OV5640_REG_SIGMADELTA_CTRL0C 0x3c0c
#define OV5640_REG_FRAME_CTRL01 0x4202
+#define OV5640_REG_FORMAT_CONTROL00 0x4300
#define OV5640_REG_MIPI_CTRL00 0x4800
#define OV5640_REG_DEBUG_MODE 0x4814
+#define OV5640_REG_ISP_FORMAT_MUX_CTRL 0x501f
#define OV5640_REG_PRE_ISP_TEST_SET1 0x503d
#define OV5640_REG_SDE_CTRL0 0x5580
#define OV5640_REG_SDE_CTRL1 0x5581
@@ -106,6 +108,18 @@ enum ov5640_frame_rate {
OV5640_NUM_FRAMERATES,
};
+struct ov5640_pixfmt {
+ u32 code;
+ u32 colorspace;
+};
+
+static const struct ov5640_pixfmt ov5640_formats[] = {
+ { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB, },
+ { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_SRGB, },
+ { MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB, },
+ { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB, },
+};
+
/*
* FIXME: remove this when a subdev API becomes available
* to set the MIPI CSI-2 virtual channel.
@@ -1798,17 +1812,23 @@ static int ov5640_try_fmt_internal(struct v4l2_subdev *sd,
{
struct ov5640_dev *sensor = to_ov5640_dev(sd);
const struct ov5640_mode_info *mode;
+ int i;
mode = ov5640_find_mode(sensor, fr, fmt->width, fmt->height, true);
if (!mode)
return -EINVAL;
-
fmt->width = mode->width;
fmt->height = mode->height;
- fmt->code = sensor->fmt.code;
if (new_mode)
*new_mode = mode;
+
+ for (i = 0; i < ARRAY_SIZE(ov5640_formats); i++)
+ if (ov5640_formats[i].code == fmt->code)
+ break;
+ if (i >= ARRAY_SIZE(ov5640_formats))
+ fmt->code = ov5640_formats[0].code;
+
return 0;
}
@@ -1851,6 +1871,49 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd,
return ret;
}
+static int ov5640_set_framefmt(struct ov5640_dev *sensor,
+ struct v4l2_mbus_framefmt *format)
+{
+ int ret = 0;
+ bool is_rgb = false;
+ u8 val;
+
+ switch (format->code) {
+ case MEDIA_BUS_FMT_UYVY8_2X8:
+ /* YUV422, UYVY */
+ val = 0x3f;
+ break;
+ case MEDIA_BUS_FMT_YUYV8_2X8:
+ /* YUV422, YUYV */
+ val = 0x30;
+ break;
+ case MEDIA_BUS_FMT_RGB565_2X8_LE:
+ /* RGB565 {g[2:0],b[4:0]},{r[4:0],g[5:3]} */
+ val = 0x6F;
+ is_rgb = true;
+ break;
+ case MEDIA_BUS_FMT_RGB565_2X8_BE:
+ /* RGB565 {r[4:0],g[5:3]},{g[2:0],b[4:0]} */
+ val = 0x61;
+ is_rgb = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* FORMAT CONTROL00: YUV and RGB formatting */
+ ret = ov5640_write_reg(sensor, OV5640_REG_FORMAT_CONTROL00, val);
+ if (ret)
+ return ret;
+
+ /* FORMAT MUX CONTROL: ISP YUV or RGB */
+ ret = ov5640_write_reg(sensor, OV5640_REG_ISP_FORMAT_MUX_CTRL,
+ is_rgb ? 0x01 : 0x00);
+ if (ret)
+ return ret;
+
+ return ret;
+}
/*
* Sensor Controls.
@@ -2236,15 +2299,12 @@ static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_mbus_code_enum *code)
{
- struct ov5640_dev *sensor = to_ov5640_dev(sd);
-
if (code->pad != 0)
return -EINVAL;
- if (code->index != 0)
+ if (code->index >= ARRAY_SIZE(ov5640_formats))
return -EINVAL;
- code->code = sensor->fmt.code;
-
+ code->code = ov5640_formats[code->index].code;
return 0;
}
@@ -2254,12 +2314,15 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
int ret = 0;
mutex_lock(&sensor->lock);
-
if (sensor->streaming == !enable) {
if (enable && sensor->pending_mode_change) {
ret = ov5640_set_mode(sensor, sensor->current_mode);
if (ret)
goto out;
+
+ ret = ov5640_set_framefmt(sensor, &sensor->fmt);
+ if (ret)
+ goto out;
}
if (sensor->ep.bus_type == V4L2_MBUS_CSI2)
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v1 3/4] media: ov5640: add support of DVP parallel interface
2017-11-16 13:41 ` [PATCH v1 3/4] media: ov5640: add support of DVP parallel interface Hugues Fruchet
@ 2017-11-24 14:06 ` Sakari Ailus
2017-11-28 16:07 ` Hugues FRUCHET
0 siblings, 1 reply; 9+ messages in thread
From: Sakari Ailus @ 2017-11-24 14:06 UTC (permalink / raw)
To: Hugues Fruchet
Cc: Steve Longerbeam, Hans Verkuil, Mauro Carvalho Chehab,
linux-media, Benjamin Gaignard
Hi Hugues,
On Thu, Nov 16, 2017 at 02:41:41PM +0100, Hugues Fruchet wrote:
> @@ -2185,7 +2262,11 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
> goto out;
> }
>
> - ret = ov5640_set_stream(sensor, enable);
> + if (sensor->ep.bus_type == V4L2_MBUS_CSI2)
> + ret = ov5640_set_stream_mipi(sensor, enable);
> + else
> + ret = ov5640_set_stream_dvp(sensor);
Hmm. Do you want to configure it even when you're disabling streaming?
--
Sakari Ailus
e-mail: sakari.ailus@iki.fi
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v1 4/4] media: ov5640: add support of RGB565 and YUYV formats
2017-11-16 13:41 ` [PATCH v1 4/4] media: ov5640: add support of RGB565 and YUYV formats Hugues Fruchet
@ 2017-11-24 14:09 ` Sakari Ailus
2017-11-28 15:39 ` Hugues FRUCHET
0 siblings, 1 reply; 9+ messages in thread
From: Sakari Ailus @ 2017-11-24 14:09 UTC (permalink / raw)
To: Hugues Fruchet
Cc: Steve Longerbeam, Hans Verkuil, Mauro Carvalho Chehab,
linux-media, Benjamin Gaignard
Hi Hugues,
On Thu, Nov 16, 2017 at 02:41:42PM +0100, Hugues Fruchet wrote:
> Add RGB565 (LE & BE) and YUV422 YUYV format in addition
> to existing YUV422 UYVY format.
>
> Signed-off-by: Hugues Fruchet <hugues.fruchet@st.com>
> ---
> drivers/media/i2c/ov5640.c | 79 +++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 71 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
> index fb519ad..086a451 100644
> --- a/drivers/media/i2c/ov5640.c
> +++ b/drivers/media/i2c/ov5640.c
> @@ -77,8 +77,10 @@
> #define OV5640_REG_HZ5060_CTRL01 0x3c01
> #define OV5640_REG_SIGMADELTA_CTRL0C 0x3c0c
> #define OV5640_REG_FRAME_CTRL01 0x4202
> +#define OV5640_REG_FORMAT_CONTROL00 0x4300
> #define OV5640_REG_MIPI_CTRL00 0x4800
> #define OV5640_REG_DEBUG_MODE 0x4814
> +#define OV5640_REG_ISP_FORMAT_MUX_CTRL 0x501f
> #define OV5640_REG_PRE_ISP_TEST_SET1 0x503d
> #define OV5640_REG_SDE_CTRL0 0x5580
> #define OV5640_REG_SDE_CTRL1 0x5581
> @@ -106,6 +108,18 @@ enum ov5640_frame_rate {
> OV5640_NUM_FRAMERATES,
> };
>
> +struct ov5640_pixfmt {
> + u32 code;
> + u32 colorspace;
> +};
> +
> +static const struct ov5640_pixfmt ov5640_formats[] = {
> + { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB, },
> + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_SRGB, },
> + { MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB, },
> + { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB, },
> +};
> +
> /*
> * FIXME: remove this when a subdev API becomes available
> * to set the MIPI CSI-2 virtual channel.
> @@ -1798,17 +1812,23 @@ static int ov5640_try_fmt_internal(struct v4l2_subdev *sd,
> {
> struct ov5640_dev *sensor = to_ov5640_dev(sd);
> const struct ov5640_mode_info *mode;
> + int i;
>
> mode = ov5640_find_mode(sensor, fr, fmt->width, fmt->height, true);
> if (!mode)
> return -EINVAL;
> -
> fmt->width = mode->width;
> fmt->height = mode->height;
> - fmt->code = sensor->fmt.code;
>
> if (new_mode)
> *new_mode = mode;
> +
> + for (i = 0; i < ARRAY_SIZE(ov5640_formats); i++)
> + if (ov5640_formats[i].code == fmt->code)
> + break;
> + if (i >= ARRAY_SIZE(ov5640_formats))
> + fmt->code = ov5640_formats[0].code;
> +
> return 0;
> }
>
> @@ -1851,6 +1871,49 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd,
> return ret;
> }
>
> +static int ov5640_set_framefmt(struct ov5640_dev *sensor,
> + struct v4l2_mbus_framefmt *format)
> +{
> + int ret = 0;
> + bool is_rgb = false;
> + u8 val;
> +
> + switch (format->code) {
> + case MEDIA_BUS_FMT_UYVY8_2X8:
> + /* YUV422, UYVY */
> + val = 0x3f;
> + break;
> + case MEDIA_BUS_FMT_YUYV8_2X8:
> + /* YUV422, YUYV */
> + val = 0x30;
> + break;
> + case MEDIA_BUS_FMT_RGB565_2X8_LE:
> + /* RGB565 {g[2:0],b[4:0]},{r[4:0],g[5:3]} */
> + val = 0x6F;
> + is_rgb = true;
> + break;
> + case MEDIA_BUS_FMT_RGB565_2X8_BE:
> + /* RGB565 {r[4:0],g[5:3]},{g[2:0],b[4:0]} */
> + val = 0x61;
> + is_rgb = true;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + /* FORMAT CONTROL00: YUV and RGB formatting */
> + ret = ov5640_write_reg(sensor, OV5640_REG_FORMAT_CONTROL00, val);
> + if (ret)
> + return ret;
> +
> + /* FORMAT MUX CONTROL: ISP YUV or RGB */
> + ret = ov5640_write_reg(sensor, OV5640_REG_ISP_FORMAT_MUX_CTRL,
> + is_rgb ? 0x01 : 0x00);
return ov5640...;
> + if (ret)
> + return ret;
> +
> + return ret;
> +}
>
> /*
> * Sensor Controls.
> @@ -2236,15 +2299,12 @@ static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
> struct v4l2_subdev_pad_config *cfg,
> struct v4l2_subdev_mbus_code_enum *code)
> {
> - struct ov5640_dev *sensor = to_ov5640_dev(sd);
> -
> if (code->pad != 0)
> return -EINVAL;
> - if (code->index != 0)
> + if (code->index >= ARRAY_SIZE(ov5640_formats))
> return -EINVAL;
>
> - code->code = sensor->fmt.code;
> -
> + code->code = ov5640_formats[code->index].code;
> return 0;
> }
>
> @@ -2254,12 +2314,15 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
> int ret = 0;
>
> mutex_lock(&sensor->lock);
> -
I rather liked this newline!
> if (sensor->streaming == !enable) {
> if (enable && sensor->pending_mode_change) {
> ret = ov5640_set_mode(sensor, sensor->current_mode);
> if (ret)
> goto out;
> +
> + ret = ov5640_set_framefmt(sensor, &sensor->fmt);
> + if (ret)
> + goto out;
> }
>
> if (sensor->ep.bus_type == V4L2_MBUS_CSI2)
--
Sakari Ailus
e-mail: sakari.ailus@iki.fi
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v1 4/4] media: ov5640: add support of RGB565 and YUYV formats
2017-11-24 14:09 ` Sakari Ailus
@ 2017-11-28 15:39 ` Hugues FRUCHET
0 siblings, 0 replies; 9+ messages in thread
From: Hugues FRUCHET @ 2017-11-28 15:39 UTC (permalink / raw)
To: Sakari Ailus
Cc: Steve Longerbeam, Hans Verkuil, Mauro Carvalho Chehab,
linux-media, Benjamin Gaignard
Thanks for review Sakari,
On 11/24/2017 03:09 PM, Sakari Ailus wrote:
> Hi Hugues,
>
> On Thu, Nov 16, 2017 at 02:41:42PM +0100, Hugues Fruchet wrote:
>> Add RGB565 (LE & BE) and YUV422 YUYV format in addition
>> to existing YUV422 UYVY format.
>>
>> Signed-off-by: Hugues Fruchet <hugues.fruchet@st.com>
>> ---
>> drivers/media/i2c/ov5640.c | 79 +++++++++++++++++++++++++++++++++++++++++-----
>> 1 file changed, 71 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
>> index fb519ad..086a451 100644
>> --- a/drivers/media/i2c/ov5640.c
>> +++ b/drivers/media/i2c/ov5640.c
>> @@ -77,8 +77,10 @@
>> #define OV5640_REG_HZ5060_CTRL01 0x3c01
>> #define OV5640_REG_SIGMADELTA_CTRL0C 0x3c0c
>> #define OV5640_REG_FRAME_CTRL01 0x4202
>> +#define OV5640_REG_FORMAT_CONTROL00 0x4300
>> #define OV5640_REG_MIPI_CTRL00 0x4800
>> #define OV5640_REG_DEBUG_MODE 0x4814
>> +#define OV5640_REG_ISP_FORMAT_MUX_CTRL 0x501f
>> #define OV5640_REG_PRE_ISP_TEST_SET1 0x503d
>> #define OV5640_REG_SDE_CTRL0 0x5580
>> #define OV5640_REG_SDE_CTRL1 0x5581
>> @@ -106,6 +108,18 @@ enum ov5640_frame_rate {
>> OV5640_NUM_FRAMERATES,
>> };
>>
>> +struct ov5640_pixfmt {
>> + u32 code;
>> + u32 colorspace;
>> +};
>> +
>> +static const struct ov5640_pixfmt ov5640_formats[] = {
>> + { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB, },
>> + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_SRGB, },
>> + { MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB, },
>> + { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB, },
>> +};
>> +
>> /*
>> * FIXME: remove this when a subdev API becomes available
>> * to set the MIPI CSI-2 virtual channel.
>> @@ -1798,17 +1812,23 @@ static int ov5640_try_fmt_internal(struct v4l2_subdev *sd,
>> {
>> struct ov5640_dev *sensor = to_ov5640_dev(sd);
>> const struct ov5640_mode_info *mode;
>> + int i;
>>
>> mode = ov5640_find_mode(sensor, fr, fmt->width, fmt->height, true);
>> if (!mode)
>> return -EINVAL;
>> -
>> fmt->width = mode->width;
>> fmt->height = mode->height;
>> - fmt->code = sensor->fmt.code;
>>
>> if (new_mode)
>> *new_mode = mode;
>> +
>> + for (i = 0; i < ARRAY_SIZE(ov5640_formats); i++)
>> + if (ov5640_formats[i].code == fmt->code)
>> + break;
>> + if (i >= ARRAY_SIZE(ov5640_formats))
>> + fmt->code = ov5640_formats[0].code;
>> +
>> return 0;
>> }
>>
>> @@ -1851,6 +1871,49 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd,
>> return ret;
>> }
>>
>> +static int ov5640_set_framefmt(struct ov5640_dev *sensor,
>> + struct v4l2_mbus_framefmt *format)
>> +{
>> + int ret = 0;
>> + bool is_rgb = false;
>> + u8 val;
>> +
>> + switch (format->code) {
>> + case MEDIA_BUS_FMT_UYVY8_2X8:
>> + /* YUV422, UYVY */
>> + val = 0x3f;
>> + break;
>> + case MEDIA_BUS_FMT_YUYV8_2X8:
>> + /* YUV422, YUYV */
>> + val = 0x30;
>> + break;
>> + case MEDIA_BUS_FMT_RGB565_2X8_LE:
>> + /* RGB565 {g[2:0],b[4:0]},{r[4:0],g[5:3]} */
>> + val = 0x6F;
>> + is_rgb = true;
>> + break;
>> + case MEDIA_BUS_FMT_RGB565_2X8_BE:
>> + /* RGB565 {r[4:0],g[5:3]},{g[2:0],b[4:0]} */
>> + val = 0x61;
>> + is_rgb = true;
>> + break;
>> + default:
>> + return -EINVAL;
>> + }
>> +
>> + /* FORMAT CONTROL00: YUV and RGB formatting */
>> + ret = ov5640_write_reg(sensor, OV5640_REG_FORMAT_CONTROL00, val);
>> + if (ret)
>> + return ret;
>> +
>> + /* FORMAT MUX CONTROL: ISP YUV or RGB */
>> + ret = ov5640_write_reg(sensor, OV5640_REG_ISP_FORMAT_MUX_CTRL,
>> + is_rgb ? 0x01 : 0x00);
>
> return ov5640...;
>
OK.
>> + if (ret)
>> + return ret;
>> +
>> + return ret;
>> +}
>>
>> /*
>> * Sensor Controls.
>> @@ -2236,15 +2299,12 @@ static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
>> struct v4l2_subdev_pad_config *cfg,
>> struct v4l2_subdev_mbus_code_enum *code)
>> {
>> - struct ov5640_dev *sensor = to_ov5640_dev(sd);
>> -
>> if (code->pad != 0)
>> return -EINVAL;
>> - if (code->index != 0)
>> + if (code->index >= ARRAY_SIZE(ov5640_formats))
>> return -EINVAL;
>>
>> - code->code = sensor->fmt.code;
>> -
>> + code->code = ov5640_formats[code->index].code;
>> return 0;
>> }
>>
>> @@ -2254,12 +2314,15 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
>> int ret = 0;
>>
>> mutex_lock(&sensor->lock);
>> -
>
> I rather liked this newline!
>
OK.
>> if (sensor->streaming == !enable) {
>> if (enable && sensor->pending_mode_change) {
>> ret = ov5640_set_mode(sensor, sensor->current_mode);
>> if (ret)
>> goto out;
>> +
>> + ret = ov5640_set_framefmt(sensor, &sensor->fmt);
>> + if (ret)
>> + goto out;
>> }
>>
>> if (sensor->ep.bus_type == V4L2_MBUS_CSI2)
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v1 3/4] media: ov5640: add support of DVP parallel interface
2017-11-24 14:06 ` Sakari Ailus
@ 2017-11-28 16:07 ` Hugues FRUCHET
0 siblings, 0 replies; 9+ messages in thread
From: Hugues FRUCHET @ 2017-11-28 16:07 UTC (permalink / raw)
To: Sakari Ailus
Cc: Steve Longerbeam, Hans Verkuil, Mauro Carvalho Chehab,
linux-media, Benjamin Gaignard
Thanks Sakari for review,
On 11/24/2017 03:06 PM, Sakari Ailus wrote:
> Hi Hugues,
>
> On Thu, Nov 16, 2017 at 02:41:41PM +0100, Hugues Fruchet wrote:
>> @@ -2185,7 +2262,11 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
>> goto out;
>> }
>>
>> - ret = ov5640_set_stream(sensor, enable);
>> + if (sensor->ep.bus_type == V4L2_MBUS_CSI2)
>> + ret = ov5640_set_stream_mipi(sensor, enable);
>> + else
>> + ret = ov5640_set_stream_dvp(sensor);
>
> Hmm. Do you want to configure it even when you're disabling streaming?
>
I will fix this by only setting stream when enabling streaming.
Best regards,
Hugues.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2017-11-28 16:07 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-16 13:41 [PATCH v1 0/4] Add OV5640 parallel interface and RGB565/YUYV support Hugues Fruchet
2017-11-16 13:41 ` [PATCH v1 1/4] media: ov5640: switch to gpiod_set_value_cansleep() Hugues Fruchet
2017-11-16 13:41 ` [PATCH v1 2/4] media: ov5640: check chip id Hugues Fruchet
2017-11-16 13:41 ` [PATCH v1 3/4] media: ov5640: add support of DVP parallel interface Hugues Fruchet
2017-11-24 14:06 ` Sakari Ailus
2017-11-28 16:07 ` Hugues FRUCHET
2017-11-16 13:41 ` [PATCH v1 4/4] media: ov5640: add support of RGB565 and YUYV formats Hugues Fruchet
2017-11-24 14:09 ` Sakari Ailus
2017-11-28 15:39 ` Hugues FRUCHET
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).