All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/30]  media: ov5647: Support RaspberryPi Camera Module v1
@ 2020-11-19 16:19 Jacopo Mondi
  2020-11-19 16:19 ` [PATCH v4 01/30] dt-bindings: media: i2c: Rename ov5647.yaml Jacopo Mondi
                   ` (11 more replies)
  0 siblings, 12 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:19 UTC (permalink / raw)
  To: linux-media
  Cc: Jacopo Mondi, mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca

v3: https://patchwork.linuxtv.org/project/linux-media/list/?series=3813
v2: https://patchwork.linuxtv.org/project/linux-media/list/?series=3782
v1: https://patchwork.linuxtv.org/project/linux-media/list/?series=2765

Address Sakari's comments which lead to a substantial rebase and a rework
of set_pad_fmt()

Last patch which removes the 8-bit mode can be left out if the mode is
considered useful even if (locally) broken.

Compliance output is the same as v3.

Thanks
  j

Dave Stevenson (8):
  media: ov5647: Add support for PWDN GPIO.
  media: ov5647: Add support for non-continuous clock mode
  media: ov5647: Add set_fmt and get_fmt calls.
  media: ov5647: Add support for get_selection()
  media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag
  media: ov5647: Support V4L2_CID_PIXEL_RATE
  media: ov5647: Support V4L2_CID_VBLANK control
  media: ov5647: Advertise the correct exposure range

David Plowman (1):
  media: ov5647: Support gain, exposure and AWB controls

Jacopo Mondi (21):
  dt-bindings: media: i2c: Rename ov5647.yaml
  media: ov5647: Fix format initialization
  media: ov5647: Fix style issues
  media: ov5647: Replace license with SPDX identifier
  media: ov5647: Fix return value from read/write
  media: ov5647: Program mode at s_stream(1) time
  media: ov5647: Implement enum_frame_size()
  media: ov5647: Protect s_stream() with mutex
  media: ov5647: Rationalize driver structure name
  media: ov5647: Break out format handling
  media: ov5647: Rename SBGGR8 VGA mode
  media: ov5647: Add SGGBR10_1X10 modes
  media: ov5647: Use SBGGR10_1X10 640x480 as default
  media: ov5647: Implement set_fmt pad operation
  media: ov5647: Support V4L2_CID_HBLANK control
  media: ov5647: Use pm_runtime infrastructure
  media: ov5647: Rework s_stream() operation
  media: ov5647: Apply controls only when powered
  media: ov5647: Constify oe_enable/disable reglist
  media: ov5647: Support VIDIOC_SUBSCRIBE_EVENT
  media: ov5647: Remove 640x480 SBGGR8 mode

 .../i2c/{ov5647.yaml => ovti,ov5647.yaml}     |    0
 MAINTAINERS                                   |    2 +-
 drivers/media/i2c/ov5647.c                    | 1259 ++++++++++++++---
 3 files changed, 1051 insertions(+), 210 deletions(-)
 rename Documentation/devicetree/bindings/media/i2c/{ov5647.yaml => ovti,ov5647.yaml} (100%)

--
2.29.1


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v4 01/30] dt-bindings: media: i2c: Rename ov5647.yaml
  2020-11-19 16:19 [PATCH v4 00/30] media: ov5647: Support RaspberryPi Camera Module v1 Jacopo Mondi
@ 2020-11-19 16:19 ` Jacopo Mondi
  2020-11-25  9:15   ` Sakari Ailus
  2020-11-19 16:19 ` [PATCH v4 02/30] media: ov5647: Add support for PWDN GPIO Jacopo Mondi
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:19 UTC (permalink / raw)
  To: linux-media
  Cc: Jacopo Mondi, mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca

Rename 'ov5647.yaml' as 'ovti,ov5647.yaml' and update the
MAINTAINERS file entry accordingly.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 .../bindings/media/i2c/{ov5647.yaml => ovti,ov5647.yaml}        | 0
 MAINTAINERS                                                     | 2 +-
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename Documentation/devicetree/bindings/media/i2c/{ov5647.yaml => ovti,ov5647.yaml} (100%)

diff --git a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml
similarity index 100%
rename from Documentation/devicetree/bindings/media/i2c/ov5647.yaml
rename to Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml
diff --git a/MAINTAINERS b/MAINTAINERS
index 69d55ed67e1cf..3f2acc3a78687 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12928,7 +12928,7 @@ M:	Jacopo Mondi <jacopo@jmondi.org>
 L:	linux-media@vger.kernel.org
 S:	Maintained
 T:	git git://linuxtv.org/media_tree.git
-F:	Documentation/devicetree/bindings/media/i2c/ov5647.yaml
+F:	Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml
 F:	drivers/media/i2c/ov5647.c
 
 OMNIVISION OV5670 SENSOR DRIVER
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 02/30] media: ov5647: Add support for PWDN GPIO.
  2020-11-19 16:19 [PATCH v4 00/30] media: ov5647: Support RaspberryPi Camera Module v1 Jacopo Mondi
  2020-11-19 16:19 ` [PATCH v4 01/30] dt-bindings: media: i2c: Rename ov5647.yaml Jacopo Mondi
@ 2020-11-19 16:19 ` Jacopo Mondi
  2020-11-19 16:19 ` [PATCH v4 03/30] media: ov5647: Add support for non-continuous clock mode Jacopo Mondi
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:19 UTC (permalink / raw)
  To: linux-media
  Cc: Jacopo Mondi, mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca

From: Dave Stevenson <dave.stevenson@raspberrypi.org>

Add support for an optional GPIO connected to PWDN on the sensor. This
allows the use of hardware standby mode where internal device clock
and circuit activities are halted.

Please note that power is off when PWDN is high.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
Signed-off-by: Roman Kovalivskyi <roman.kovalivskyi@globallogic.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index e7d2e5b4ad4b9..5dde138763eb0 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -21,6 +21,7 @@
 
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/io.h>
@@ -35,6 +36,13 @@
 
 #define SENSOR_NAME "ov5647"
 
+/*
+ * From the datasheet, "20ms after PWDN goes low or 20ms after RESETB goes
+ * high if reset is inserted after PWDN goes high, host can access sensor's
+ * SCCB to initialize sensor."
+ */
+#define PWDN_ACTIVE_DELAY_MS	20
+
 #define MIPI_CTRL00_CLOCK_LANE_GATE		BIT(5)
 #define MIPI_CTRL00_BUS_IDLE			BIT(2)
 #define MIPI_CTRL00_CLOCK_LANE_DISABLE		BIT(0)
@@ -86,6 +94,7 @@ struct ov5647 {
 	unsigned int			height;
 	int				power_count;
 	struct clk			*xclk;
+	struct gpio_desc		*pwdn;
 };
 
 static inline struct ov5647 *to_state(struct v4l2_subdev *sd)
@@ -355,6 +364,11 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
 	if (on && !ov5647->power_count)	{
 		dev_dbg(&client->dev, "OV5647 power on\n");
 
+		if (ov5647->pwdn) {
+			gpiod_set_value_cansleep(ov5647->pwdn, 0);
+			msleep(PWDN_ACTIVE_DELAY_MS);
+		}
+
 		ret = clk_prepare_enable(ov5647->xclk);
 		if (ret < 0) {
 			dev_err(&client->dev, "clk prepare enable failed\n");
@@ -392,6 +406,8 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
 			dev_dbg(&client->dev, "soft stby failed\n");
 
 		clk_disable_unprepare(ov5647->xclk);
+
+		gpiod_set_value_cansleep(ov5647->pwdn, 1);
 	}
 
 	/* Update the power count. */
@@ -581,6 +597,14 @@ static int ov5647_probe(struct i2c_client *client)
 		return -EINVAL;
 	}
 
+	/* Request the power down GPIO asserted */
+	sensor->pwdn = devm_gpiod_get_optional(&client->dev, "pwdn",
+					       GPIOD_OUT_HIGH);
+	if (IS_ERR(sensor->pwdn)) {
+		dev_err(dev, "Failed to get 'pwdn' gpio\n");
+		return -EINVAL;
+	}
+
 	mutex_init(&sensor->lock);
 
 	sd = &sensor->sd;
@@ -594,7 +618,15 @@ static int ov5647_probe(struct i2c_client *client)
 	if (ret < 0)
 		goto mutex_remove;
 
+	if (sensor->pwdn) {
+		gpiod_set_value_cansleep(sensor->pwdn, 0);
+		msleep(PWDN_ACTIVE_DELAY_MS);
+	}
+
 	ret = ov5647_detect(sd);
+
+	gpiod_set_value_cansleep(sensor->pwdn, 1);
+
 	if (ret < 0)
 		goto error;
 
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 03/30] media: ov5647: Add support for non-continuous clock mode
  2020-11-19 16:19 [PATCH v4 00/30] media: ov5647: Support RaspberryPi Camera Module v1 Jacopo Mondi
  2020-11-19 16:19 ` [PATCH v4 01/30] dt-bindings: media: i2c: Rename ov5647.yaml Jacopo Mondi
  2020-11-19 16:19 ` [PATCH v4 02/30] media: ov5647: Add support for PWDN GPIO Jacopo Mondi
@ 2020-11-19 16:19 ` Jacopo Mondi
  2020-11-19 16:19 ` [PATCH v4 04/30] media: ov5647: Add set_fmt and get_fmt calls Jacopo Mondi
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:19 UTC (permalink / raw)
  To: linux-media
  Cc: Jacopo Mondi, mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca

From: Dave Stevenson <dave.stevenson@raspberrypi.org>

Add support for optional non-continuous clock mode to the ov5647
sensor driver.

Non-continuous clock saves a small amount of power and on some SoCs
is easier to interface with.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
Signed-off-by: Roman Kovalivskyi <roman.kovalivskyi@globallogic.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 5dde138763eb0..ccb56f9b09fd4 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -44,6 +44,7 @@
 #define PWDN_ACTIVE_DELAY_MS	20
 
 #define MIPI_CTRL00_CLOCK_LANE_GATE		BIT(5)
+#define MIPI_CTRL00_LINE_SYNC_ENABLE		BIT(4)
 #define MIPI_CTRL00_BUS_IDLE			BIT(2)
 #define MIPI_CTRL00_CLOCK_LANE_DISABLE		BIT(0)
 
@@ -95,6 +96,7 @@ struct ov5647 {
 	int				power_count;
 	struct clk			*xclk;
 	struct gpio_desc		*pwdn;
+	bool				clock_ncont;
 };
 
 static inline struct ov5647 *to_state(struct v4l2_subdev *sd)
@@ -269,9 +271,15 @@ static int ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel)
 
 static int ov5647_stream_on(struct v4l2_subdev *sd)
 {
+	struct ov5647 *ov5647 = to_state(sd);
+	u8 val = MIPI_CTRL00_BUS_IDLE;
 	int ret;
 
-	ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, MIPI_CTRL00_BUS_IDLE);
+	if (ov5647->clock_ncont)
+		val |= MIPI_CTRL00_CLOCK_LANE_GATE |
+		       MIPI_CTRL00_LINE_SYNC_ENABLE;
+
+	ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, val);
 	if (ret < 0)
 		return ret;
 
@@ -546,9 +554,11 @@ static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = {
 	.open = ov5647_open,
 };
 
-static int ov5647_parse_dt(struct device_node *np)
+static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np)
 {
-	struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
+	struct v4l2_fwnode_endpoint bus_cfg = {
+		.bus_type = V4L2_MBUS_CSI2_DPHY,
+	};
 	struct device_node *ep;
 
 	int ret;
@@ -558,7 +568,13 @@ static int ov5647_parse_dt(struct device_node *np)
 		return -EINVAL;
 
 	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &bus_cfg);
+	if (ret)
+		goto out;
 
+	sensor->clock_ncont = bus_cfg.bus.mipi_csi2.flags &
+			      V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
+
+out:
 	of_node_put(ep);
 	return ret;
 }
@@ -577,7 +593,7 @@ static int ov5647_probe(struct i2c_client *client)
 		return -ENOMEM;
 
 	if (IS_ENABLED(CONFIG_OF) && np) {
-		ret = ov5647_parse_dt(np);
+		ret = ov5647_parse_dt(sensor, np);
 		if (ret) {
 			dev_err(dev, "DT parsing error: %d\n", ret);
 			return ret;
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 04/30] media: ov5647: Add set_fmt and get_fmt calls.
  2020-11-19 16:19 [PATCH v4 00/30] media: ov5647: Support RaspberryPi Camera Module v1 Jacopo Mondi
                   ` (2 preceding siblings ...)
  2020-11-19 16:19 ` [PATCH v4 03/30] media: ov5647: Add support for non-continuous clock mode Jacopo Mondi
@ 2020-11-19 16:19 ` Jacopo Mondi
  2020-11-19 16:19 ` [PATCH v4 05/30] media: ov5647: Fix format initialization Jacopo Mondi
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:19 UTC (permalink / raw)
  To: linux-media
  Cc: Jacopo Mondi, mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca

From: Dave Stevenson <dave.stevenson@raspberrypi.org>

There's no way to query the subdevice for the supported
resolutions. Add set_fmt and get_fmt implementations. Since there's
only one format supported set_fmt does nothing and get returns single
format.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
Signed-off-by: Roman Kovalivskyi <roman.kovalivskyi@globallogic.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index ccb56f9b09fd4..9093a1ca7bce2 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -487,8 +487,27 @@ static int ov5647_enum_mbus_code(struct v4l2_subdev *sd,
 	return 0;
 }
 
+static int ov5647_set_get_fmt(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_pad_config *cfg,
+			      struct v4l2_subdev_format *format)
+{
+	struct v4l2_mbus_framefmt *fmt = &format->format;
+
+	/* Only one format is supported, so return that */
+	memset(fmt, 0, sizeof(*fmt));
+	fmt->code = MEDIA_BUS_FMT_SBGGR8_1X8;
+	fmt->colorspace = V4L2_COLORSPACE_SRGB;
+	fmt->field = V4L2_FIELD_NONE;
+	fmt->width = 640;
+	fmt->height = 480;
+
+	return 0;
+}
+
 static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = {
 	.enum_mbus_code = ov5647_enum_mbus_code,
+	.set_fmt =	  ov5647_set_get_fmt,
+	.get_fmt =	  ov5647_set_get_fmt,
 };
 
 static const struct v4l2_subdev_ops ov5647_subdev_ops = {
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 05/30] media: ov5647: Fix format initialization
  2020-11-19 16:19 [PATCH v4 00/30] media: ov5647: Support RaspberryPi Camera Module v1 Jacopo Mondi
                   ` (3 preceding siblings ...)
  2020-11-19 16:19 ` [PATCH v4 04/30] media: ov5647: Add set_fmt and get_fmt calls Jacopo Mondi
@ 2020-11-19 16:19 ` Jacopo Mondi
  2020-11-19 16:19 ` [PATCH v4 06/30] media: ov5647: Fix style issues Jacopo Mondi
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:19 UTC (permalink / raw)
  To: linux-media
  Cc: Jacopo Mondi, mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca

The driver currently support a single format. Fix its initialization to
use the only supported resolution.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 9093a1ca7bce2..04551ed683df3 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -560,9 +560,8 @@ static int ov5647_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 	crop->height = OV5647_WINDOW_HEIGHT_DEF;
 
 	format->code = MEDIA_BUS_FMT_SBGGR8_1X8;
-
-	format->width = OV5647_WINDOW_WIDTH_DEF;
-	format->height = OV5647_WINDOW_HEIGHT_DEF;
+	format->width = 640;
+	format->height = 480;
 	format->field = V4L2_FIELD_NONE;
 	format->colorspace = V4L2_COLORSPACE_SRGB;
 
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 06/30] media: ov5647: Fix style issues
  2020-11-19 16:19 [PATCH v4 00/30] media: ov5647: Support RaspberryPi Camera Module v1 Jacopo Mondi
                   ` (4 preceding siblings ...)
  2020-11-19 16:19 ` [PATCH v4 05/30] media: ov5647: Fix format initialization Jacopo Mondi
@ 2020-11-19 16:19 ` Jacopo Mondi
  2020-11-19 16:19 ` [PATCH v4 07/30] media: ov5647: Replace license with SPDX identifier Jacopo Mondi
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:19 UTC (permalink / raw)
  To: linux-media
  Cc: Jacopo Mondi, mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca

The driver has some obvious style issues which are worth fixing before
expanding the driver capabilities.

Fix:
- Variable declaration order
- Function parameters alignment
- Multi-line comments and spurious line breaks
- Use lowercase for hexadecimal values
- > 80 cols lines

Cosmetic change, no functional changes intended.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 102 +++++++++++++++++--------------------
 1 file changed, 47 insertions(+), 55 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 04551ed683df3..f8e982407ed6b 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -34,8 +34,6 @@
 #include <media/v4l2-image-sizes.h>
 #include <media/v4l2-mediabus.h>
 
-#define SENSOR_NAME "ov5647"
-
 /*
  * From the datasheet, "20ms after PWDN goes low or 20ms after RESETB goes
  * high if reset is inserted after PWDN goes high, host can access sensor's
@@ -50,9 +48,9 @@
 
 #define OV5647_SW_STANDBY		0x0100
 #define OV5647_SW_RESET			0x0103
-#define OV5647_REG_CHIPID_H		0x300A
-#define OV5647_REG_CHIPID_L		0x300B
-#define OV5640_REG_PAD_OUT		0x300D
+#define OV5647_REG_CHIPID_H		0x300a
+#define OV5647_REG_CHIPID_L		0x300b
+#define OV5640_REG_PAD_OUT		0x300d
 #define OV5647_REG_FRAME_OFF_NUMBER	0x4202
 #define OV5647_REG_MIPI_CTRL00		0x4800
 #define OV5647_REG_MIPI_CTRL14		0x4814
@@ -158,7 +156,7 @@ static struct regval_list ov5647_640x480[] = {
 	{0x3808, 0x02},
 	{0x3809, 0x80},
 	{0x380a, 0x01},
-	{0x380b, 0xE0},
+	{0x380b, 0xe0},
 	{0x3801, 0x00},
 	{0x3802, 0x00},
 	{0x3803, 0x00},
@@ -209,9 +207,9 @@ static struct regval_list ov5647_640x480[] = {
 
 static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val)
 {
-	int ret;
 	unsigned char data[3] = { reg >> 8, reg & 0xff, val};
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret;
 
 	ret = i2c_master_send(client, data, 3);
 	if (ret < 0)
@@ -223,9 +221,9 @@ static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val)
 
 static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val)
 {
-	int ret;
 	unsigned char data_w[2] = { reg >> 8, reg & 0xff };
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret;
 
 	ret = i2c_master_send(client, data_w, 2);
 	if (ret < 0) {
@@ -243,7 +241,7 @@ static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val)
 }
 
 static int ov5647_write_array(struct v4l2_subdev *sd,
-				struct regval_list *regs, int array_size)
+			      struct regval_list *regs, int array_size)
 {
 	int i, ret;
 
@@ -266,7 +264,9 @@ static int ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel)
 		return ret;
 
 	channel_id &= ~(3 << 6);
-	return ov5647_write(sd, OV5647_REG_MIPI_CTRL14, channel_id | (channel << 6));
+
+	return ov5647_write(sd, OV5647_REG_MIPI_CTRL14,
+			    channel_id | (channel << 6));
 }
 
 static int ov5647_stream_on(struct v4l2_subdev *sd)
@@ -294,8 +294,9 @@ static int ov5647_stream_off(struct v4l2_subdev *sd)
 {
 	int ret;
 
-	ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, MIPI_CTRL00_CLOCK_LANE_GATE
-			   | MIPI_CTRL00_BUS_IDLE | MIPI_CTRL00_CLOCK_LANE_DISABLE);
+	ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00,
+			   MIPI_CTRL00_CLOCK_LANE_GATE | MIPI_CTRL00_BUS_IDLE |
+			   MIPI_CTRL00_CLOCK_LANE_DISABLE);
 	if (ret < 0)
 		return ret;
 
@@ -325,16 +326,16 @@ static int set_sw_standby(struct v4l2_subdev *sd, bool standby)
 
 static int __sensor_init(struct v4l2_subdev *sd)
 {
-	int ret;
-	u8 resetval, rdval;
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u8 resetval, rdval;
+	int ret;
 
 	ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval);
 	if (ret < 0)
 		return ret;
 
 	ret = ov5647_write_array(sd, ov5647_640x480,
-					ARRAY_SIZE(ov5647_640x480));
+				 ARRAY_SIZE(ov5647_640x480));
 	if (ret < 0) {
 		dev_err(&client->dev, "write sensor default regs error\n");
 		return ret;
@@ -355,17 +356,15 @@ static int __sensor_init(struct v4l2_subdev *sd)
 			return ret;
 	}
 
-	/*
-	 * stream off to make the clock lane into LP-11 state.
-	 */
+	/* Stream off to make the clock lane into LP-11 state. */
 	return ov5647_stream_off(sd);
 }
 
 static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
 {
-	int ret = 0;
-	struct ov5647 *ov5647 = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ov5647 *ov5647 = to_state(sd);
+	int ret = 0;
 
 	mutex_lock(&ov5647->lock);
 
@@ -384,7 +383,7 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
 		}
 
 		ret = ov5647_write_array(sd, sensor_oe_enable_regs,
-				ARRAY_SIZE(sensor_oe_enable_regs));
+					 ARRAY_SIZE(sensor_oe_enable_regs));
 		if (ret < 0) {
 			clk_disable_unprepare(ov5647->xclk);
 			dev_err(&client->dev,
@@ -403,18 +402,15 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
 		dev_dbg(&client->dev, "OV5647 power off\n");
 
 		ret = ov5647_write_array(sd, sensor_oe_disable_regs,
-				ARRAY_SIZE(sensor_oe_disable_regs));
-
+					 ARRAY_SIZE(sensor_oe_disable_regs));
 		if (ret < 0)
 			dev_dbg(&client->dev, "disable oe failed\n");
 
 		ret = set_sw_standby(sd, true);
-
 		if (ret < 0)
 			dev_dbg(&client->dev, "soft stby failed\n");
 
 		clk_disable_unprepare(ov5647->xclk);
-
 		gpiod_set_value_cansleep(ov5647->pwdn, 1);
 	}
 
@@ -430,10 +426,10 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ov5647_sensor_get_register(struct v4l2_subdev *sd,
-				struct v4l2_dbg_register *reg)
+				      struct v4l2_dbg_register *reg)
 {
-	u8 val;
 	int ret;
+	u8 val;
 
 	ret = ov5647_read(sd, reg->reg & 0xff, &val);
 	if (ret < 0)
@@ -446,15 +442,13 @@ static int ov5647_sensor_get_register(struct v4l2_subdev *sd,
 }
 
 static int ov5647_sensor_set_register(struct v4l2_subdev *sd,
-				const struct v4l2_dbg_register *reg)
+				      const struct v4l2_dbg_register *reg)
 {
 	return ov5647_write(sd, reg->reg & 0xff, reg->val & 0xff);
 }
 #endif
 
-/*
- * Subdev core operations registration
- */
+/* Subdev core operations registration */
 static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = {
 	.s_power		= ov5647_sensor_power,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -476,8 +470,8 @@ static const struct v4l2_subdev_video_ops ov5647_subdev_video_ops = {
 };
 
 static int ov5647_enum_mbus_code(struct v4l2_subdev *sd,
-				struct v4l2_subdev_pad_config *cfg,
-				struct v4l2_subdev_mbus_code_enum *code)
+				 struct v4l2_subdev_pad_config *cfg,
+				 struct v4l2_subdev_mbus_code_enum *code)
 {
 	if (code->index > 0)
 		return -EINVAL;
@@ -493,7 +487,7 @@ static int ov5647_set_get_fmt(struct v4l2_subdev *sd,
 {
 	struct v4l2_mbus_framefmt *fmt = &format->format;
 
-	/* Only one format is supported, so return that */
+	/* Only one format is supported, so return that. */
 	memset(fmt, 0, sizeof(*fmt));
 	fmt->code = MEDIA_BUS_FMT_SBGGR8_1X8;
 	fmt->colorspace = V4L2_COLORSPACE_SRGB;
@@ -518,9 +512,9 @@ static const struct v4l2_subdev_ops ov5647_subdev_ops = {
 
 static int ov5647_detect(struct v4l2_subdev *sd)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	u8 read;
 	int ret;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
 	ret = ov5647_write(sd, OV5647_SW_RESET, 0x01);
 	if (ret < 0)
@@ -551,8 +545,7 @@ static int ov5647_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 {
 	struct v4l2_mbus_framefmt *format =
 				v4l2_subdev_get_try_format(sd, fh->pad, 0);
-	struct v4l2_rect *crop =
-				v4l2_subdev_get_try_crop(sd, fh->pad, 0);
+	struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, fh->pad, 0);
 
 	crop->left = OV5647_COLUMN_START_DEF;
 	crop->top = OV5647_ROW_START_DEF;
@@ -578,7 +571,6 @@ static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np)
 		.bus_type = V4L2_MBUS_CSI2_DPHY,
 	};
 	struct device_node *ep;
-
 	int ret;
 
 	ep = of_graph_get_next_endpoint(np, NULL);
@@ -594,17 +586,18 @@ static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np)
 
 out:
 	of_node_put(ep);
+
 	return ret;
 }
 
 static int ov5647_probe(struct i2c_client *client)
 {
+	struct device_node *np = client->dev.of_node;
 	struct device *dev = &client->dev;
 	struct ov5647 *sensor;
-	int ret;
 	struct v4l2_subdev *sd;
-	struct device_node *np = client->dev.of_node;
 	u32 xclk_freq;
+	int ret;
 
 	sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
 	if (!sensor)
@@ -618,7 +611,6 @@ static int ov5647_probe(struct i2c_client *client)
 		}
 	}
 
-	/* get system clock (xclk) */
 	sensor->xclk = devm_clk_get(dev, NULL);
 	if (IS_ERR(sensor->xclk)) {
 		dev_err(dev, "could not get xclk");
@@ -631,9 +623,8 @@ static int ov5647_probe(struct i2c_client *client)
 		return -EINVAL;
 	}
 
-	/* Request the power down GPIO asserted */
-	sensor->pwdn = devm_gpiod_get_optional(&client->dev, "pwdn",
-					       GPIOD_OUT_HIGH);
+	/* Request the power down GPIO asserted. */
+	sensor->pwdn = devm_gpiod_get_optional(dev, "pwdn", GPIOD_OUT_HIGH);
 	if (IS_ERR(sensor->pwdn)) {
 		dev_err(dev, "Failed to get 'pwdn' gpio\n");
 		return -EINVAL;
@@ -643,14 +634,14 @@ static int ov5647_probe(struct i2c_client *client)
 
 	sd = &sensor->sd;
 	v4l2_i2c_subdev_init(sd, client, &ov5647_subdev_ops);
-	sensor->sd.internal_ops = &ov5647_subdev_internal_ops;
-	sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	sd->internal_ops = &ov5647_subdev_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 
 	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
 	ret = media_entity_pads_init(&sd->entity, 1, &sensor->pad);
 	if (ret < 0)
-		goto mutex_remove;
+		goto mutex_destroy;
 
 	if (sensor->pwdn) {
 		gpiod_set_value_cansleep(sensor->pwdn, 0);
@@ -658,22 +649,23 @@ static int ov5647_probe(struct i2c_client *client)
 	}
 
 	ret = ov5647_detect(sd);
-
 	gpiod_set_value_cansleep(sensor->pwdn, 1);
-
 	if (ret < 0)
-		goto error;
+		goto entity_cleanup;
 
 	ret = v4l2_async_register_subdev(sd);
 	if (ret < 0)
-		goto error;
+		goto entity_cleanup;
 
 	dev_dbg(dev, "OmniVision OV5647 camera driver probed\n");
+
 	return 0;
-error:
+
+entity_cleanup:
 	media_entity_cleanup(&sd->entity);
-mutex_remove:
+mutex_destroy:
 	mutex_destroy(&sensor->lock);
+
 	return ret;
 }
 
@@ -692,7 +684,7 @@ static int ov5647_remove(struct i2c_client *client)
 
 static const struct i2c_device_id ov5647_id[] = {
 	{ "ov5647", 0 },
-	{ }
+	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(i2c, ov5647_id);
 
@@ -707,7 +699,7 @@ MODULE_DEVICE_TABLE(of, ov5647_of_match);
 static struct i2c_driver ov5647_driver = {
 	.driver = {
 		.of_match_table = of_match_ptr(ov5647_of_match),
-		.name	= SENSOR_NAME,
+		.name	= "ov5647",
 	},
 	.probe_new	= ov5647_probe,
 	.remove		= ov5647_remove,
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 07/30] media: ov5647: Replace license with SPDX identifier
  2020-11-19 16:19 [PATCH v4 00/30] media: ov5647: Support RaspberryPi Camera Module v1 Jacopo Mondi
                   ` (5 preceding siblings ...)
  2020-11-19 16:19 ` [PATCH v4 06/30] media: ov5647: Fix style issues Jacopo Mondi
@ 2020-11-19 16:19 ` Jacopo Mondi
  2020-11-19 16:19 ` [PATCH v4 08/30] media: ov5647: Fix return value from read/write Jacopo Mondi
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:19 UTC (permalink / raw)
  To: linux-media
  Cc: Jacopo Mondi, mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca

Replace the boilerplate license text with the SPDX identifier.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index f8e982407ed6b..5c5449c42edf6 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * A V4L2 driver for OmniVision OV5647 cameras.
  *
@@ -8,15 +9,6 @@
  * Copyright (C) 2006-7 Jonathan Corbet <corbet@lwn.net>
  *
  * Copyright (C) 2016, Synopsys, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/clk.h>
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 08/30] media: ov5647: Fix return value from read/write
  2020-11-19 16:19 [PATCH v4 00/30] media: ov5647: Support RaspberryPi Camera Module v1 Jacopo Mondi
                   ` (6 preceding siblings ...)
  2020-11-19 16:19 ` [PATCH v4 07/30] media: ov5647: Replace license with SPDX identifier Jacopo Mondi
@ 2020-11-19 16:19 ` Jacopo Mondi
  2020-11-19 16:19 ` [PATCH v4 09/30] media: ov5647: Program mode at s_stream(1) time Jacopo Mondi
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:19 UTC (permalink / raw)
  To: linux-media
  Cc: Jacopo Mondi, mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca

The ov5647_read()/ov5647_write() return in case of success the number
of bytes read or written respectively. This requires callers to check
if the return value is less than zero to detect an error. Unfortunately,
in several places, callers directly return the result of a read/write
call, causing issues when the returned valued is checked to be different
from zero to detect an error.

Fix this by returning zero if i2c_master_send() and i2c_master_read()
return a positive value (the number of bytes written or read).

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 5c5449c42edf6..79ac8c76baeac 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -204,11 +204,13 @@ static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val)
 	int ret;
 
 	ret = i2c_master_send(client, data, 3);
-	if (ret < 0)
+	if (ret < 0) {
 		dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
 				__func__, reg);
+		return ret;
+	}
 
-	return ret;
+	return 0;
 }
 
 static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val)
@@ -225,11 +227,13 @@ static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val)
 	}
 
 	ret = i2c_master_recv(client, val, 1);
-	if (ret < 0)
+	if (ret < 0) {
 		dev_dbg(&client->dev, "%s: i2c read error, reg: %x\n",
 				__func__, reg);
+		return ret;
+	}
 
-	return ret;
+	return 0;
 }
 
 static int ov5647_write_array(struct v4l2_subdev *sd,
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 09/30] media: ov5647: Program mode at s_stream(1) time
  2020-11-19 16:19 [PATCH v4 00/30] media: ov5647: Support RaspberryPi Camera Module v1 Jacopo Mondi
                   ` (7 preceding siblings ...)
  2020-11-19 16:19 ` [PATCH v4 08/30] media: ov5647: Fix return value from read/write Jacopo Mondi
@ 2020-11-19 16:19 ` Jacopo Mondi
  2020-11-19 16:32 ` [PATCH v4 10/30] media: ov5647: Implement enum_frame_size() Jacopo Mondi
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:19 UTC (permalink / raw)
  To: linux-media
  Cc: Jacopo Mondi, mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca

Rename __sensor_init() function to ov5647_set_mode() as the function
is a regular one and the double underscores prefix shall be removed, and
then move it to program the mode at s_stream(1) time, not at sensor power
up.

Break out from __sensor_init() the stream_off() operation call at sensor
power up to coax the lanes in LP-11 state.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 81 +++++++++++++++++++++-----------------
 1 file changed, 44 insertions(+), 37 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 79ac8c76baeac..ad3397881c9a5 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -265,12 +265,54 @@ static int ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel)
 			    channel_id | (channel << 6));
 }
 
+static int ov5647_set_mode(struct v4l2_subdev *sd)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u8 resetval, rdval;
+	int ret;
+
+	ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval);
+	if (ret < 0)
+		return ret;
+
+	ret = ov5647_write_array(sd, ov5647_640x480,
+				 ARRAY_SIZE(ov5647_640x480));
+	if (ret < 0) {
+		dev_err(&client->dev, "write sensor default regs error\n");
+		return ret;
+	}
+
+	ret = ov5647_set_virtual_channel(sd, 0);
+	if (ret < 0)
+		return ret;
+
+	ret = ov5647_read(sd, OV5647_SW_STANDBY, &resetval);
+	if (ret < 0)
+		return ret;
+
+	if (!(resetval & 0x01)) {
+		dev_err(&client->dev, "Device was in SW standby");
+		ret = ov5647_write(sd, OV5647_SW_STANDBY, 0x01);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
 static int ov5647_stream_on(struct v4l2_subdev *sd)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct ov5647 *ov5647 = to_state(sd);
 	u8 val = MIPI_CTRL00_BUS_IDLE;
 	int ret;
 
+	ret = ov5647_set_mode(sd);
+	if (ret) {
+		dev_err(&client->dev, "Failed to program sensor mode: %d\n", ret);
+		return ret;
+	}
+
 	if (ov5647->clock_ncont)
 		val |= MIPI_CTRL00_CLOCK_LANE_GATE |
 		       MIPI_CTRL00_LINE_SYNC_ENABLE;
@@ -320,42 +362,6 @@ static int set_sw_standby(struct v4l2_subdev *sd, bool standby)
 	return ov5647_write(sd, OV5647_SW_STANDBY, rdval);
 }
 
-static int __sensor_init(struct v4l2_subdev *sd)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	u8 resetval, rdval;
-	int ret;
-
-	ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval);
-	if (ret < 0)
-		return ret;
-
-	ret = ov5647_write_array(sd, ov5647_640x480,
-				 ARRAY_SIZE(ov5647_640x480));
-	if (ret < 0) {
-		dev_err(&client->dev, "write sensor default regs error\n");
-		return ret;
-	}
-
-	ret = ov5647_set_virtual_channel(sd, 0);
-	if (ret < 0)
-		return ret;
-
-	ret = ov5647_read(sd, OV5647_SW_STANDBY, &resetval);
-	if (ret < 0)
-		return ret;
-
-	if (!(resetval & 0x01)) {
-		dev_err(&client->dev, "Device was in SW standby");
-		ret = ov5647_write(sd, OV5647_SW_STANDBY, 0x01);
-		if (ret < 0)
-			return ret;
-	}
-
-	/* Stream off to make the clock lane into LP-11 state. */
-	return ov5647_stream_off(sd);
-}
-
 static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -387,7 +393,8 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
 			goto out;
 		}
 
-		ret = __sensor_init(sd);
+		/* Stream off to coax lanes into LP-11 state. */
+		ret = ov5647_stream_off(sd);
 		if (ret < 0) {
 			clk_disable_unprepare(ov5647->xclk);
 			dev_err(&client->dev,
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 10/30] media: ov5647: Implement enum_frame_size()
  2020-11-19 16:19 [PATCH v4 00/30] media: ov5647: Support RaspberryPi Camera Module v1 Jacopo Mondi
                   ` (8 preceding siblings ...)
  2020-11-19 16:19 ` [PATCH v4 09/30] media: ov5647: Program mode at s_stream(1) time Jacopo Mondi
@ 2020-11-19 16:32 ` Jacopo Mondi
  2020-11-19 16:32   ` [PATCH v4 11/30] media: ov5647: Protect s_stream() with mutex Jacopo Mondi
                     ` (8 more replies)
  2020-11-19 16:35 ` [PATCH v4 20/30] media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag Jacopo Mondi
  2020-11-19 16:37 ` [PATCH v4 30/30] media: ov5647: Remove 640x480 SBGGR8 mode Jacopo Mondi
  11 siblings, 9 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:32 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

Implement the .enum_frame_size subdev pad operation.

As the driver only supports one format and one resolution at the moment
the implementation is trivial.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index ad3397881c9a5..2e7a6cb396890 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -484,6 +484,24 @@ static int ov5647_enum_mbus_code(struct v4l2_subdev *sd,
 	return 0;
 }
 
+static int ov5647_enum_frame_size(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->index)
+		return -EINVAL;
+
+	if (fse->code != MEDIA_BUS_FMT_SBGGR8_1X8)
+		return -EINVAL;
+
+	fse->min_width = 640;
+	fse->max_width = 640;
+	fse->min_height = 480;
+	fse->max_height = 480;
+
+	return 0;
+}
+
 static int ov5647_set_get_fmt(struct v4l2_subdev *sd,
 			      struct v4l2_subdev_pad_config *cfg,
 			      struct v4l2_subdev_format *format)
@@ -502,9 +520,10 @@ static int ov5647_set_get_fmt(struct v4l2_subdev *sd,
 }
 
 static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = {
-	.enum_mbus_code = ov5647_enum_mbus_code,
-	.set_fmt =	  ov5647_set_get_fmt,
-	.get_fmt =	  ov5647_set_get_fmt,
+	.enum_mbus_code		= ov5647_enum_mbus_code,
+	.enum_frame_size	= ov5647_enum_frame_size,
+	.set_fmt		= ov5647_set_get_fmt,
+	.get_fmt		= ov5647_set_get_fmt,
 };
 
 static const struct v4l2_subdev_ops ov5647_subdev_ops = {
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 11/30] media: ov5647: Protect s_stream() with mutex
  2020-11-19 16:32 ` [PATCH v4 10/30] media: ov5647: Implement enum_frame_size() Jacopo Mondi
@ 2020-11-19 16:32   ` Jacopo Mondi
  2020-11-19 16:32   ` [PATCH v4 12/30] media: ov5647: Support gain, exposure and AWB controls Jacopo Mondi
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:32 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

Use the driver mutex to protect s_stream() operations.
This will become more relevant once the sensor will support more formats
and set_format() could be issue concurrently to s_stream().

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 2e7a6cb396890..69a5e25dcd707 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -462,10 +462,17 @@ static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = {
 
 static int ov5647_s_stream(struct v4l2_subdev *sd, int enable)
 {
+	struct ov5647 *sensor = to_state(sd);
+	int ret;
+
+	mutex_lock(&sensor->lock);
 	if (enable)
-		return ov5647_stream_on(sd);
+		ret = ov5647_stream_on(sd);
 	else
-		return ov5647_stream_off(sd);
+		ret = ov5647_stream_off(sd);
+	mutex_unlock(&sensor->lock);
+
+	return ret;
 }
 
 static const struct v4l2_subdev_video_ops ov5647_subdev_video_ops = {
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 12/30] media: ov5647: Support gain, exposure and AWB controls
  2020-11-19 16:32 ` [PATCH v4 10/30] media: ov5647: Implement enum_frame_size() Jacopo Mondi
  2020-11-19 16:32   ` [PATCH v4 11/30] media: ov5647: Protect s_stream() with mutex Jacopo Mondi
@ 2020-11-19 16:32   ` Jacopo Mondi
  2020-11-19 16:32   ` [PATCH v4 13/30] media: ov5647: Rationalize driver structure name Jacopo Mondi
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:32 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, David Plowman, Jacopo Mondi

From: David Plowman <david.plowman@raspberrypi.com>

Add controls to support AWB, AEC and AGC. Also add control support to
set exposure (in lines) and analogue gain (as a register code).

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 172 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 170 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 69a5e25dcd707..9ad1e3004ff18 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -21,6 +21,7 @@
 #include <linux/of_graph.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-image-sizes.h>
@@ -43,9 +44,16 @@
 #define OV5647_REG_CHIPID_H		0x300a
 #define OV5647_REG_CHIPID_L		0x300b
 #define OV5640_REG_PAD_OUT		0x300d
+#define OV5647_REG_EXP_HI		0x3500
+#define OV5647_REG_EXP_MID		0x3501
+#define OV5647_REG_EXP_LO		0x3502
+#define OV5647_REG_AEC_AGC		0x3503
+#define OV5647_REG_GAIN_HI		0x350a
+#define OV5647_REG_GAIN_LO		0x350b
 #define OV5647_REG_FRAME_OFF_NUMBER	0x4202
 #define OV5647_REG_MIPI_CTRL00		0x4800
 #define OV5647_REG_MIPI_CTRL14		0x4814
+#define OV5647_REG_AWB			0x5001
 
 #define REG_TERM 0xfffe
 #define VAL_TERM 0xfe
@@ -87,6 +95,7 @@ struct ov5647 {
 	struct clk			*xclk;
 	struct gpio_desc		*pwdn;
 	bool				clock_ncont;
+	struct v4l2_ctrl_handler	ctrls;
 };
 
 static inline struct ov5647 *to_state(struct v4l2_subdev *sd)
@@ -121,7 +130,6 @@ static struct regval_list ov5647_640x480[] = {
 	{0x3612, 0x59},
 	{0x3618, 0x00},
 	{0x5000, 0x06},
-	{0x5001, 0x01},
 	{0x5002, 0x41},
 	{0x5003, 0x08},
 	{0x5a00, 0x08},
@@ -313,6 +321,11 @@ static int ov5647_stream_on(struct v4l2_subdev *sd)
 		return ret;
 	}
 
+	/* Apply customized values from user when stream starts. */
+	ret =  __v4l2_ctrl_handler_setup(sd->ctrl_handler);
+	if (ret)
+		return ret;
+
 	if (ov5647->clock_ncont)
 		val |= MIPI_CTRL00_CLOCK_LANE_GATE |
 		       MIPI_CTRL00_LINE_SYNC_ENABLE;
@@ -594,6 +607,154 @@ static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = {
 	.open = ov5647_open,
 };
 
+static int ov5647_s_auto_white_balance(struct v4l2_subdev *sd, u32 val)
+{
+	return ov5647_write(sd, OV5647_REG_AWB, val ? 1 : 0);
+}
+
+static int ov5647_s_autogain(struct v4l2_subdev *sd, u32 val)
+{
+	int ret;
+	u8 reg;
+
+	/* Non-zero turns on AGC by clearing bit 1.*/
+	ret = ov5647_read(sd, OV5647_REG_AEC_AGC, &reg);
+	if (ret)
+		return ret;
+
+	return ov5647_write(sd, OV5647_REG_AEC_AGC, val ? reg & ~BIT(1)
+							: reg | BIT(1));
+}
+
+static int ov5647_s_exposure_auto(struct v4l2_subdev *sd, u32 val)
+{
+	int ret;
+	u8 reg;
+
+	/*
+	 * Everything except V4L2_EXPOSURE_MANUAL turns on AEC by
+	 * clearing bit 0.
+	 */
+	ret = ov5647_read(sd, OV5647_REG_AEC_AGC, &reg);
+	if (ret)
+		return ret;
+
+	return ov5647_write(sd, OV5647_REG_AEC_AGC,
+			    val == V4L2_EXPOSURE_MANUAL ? reg | BIT(0)
+							: reg & ~BIT(0));
+}
+
+static int ov5647_s_analogue_gain(struct v4l2_subdev *sd, u32 val)
+{
+	int ret;
+
+	/* 10 bits of gain, 2 in the high register. */
+	ret = ov5647_write(sd, OV5647_REG_GAIN_HI, (val >> 8) & 3);
+	if (ret)
+		return ret;
+
+	return ov5647_write(sd, OV5647_REG_GAIN_LO, val & 0xff);
+}
+
+static int ov5647_s_exposure(struct v4l2_subdev *sd, u32 val)
+{
+	int ret;
+
+	/*
+	 * Sensor has 20 bits, but the bottom 4 bits are fractions of a line
+	 * which we leave as zero (and don't receive in "val").
+	 */
+	ret = ov5647_write(sd, OV5647_REG_EXP_HI, (val >> 12) & 0xf);
+	if (ret)
+		return ret;
+
+	ret = ov5647_write(sd, OV5647_REG_EXP_MID, (val >> 4) & 0xff);
+	if (ret)
+		return ret;
+
+	return ov5647_write(sd, OV5647_REG_EXP_LO, (val & 0xf) << 4);
+}
+
+static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ov5647 *sensor = container_of(ctrl->handler,
+					    struct ov5647, ctrls);
+	struct v4l2_subdev *sd = &sensor->sd;
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	/* v4l2_ctrl_lock() locks our own mutex */
+
+	/*
+	 * If the device is not powered up by the host driver do
+	 * not apply any controls to H/W at this time. Instead
+	 * the controls will be restored at s_stream(1) time.
+	 */
+	if (!sensor->power_count)
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUTO_WHITE_BALANCE:
+		return ov5647_s_auto_white_balance(sd, ctrl->val);
+	case V4L2_CID_AUTOGAIN:
+		return ov5647_s_autogain(sd, ctrl->val);
+	case V4L2_CID_EXPOSURE_AUTO:
+		return ov5647_s_exposure_auto(sd, ctrl->val);
+	case V4L2_CID_ANALOGUE_GAIN:
+		return  ov5647_s_analogue_gain(sd, ctrl->val);
+	case V4L2_CID_EXPOSURE:
+		return ov5647_s_exposure(sd, ctrl->val);
+	default:
+		dev_info(&client->dev,
+			 "Control (id:0x%x, val:0x%x) not supported\n",
+			 ctrl->id, ctrl->val);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops ov5647_ctrl_ops = {
+	.s_ctrl = ov5647_s_ctrl,
+};
+
+static int ov5647_init_controls(struct ov5647 *sensor)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
+
+	v4l2_ctrl_handler_init(&sensor->ctrls, 5);
+
+	v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
+			  V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
+
+	v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
+			  V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 0);
+
+	v4l2_ctrl_new_std_menu(&sensor->ctrls, &ov5647_ctrl_ops,
+			       V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL,
+			       0, V4L2_EXPOSURE_MANUAL);
+
+	/* min: 4 lines; max: 0xffff lines; default: 1000 lines. */
+	v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
+			  V4L2_CID_EXPOSURE, 4, 65535, 1, 1000);
+
+	/* min: 16 = 1.0x; max (10 bits); default: 32 = 2.0x. */
+	v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
+			  V4L2_CID_ANALOGUE_GAIN, 16, 1023, 1, 32);
+
+	if (sensor->ctrls.error) {
+		dev_err(&client->dev,
+			"%s Controls initialization failed (%d)\n",
+			__func__, sensor->ctrls.error);
+		v4l2_ctrl_handler_free(&sensor->ctrls);
+
+		return sensor->ctrls.error;
+	}
+
+	sensor->sd.ctrl_handler = &sensor->ctrls;
+
+	return 0;
+}
+
 static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np)
 {
 	struct v4l2_fwnode_endpoint bus_cfg = {
@@ -661,6 +822,10 @@ static int ov5647_probe(struct i2c_client *client)
 
 	mutex_init(&sensor->lock);
 
+	ret = ov5647_init_controls(sensor);
+	if (ret)
+		goto mutex_destroy;
+
 	sd = &sensor->sd;
 	v4l2_i2c_subdev_init(sd, client, &ov5647_subdev_ops);
 	sd->internal_ops = &ov5647_subdev_internal_ops;
@@ -670,7 +835,7 @@ static int ov5647_probe(struct i2c_client *client)
 	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
 	ret = media_entity_pads_init(&sd->entity, 1, &sensor->pad);
 	if (ret < 0)
-		goto mutex_destroy;
+		goto ctrl_handler_free;
 
 	if (sensor->pwdn) {
 		gpiod_set_value_cansleep(sensor->pwdn, 0);
@@ -692,6 +857,8 @@ static int ov5647_probe(struct i2c_client *client)
 
 entity_cleanup:
 	media_entity_cleanup(&sd->entity);
+ctrl_handler_free:
+	v4l2_ctrl_handler_free(&sensor->ctrls);
 mutex_destroy:
 	mutex_destroy(&sensor->lock);
 
@@ -705,6 +872,7 @@ static int ov5647_remove(struct i2c_client *client)
 
 	v4l2_async_unregister_subdev(&ov5647->sd);
 	media_entity_cleanup(&ov5647->sd.entity);
+	v4l2_ctrl_handler_free(&ov5647->ctrls);
 	v4l2_device_unregister_subdev(sd);
 	mutex_destroy(&ov5647->lock);
 
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 13/30] media: ov5647: Rationalize driver structure name
  2020-11-19 16:32 ` [PATCH v4 10/30] media: ov5647: Implement enum_frame_size() Jacopo Mondi
  2020-11-19 16:32   ` [PATCH v4 11/30] media: ov5647: Protect s_stream() with mutex Jacopo Mondi
  2020-11-19 16:32   ` [PATCH v4 12/30] media: ov5647: Support gain, exposure and AWB controls Jacopo Mondi
@ 2020-11-19 16:32   ` Jacopo Mondi
  2020-11-19 16:32   ` [PATCH v4 14/30] media: ov5647: Break out format handling Jacopo Mondi
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:32 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

The driver structure name is referred to with different names ('ov5647',
'state', 'sensor') in different functions in the driver.

Polish this up by using 'struct ov5647 *sensor' everywhere.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 46 +++++++++++++++++++-------------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 9ad1e3004ff18..4c134865cd68d 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -98,7 +98,7 @@ struct ov5647 {
 	struct v4l2_ctrl_handler	ctrls;
 };
 
-static inline struct ov5647 *to_state(struct v4l2_subdev *sd)
+static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd)
 {
 	return container_of(sd, struct ov5647, sd);
 }
@@ -311,7 +311,7 @@ static int ov5647_set_mode(struct v4l2_subdev *sd)
 static int ov5647_stream_on(struct v4l2_subdev *sd)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct ov5647 *ov5647 = to_state(sd);
+	struct ov5647 *sensor = to_sensor(sd);
 	u8 val = MIPI_CTRL00_BUS_IDLE;
 	int ret;
 
@@ -326,7 +326,7 @@ static int ov5647_stream_on(struct v4l2_subdev *sd)
 	if (ret)
 		return ret;
 
-	if (ov5647->clock_ncont)
+	if (sensor->clock_ncont)
 		val |= MIPI_CTRL00_CLOCK_LANE_GATE |
 		       MIPI_CTRL00_LINE_SYNC_ENABLE;
 
@@ -378,20 +378,20 @@ static int set_sw_standby(struct v4l2_subdev *sd, bool standby)
 static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct ov5647 *ov5647 = to_state(sd);
+	struct ov5647 *sensor = to_sensor(sd);
 	int ret = 0;
 
-	mutex_lock(&ov5647->lock);
+	mutex_lock(&sensor->lock);
 
-	if (on && !ov5647->power_count)	{
+	if (on && !sensor->power_count)	{
 		dev_dbg(&client->dev, "OV5647 power on\n");
 
-		if (ov5647->pwdn) {
-			gpiod_set_value_cansleep(ov5647->pwdn, 0);
+		if (sensor->pwdn) {
+			gpiod_set_value_cansleep(sensor->pwdn, 0);
 			msleep(PWDN_ACTIVE_DELAY_MS);
 		}
 
-		ret = clk_prepare_enable(ov5647->xclk);
+		ret = clk_prepare_enable(sensor->xclk);
 		if (ret < 0) {
 			dev_err(&client->dev, "clk prepare enable failed\n");
 			goto out;
@@ -400,7 +400,7 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
 		ret = ov5647_write_array(sd, sensor_oe_enable_regs,
 					 ARRAY_SIZE(sensor_oe_enable_regs));
 		if (ret < 0) {
-			clk_disable_unprepare(ov5647->xclk);
+			clk_disable_unprepare(sensor->xclk);
 			dev_err(&client->dev,
 				"write sensor_oe_enable_regs error\n");
 			goto out;
@@ -409,12 +409,12 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
 		/* Stream off to coax lanes into LP-11 state. */
 		ret = ov5647_stream_off(sd);
 		if (ret < 0) {
-			clk_disable_unprepare(ov5647->xclk);
+			clk_disable_unprepare(sensor->xclk);
 			dev_err(&client->dev,
 				"Camera not available, check Power\n");
 			goto out;
 		}
-	} else if (!on && ov5647->power_count == 1) {
+	} else if (!on && sensor->power_count == 1) {
 		dev_dbg(&client->dev, "OV5647 power off\n");
 
 		ret = ov5647_write_array(sd, sensor_oe_disable_regs,
@@ -426,16 +426,16 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
 		if (ret < 0)
 			dev_dbg(&client->dev, "soft stby failed\n");
 
-		clk_disable_unprepare(ov5647->xclk);
-		gpiod_set_value_cansleep(ov5647->pwdn, 1);
+		clk_disable_unprepare(sensor->xclk);
+		gpiod_set_value_cansleep(sensor->pwdn, 1);
 	}
 
 	/* Update the power count. */
-	ov5647->power_count += on ? 1 : -1;
-	WARN_ON(ov5647->power_count < 0);
+	sensor->power_count += on ? 1 : -1;
+	WARN_ON(sensor->power_count < 0);
 
 out:
-	mutex_unlock(&ov5647->lock);
+	mutex_unlock(&sensor->lock);
 
 	return ret;
 }
@@ -475,7 +475,7 @@ static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = {
 
 static int ov5647_s_stream(struct v4l2_subdev *sd, int enable)
 {
-	struct ov5647 *sensor = to_state(sd);
+	struct ov5647 *sensor = to_sensor(sd);
 	int ret;
 
 	mutex_lock(&sensor->lock);
@@ -868,13 +868,13 @@ static int ov5647_probe(struct i2c_client *client)
 static int ov5647_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct ov5647 *ov5647 = to_state(sd);
+	struct ov5647 *sensor = to_sensor(sd);
 
-	v4l2_async_unregister_subdev(&ov5647->sd);
-	media_entity_cleanup(&ov5647->sd.entity);
-	v4l2_ctrl_handler_free(&ov5647->ctrls);
+	v4l2_async_unregister_subdev(&sensor->sd);
+	media_entity_cleanup(&sensor->sd.entity);
+	v4l2_ctrl_handler_free(&sensor->ctrls);
 	v4l2_device_unregister_subdev(sd);
-	mutex_destroy(&ov5647->lock);
+	mutex_destroy(&sensor->lock);
 
 	return 0;
 }
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 14/30] media: ov5647: Break out format handling
  2020-11-19 16:32 ` [PATCH v4 10/30] media: ov5647: Implement enum_frame_size() Jacopo Mondi
                     ` (2 preceding siblings ...)
  2020-11-19 16:32   ` [PATCH v4 13/30] media: ov5647: Rationalize driver structure name Jacopo Mondi
@ 2020-11-19 16:32   ` Jacopo Mondi
  2020-11-19 16:32   ` [PATCH v4 15/30] media: ov5647: Add support for get_selection() Jacopo Mondi
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:32 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

Break format handling out from the main driver structure.

This commit prepares for the introduction of more sensor formats and
resolutions by instrumenting the existing operation to work on multiple
modes instead of assuming a single supported one.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 91 +++++++++++++++++++++++++++-----------
 1 file changed, 65 insertions(+), 26 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 4c134865cd68d..9a6766410e0ee 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -84,18 +84,28 @@ struct regval_list {
 	u8 data;
 };
 
+struct ov5647_mode {
+	struct v4l2_mbus_framefmt	format;
+	const struct regval_list	*reg_list;
+	unsigned int			num_regs;
+};
+
+struct ov5647_format_list {
+	unsigned int			mbus_code;
+	const struct ov5647_mode	*modes;
+	unsigned int			num_modes;
+};
+
 struct ov5647 {
 	struct v4l2_subdev		sd;
 	struct media_pad		pad;
 	struct mutex			lock;
-	struct v4l2_mbus_framefmt	format;
-	unsigned int			width;
-	unsigned int			height;
 	int				power_count;
 	struct clk			*xclk;
 	struct gpio_desc		*pwdn;
 	bool				clock_ncont;
 	struct v4l2_ctrl_handler	ctrls;
+	const struct ov5647_mode	*mode;
 };
 
 static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd)
@@ -115,7 +125,7 @@ static struct regval_list sensor_oe_enable_regs[] = {
 	{0x3002, 0xe4},
 };
 
-static struct regval_list ov5647_640x480[] = {
+static const struct regval_list ov5647_640x480[] = {
 	{0x0100, 0x00},
 	{0x0103, 0x01},
 	{0x3034, 0x08},
@@ -205,6 +215,33 @@ static struct regval_list ov5647_640x480[] = {
 	{0x0100, 0x01},
 };
 
+static const struct ov5647_mode ov5647_8bit_modes[] = {
+	{
+		.format	= {
+			.code		= MEDIA_BUS_FMT_SBGGR8_1X8,
+			.colorspace	= V4L2_COLORSPACE_SRGB,
+			.field		= V4L2_FIELD_NONE,
+			.width		= 640,
+			.height		= 480
+		},
+		.reg_list	= ov5647_640x480,
+		.num_regs	= ARRAY_SIZE(ov5647_640x480)
+	},
+};
+
+static const struct ov5647_format_list ov5647_formats[] = {
+	{
+		.mbus_code	= MEDIA_BUS_FMT_SBGGR8_1X8,
+		.modes		= ov5647_8bit_modes,
+		.num_modes	= ARRAY_SIZE(ov5647_8bit_modes),
+	},
+};
+
+#define OV5647_NUM_FORMATS	(ARRAY_SIZE(ov5647_formats))
+
+#define OV5647_DEFAULT_MODE	(&ov5647_formats[0].modes[0])
+#define OV5647_DEFAULT_FORMAT	(ov5647_formats[0].modes[0].format)
+
 static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val)
 {
 	unsigned char data[3] = { reg >> 8, reg & 0xff, val};
@@ -245,7 +282,7 @@ static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val)
 }
 
 static int ov5647_write_array(struct v4l2_subdev *sd,
-			      struct regval_list *regs, int array_size)
+			      const struct regval_list *regs, int array_size)
 {
 	int i, ret;
 
@@ -276,6 +313,7 @@ static int ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel)
 static int ov5647_set_mode(struct v4l2_subdev *sd)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ov5647 *sensor = to_sensor(sd);
 	u8 resetval, rdval;
 	int ret;
 
@@ -283,8 +321,8 @@ static int ov5647_set_mode(struct v4l2_subdev *sd)
 	if (ret < 0)
 		return ret;
 
-	ret = ov5647_write_array(sd, ov5647_640x480,
-				 ARRAY_SIZE(ov5647_640x480));
+	ret = ov5647_write_array(sd, sensor->mode->reg_list,
+				 sensor->mode->num_regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "write sensor default regs error\n");
 		return ret;
@@ -496,10 +534,10 @@ static int ov5647_enum_mbus_code(struct v4l2_subdev *sd,
 				 struct v4l2_subdev_pad_config *cfg,
 				 struct v4l2_subdev_mbus_code_enum *code)
 {
-	if (code->index > 0)
+	if (code->index >= OV5647_NUM_FORMATS)
 		return -EINVAL;
 
-	code->code = MEDIA_BUS_FMT_SBGGR8_1X8;
+	code->code = ov5647_formats[code->index].mbus_code;
 
 	return 0;
 }
@@ -508,16 +546,24 @@ static int ov5647_enum_frame_size(struct v4l2_subdev *sd,
 				  struct v4l2_subdev_pad_config *cfg,
 				  struct v4l2_subdev_frame_size_enum *fse)
 {
-	if (fse->index)
+	const struct v4l2_mbus_framefmt *fmt;
+	unsigned int i = 0;
+
+	for (; i < OV5647_NUM_FORMATS; ++i) {
+		if (ov5647_formats[i].mbus_code == fse->code)
+			break;
+	}
+	if (i == OV5647_NUM_FORMATS)
 		return -EINVAL;
 
-	if (fse->code != MEDIA_BUS_FMT_SBGGR8_1X8)
+	if (fse->index >= ov5647_formats[i].num_modes)
 		return -EINVAL;
 
-	fse->min_width = 640;
-	fse->max_width = 640;
-	fse->min_height = 480;
-	fse->max_height = 480;
+	fmt = &ov5647_formats[i].modes[fse->index].format;
+	fse->min_width = fmt->width;
+	fse->max_width = fmt->width;
+	fse->min_height = fmt->height;
+	fse->max_height = fmt->height;
 
 	return 0;
 }
@@ -529,12 +575,7 @@ static int ov5647_set_get_fmt(struct v4l2_subdev *sd,
 	struct v4l2_mbus_framefmt *fmt = &format->format;
 
 	/* Only one format is supported, so return that. */
-	memset(fmt, 0, sizeof(*fmt));
-	fmt->code = MEDIA_BUS_FMT_SBGGR8_1X8;
-	fmt->colorspace = V4L2_COLORSPACE_SRGB;
-	fmt->field = V4L2_FIELD_NONE;
-	fmt->width = 640;
-	fmt->height = 480;
+	*fmt = OV5647_DEFAULT_FORMAT;
 
 	return 0;
 }
@@ -594,11 +635,7 @@ static int ov5647_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 	crop->width = OV5647_WINDOW_WIDTH_DEF;
 	crop->height = OV5647_WINDOW_HEIGHT_DEF;
 
-	format->code = MEDIA_BUS_FMT_SBGGR8_1X8;
-	format->width = 640;
-	format->height = 480;
-	format->field = V4L2_FIELD_NONE;
-	format->colorspace = V4L2_COLORSPACE_SRGB;
+	*format = OV5647_DEFAULT_FORMAT;
 
 	return 0;
 }
@@ -822,6 +859,8 @@ static int ov5647_probe(struct i2c_client *client)
 
 	mutex_init(&sensor->lock);
 
+	sensor->mode = OV5647_DEFAULT_MODE;
+
 	ret = ov5647_init_controls(sensor);
 	if (ret)
 		goto mutex_destroy;
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 15/30] media: ov5647: Add support for get_selection()
  2020-11-19 16:32 ` [PATCH v4 10/30] media: ov5647: Implement enum_frame_size() Jacopo Mondi
                     ` (3 preceding siblings ...)
  2020-11-19 16:32   ` [PATCH v4 14/30] media: ov5647: Break out format handling Jacopo Mondi
@ 2020-11-19 16:32   ` Jacopo Mondi
  2020-11-19 16:32   ` [PATCH v4 16/30] media: ov5647: Rename SBGGR8 VGA mode Jacopo Mondi
                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:32 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Dave Stevenson, Jacopo Mondi

From: Dave Stevenson <dave.stevenson@raspberrypi.com>

Support the get_selection() pad operation to report the device
full pixel array size, the currently applied analogue crop rectangle and
the active pixel array dimensions.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 94 ++++++++++++++++++++++++++++----------
 1 file changed, 71 insertions(+), 23 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 9a6766410e0ee..e5a0e6b7e84e2 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -59,25 +59,14 @@
 #define VAL_TERM 0xfe
 #define REG_DLY  0xffff
 
-#define OV5647_ROW_START		0x01
-#define OV5647_ROW_START_MIN		0
-#define OV5647_ROW_START_MAX		2004
-#define OV5647_ROW_START_DEF		54
-
-#define OV5647_COLUMN_START		0x02
-#define OV5647_COLUMN_START_MIN		0
-#define OV5647_COLUMN_START_MAX		2750
-#define OV5647_COLUMN_START_DEF		16
-
-#define OV5647_WINDOW_HEIGHT		0x03
-#define OV5647_WINDOW_HEIGHT_MIN	2
-#define OV5647_WINDOW_HEIGHT_MAX	2006
-#define OV5647_WINDOW_HEIGHT_DEF	1944
-
-#define OV5647_WINDOW_WIDTH		0x04
-#define OV5647_WINDOW_WIDTH_MIN		2
-#define OV5647_WINDOW_WIDTH_MAX		2752
-#define OV5647_WINDOW_WIDTH_DEF		2592
+/* OV5647 native and active pixel array size */
+#define OV5647_NATIVE_WIDTH		2624U
+#define OV5647_NATIVE_HEIGHT		1956U
+
+#define OV5647_PIXEL_ARRAY_LEFT		16U
+#define OV5647_PIXEL_ARRAY_TOP		16U
+#define OV5647_PIXEL_ARRAY_WIDTH	2592U
+#define OV5647_PIXEL_ARRAY_HEIGHT	1944U
 
 struct regval_list {
 	u16 addr;
@@ -86,6 +75,7 @@ struct regval_list {
 
 struct ov5647_mode {
 	struct v4l2_mbus_framefmt	format;
+	struct v4l2_rect		crop;
 	const struct regval_list	*reg_list;
 	unsigned int			num_regs;
 };
@@ -224,6 +214,12 @@ static const struct ov5647_mode ov5647_8bit_modes[] = {
 			.width		= 640,
 			.height		= 480
 		},
+		.crop = {
+			.left		= OV5647_PIXEL_ARRAY_LEFT,
+			.top		= OV5647_PIXEL_ARRAY_TOP,
+			.width		= 1280,
+			.height		= 960,
+		},
 		.reg_list	= ov5647_640x480,
 		.num_regs	= ARRAY_SIZE(ov5647_640x480)
 	},
@@ -511,6 +507,20 @@ static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = {
 #endif
 };
 
+static const struct v4l2_rect *
+__ov5647_get_pad_crop(struct ov5647 *ov5647, struct v4l2_subdev_pad_config *cfg,
+		      unsigned int pad, enum v4l2_subdev_format_whence which)
+{
+	switch (which) {
+	case V4L2_SUBDEV_FORMAT_TRY:
+		return v4l2_subdev_get_try_crop(&ov5647->sd, cfg, pad);
+	case V4L2_SUBDEV_FORMAT_ACTIVE:
+		return &ov5647->mode->crop;
+	}
+
+	return NULL;
+}
+
 static int ov5647_s_stream(struct v4l2_subdev *sd, int enable)
 {
 	struct ov5647 *sensor = to_sensor(sd);
@@ -580,11 +590,49 @@ static int ov5647_set_get_fmt(struct v4l2_subdev *sd,
 	return 0;
 }
 
+static int ov5647_get_selection(struct v4l2_subdev *sd,
+				struct v4l2_subdev_pad_config *cfg,
+				struct v4l2_subdev_selection *sel)
+{
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP: {
+		struct ov5647 *sensor = to_sensor(sd);
+
+		mutex_lock(&sensor->lock);
+		sel->r = *__ov5647_get_pad_crop(sensor, cfg, sel->pad,
+						sel->which);
+		mutex_unlock(&sensor->lock);
+
+		return 0;
+	}
+
+	case V4L2_SEL_TGT_NATIVE_SIZE:
+		sel->r.top = 0;
+		sel->r.left = 0;
+		sel->r.width = OV5647_NATIVE_WIDTH;
+		sel->r.height = OV5647_NATIVE_HEIGHT;
+
+		return 0;
+
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		sel->r.top = OV5647_PIXEL_ARRAY_TOP;
+		sel->r.left = OV5647_PIXEL_ARRAY_LEFT;
+		sel->r.width = OV5647_PIXEL_ARRAY_WIDTH;
+		sel->r.height = OV5647_PIXEL_ARRAY_HEIGHT;
+
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = {
 	.enum_mbus_code		= ov5647_enum_mbus_code,
 	.enum_frame_size	= ov5647_enum_frame_size,
 	.set_fmt		= ov5647_set_get_fmt,
 	.get_fmt		= ov5647_set_get_fmt,
+	.get_selection		= ov5647_get_selection,
 };
 
 static const struct v4l2_subdev_ops ov5647_subdev_ops = {
@@ -630,10 +678,10 @@ static int ov5647_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 				v4l2_subdev_get_try_format(sd, fh->pad, 0);
 	struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, fh->pad, 0);
 
-	crop->left = OV5647_COLUMN_START_DEF;
-	crop->top = OV5647_ROW_START_DEF;
-	crop->width = OV5647_WINDOW_WIDTH_DEF;
-	crop->height = OV5647_WINDOW_HEIGHT_DEF;
+	crop->left = OV5647_PIXEL_ARRAY_LEFT;
+	crop->top = OV5647_PIXEL_ARRAY_TOP;
+	crop->width = OV5647_PIXEL_ARRAY_WIDTH;
+	crop->height = OV5647_PIXEL_ARRAY_HEIGHT;
 
 	*format = OV5647_DEFAULT_FORMAT;
 
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 16/30] media: ov5647: Rename SBGGR8 VGA mode
  2020-11-19 16:32 ` [PATCH v4 10/30] media: ov5647: Implement enum_frame_size() Jacopo Mondi
                     ` (4 preceding siblings ...)
  2020-11-19 16:32   ` [PATCH v4 15/30] media: ov5647: Add support for get_selection() Jacopo Mondi
@ 2020-11-19 16:32   ` Jacopo Mondi
  2020-11-19 16:32   ` [PATCH v4 17/30] media: ov5647: Add SGGBR10_1X10 modes Jacopo Mondi
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:32 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

Before adding new modes, rename the only existing one to report
the bit depth to distinguish it from future additions.

While at it, briefly describe the mode.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index e5a0e6b7e84e2..0234aed43a10a 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -115,7 +115,7 @@ static struct regval_list sensor_oe_enable_regs[] = {
 	{0x3002, 0xe4},
 };
 
-static const struct regval_list ov5647_640x480[] = {
+static const struct regval_list ov5647_640x480_8bpp[] = {
 	{0x0100, 0x00},
 	{0x0103, 0x01},
 	{0x3034, 0x08},
@@ -205,7 +205,8 @@ static const struct regval_list ov5647_640x480[] = {
 	{0x0100, 0x01},
 };
 
-static const struct ov5647_mode ov5647_8bit_modes[] = {
+static const struct ov5647_mode ov5647_8bpp_modes[] = {
+	/* 8-bit VGA mode: Uncentred crop 2x2 binned 1296x972 image. */
 	{
 		.format	= {
 			.code		= MEDIA_BUS_FMT_SBGGR8_1X8,
@@ -220,16 +221,16 @@ static const struct ov5647_mode ov5647_8bit_modes[] = {
 			.width		= 1280,
 			.height		= 960,
 		},
-		.reg_list	= ov5647_640x480,
-		.num_regs	= ARRAY_SIZE(ov5647_640x480)
+		.reg_list	= ov5647_640x480_8bpp,
+		.num_regs	= ARRAY_SIZE(ov5647_640x480_8bpp)
 	},
 };
 
 static const struct ov5647_format_list ov5647_formats[] = {
 	{
 		.mbus_code	= MEDIA_BUS_FMT_SBGGR8_1X8,
-		.modes		= ov5647_8bit_modes,
-		.num_modes	= ARRAY_SIZE(ov5647_8bit_modes),
+		.modes		= ov5647_8bpp_modes,
+		.num_modes	= ARRAY_SIZE(ov5647_8bpp_modes),
 	},
 };
 
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 17/30] media: ov5647: Add SGGBR10_1X10 modes
  2020-11-19 16:32 ` [PATCH v4 10/30] media: ov5647: Implement enum_frame_size() Jacopo Mondi
                     ` (5 preceding siblings ...)
  2020-11-19 16:32   ` [PATCH v4 16/30] media: ov5647: Rename SBGGR8 VGA mode Jacopo Mondi
@ 2020-11-19 16:32   ` Jacopo Mondi
  2020-11-19 16:32   ` [PATCH v4 18/30] media: ov5647: Use SBGGR10_1X10 640x480 as default Jacopo Mondi
  2020-11-19 16:32   ` [PATCH v4 19/30] media: ov5647: Implement set_fmt pad operation Jacopo Mondi
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:32 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

Add 4 additional sensor modes in SBGGR10_1X10 format.

Add the following resolutions:
- 2592x1944 full resolution
- 1920x1080 1080p cropped
- 1296x972 2x2 binned
- 640x480 2x2 binned, 2x2 subsampled

The register lists and modes definition have been upported from the
RaspberryPi BSP at revision:
commit 581dfda6d0a62 ("media: i2c: ov5647: Advertise the correct exposure range")

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 441 +++++++++++++++++++++++++++++++++++++
 1 file changed, 441 insertions(+)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 0234aed43a10a..e206656a5e883 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -205,6 +205,367 @@ static const struct regval_list ov5647_640x480_8bpp[] = {
 	{0x0100, 0x01},
 };
 
+static struct regval_list ov5647_2592x1944_10bpp[] = {
+	{0x0100, 0x00},
+	{0x0103, 0x01},
+	{0x3034, 0x1a},
+	{0x3035, 0x21},
+	{0x3036, 0x69},
+	{0x303c, 0x11},
+	{0x3106, 0xf5},
+	{0x3821, 0x06},
+	{0x3820, 0x00},
+	{0x3827, 0xec},
+	{0x370c, 0x03},
+	{0x3612, 0x5b},
+	{0x3618, 0x04},
+	{0x5000, 0x06},
+	{0x5002, 0x41},
+	{0x5003, 0x08},
+	{0x5a00, 0x08},
+	{0x3000, 0x00},
+	{0x3001, 0x00},
+	{0x3002, 0x00},
+	{0x3016, 0x08},
+	{0x3017, 0xe0},
+	{0x3018, 0x44},
+	{0x301c, 0xf8},
+	{0x301d, 0xf0},
+	{0x3a18, 0x00},
+	{0x3a19, 0xf8},
+	{0x3c01, 0x80},
+	{0x3b07, 0x0c},
+	{0x380c, 0x0b},
+	{0x380d, 0x1c},
+	{0x3814, 0x11},
+	{0x3815, 0x11},
+	{0x3708, 0x64},
+	{0x3709, 0x12},
+	{0x3808, 0x0a},
+	{0x3809, 0x20},
+	{0x380a, 0x07},
+	{0x380b, 0x98},
+	{0x3800, 0x00},
+	{0x3801, 0x00},
+	{0x3802, 0x00},
+	{0x3803, 0x00},
+	{0x3804, 0x0a},
+	{0x3805, 0x3f},
+	{0x3806, 0x07},
+	{0x3807, 0xa3},
+	{0x3811, 0x10},
+	{0x3813, 0x06},
+	{0x3630, 0x2e},
+	{0x3632, 0xe2},
+	{0x3633, 0x23},
+	{0x3634, 0x44},
+	{0x3636, 0x06},
+	{0x3620, 0x64},
+	{0x3621, 0xe0},
+	{0x3600, 0x37},
+	{0x3704, 0xa0},
+	{0x3703, 0x5a},
+	{0x3715, 0x78},
+	{0x3717, 0x01},
+	{0x3731, 0x02},
+	{0x370b, 0x60},
+	{0x3705, 0x1a},
+	{0x3f05, 0x02},
+	{0x3f06, 0x10},
+	{0x3f01, 0x0a},
+	{0x3a08, 0x01},
+	{0x3a09, 0x28},
+	{0x3a0a, 0x00},
+	{0x3a0b, 0xf6},
+	{0x3a0d, 0x08},
+	{0x3a0e, 0x06},
+	{0x3a0f, 0x58},
+	{0x3a10, 0x50},
+	{0x3a1b, 0x58},
+	{0x3a1e, 0x50},
+	{0x3a11, 0x60},
+	{0x3a1f, 0x28},
+	{0x4001, 0x02},
+	{0x4004, 0x04},
+	{0x4000, 0x09},
+	{0x4837, 0x19},
+	{0x4800, 0x24},
+	{0x3503, 0x03},
+	{0x0100, 0x01},
+};
+
+static struct regval_list ov5647_1080p30_10bpp[] = {
+	{0x0100, 0x00},
+	{0x0103, 0x01},
+	{0x3034, 0x1a},
+	{0x3035, 0x21},
+	{0x3036, 0x62},
+	{0x303c, 0x11},
+	{0x3106, 0xf5},
+	{0x3821, 0x06},
+	{0x3820, 0x00},
+	{0x3827, 0xec},
+	{0x370c, 0x03},
+	{0x3612, 0x5b},
+	{0x3618, 0x04},
+	{0x5000, 0x06},
+	{0x5002, 0x41},
+	{0x5003, 0x08},
+	{0x5a00, 0x08},
+	{0x3000, 0x00},
+	{0x3001, 0x00},
+	{0x3002, 0x00},
+	{0x3016, 0x08},
+	{0x3017, 0xe0},
+	{0x3018, 0x44},
+	{0x301c, 0xf8},
+	{0x301d, 0xf0},
+	{0x3a18, 0x00},
+	{0x3a19, 0xf8},
+	{0x3c01, 0x80},
+	{0x3b07, 0x0c},
+	{0x380c, 0x09},
+	{0x380d, 0x70},
+	{0x3814, 0x11},
+	{0x3815, 0x11},
+	{0x3708, 0x64},
+	{0x3709, 0x12},
+	{0x3808, 0x07},
+	{0x3809, 0x80},
+	{0x380a, 0x04},
+	{0x380b, 0x38},
+	{0x3800, 0x01},
+	{0x3801, 0x5c},
+	{0x3802, 0x01},
+	{0x3803, 0xb2},
+	{0x3804, 0x08},
+	{0x3805, 0xe3},
+	{0x3806, 0x05},
+	{0x3807, 0xf1},
+	{0x3811, 0x04},
+	{0x3813, 0x02},
+	{0x3630, 0x2e},
+	{0x3632, 0xe2},
+	{0x3633, 0x23},
+	{0x3634, 0x44},
+	{0x3636, 0x06},
+	{0x3620, 0x64},
+	{0x3621, 0xe0},
+	{0x3600, 0x37},
+	{0x3704, 0xa0},
+	{0x3703, 0x5a},
+	{0x3715, 0x78},
+	{0x3717, 0x01},
+	{0x3731, 0x02},
+	{0x370b, 0x60},
+	{0x3705, 0x1a},
+	{0x3f05, 0x02},
+	{0x3f06, 0x10},
+	{0x3f01, 0x0a},
+	{0x3a08, 0x01},
+	{0x3a09, 0x4b},
+	{0x3a0a, 0x01},
+	{0x3a0b, 0x13},
+	{0x3a0d, 0x04},
+	{0x3a0e, 0x03},
+	{0x3a0f, 0x58},
+	{0x3a10, 0x50},
+	{0x3a1b, 0x58},
+	{0x3a1e, 0x50},
+	{0x3a11, 0x60},
+	{0x3a1f, 0x28},
+	{0x4001, 0x02},
+	{0x4004, 0x04},
+	{0x4000, 0x09},
+	{0x4837, 0x19},
+	{0x4800, 0x34},
+	{0x3503, 0x03},
+	{0x0100, 0x01},
+};
+
+static struct regval_list ov5647_2x2binned_10bpp[] = {
+	{0x0100, 0x00},
+	{0x0103, 0x01},
+	{0x3034, 0x1a},
+	{0x3035, 0x21},
+	{0x3036, 0x62},
+	{0x303c, 0x11},
+	{0x3106, 0xf5},
+	{0x3827, 0xec},
+	{0x370c, 0x03},
+	{0x3612, 0x59},
+	{0x3618, 0x00},
+	{0x5000, 0x06},
+	{0x5002, 0x41},
+	{0x5003, 0x08},
+	{0x5a00, 0x08},
+	{0x3000, 0x00},
+	{0x3001, 0x00},
+	{0x3002, 0x00},
+	{0x3016, 0x08},
+	{0x3017, 0xe0},
+	{0x3018, 0x44},
+	{0x301c, 0xf8},
+	{0x301d, 0xf0},
+	{0x3a18, 0x00},
+	{0x3a19, 0xf8},
+	{0x3c01, 0x80},
+	{0x3b07, 0x0c},
+	{0x3800, 0x00},
+	{0x3801, 0x00},
+	{0x3802, 0x00},
+	{0x3803, 0x00},
+	{0x3804, 0x0a},
+	{0x3805, 0x3f},
+	{0x3806, 0x07},
+	{0x3807, 0xa3},
+	{0x3808, 0x05},
+	{0x3809, 0x10},
+	{0x380a, 0x03},
+	{0x380b, 0xcc},
+	{0x380c, 0x07},
+	{0x380d, 0x68},
+	{0x3811, 0x0c},
+	{0x3813, 0x06},
+	{0x3814, 0x31},
+	{0x3815, 0x31},
+	{0x3630, 0x2e},
+	{0x3632, 0xe2},
+	{0x3633, 0x23},
+	{0x3634, 0x44},
+	{0x3636, 0x06},
+	{0x3620, 0x64},
+	{0x3621, 0xe0},
+	{0x3600, 0x37},
+	{0x3704, 0xa0},
+	{0x3703, 0x5a},
+	{0x3715, 0x78},
+	{0x3717, 0x01},
+	{0x3731, 0x02},
+	{0x370b, 0x60},
+	{0x3705, 0x1a},
+	{0x3f05, 0x02},
+	{0x3f06, 0x10},
+	{0x3f01, 0x0a},
+	{0x3a08, 0x01},
+	{0x3a09, 0x28},
+	{0x3a0a, 0x00},
+	{0x3a0b, 0xf6},
+	{0x3a0d, 0x08},
+	{0x3a0e, 0x06},
+	{0x3a0f, 0x58},
+	{0x3a10, 0x50},
+	{0x3a1b, 0x58},
+	{0x3a1e, 0x50},
+	{0x3a11, 0x60},
+	{0x3a1f, 0x28},
+	{0x4001, 0x02},
+	{0x4004, 0x04},
+	{0x4000, 0x09},
+	{0x4837, 0x16},
+	{0x4800, 0x24},
+	{0x3503, 0x03},
+	{0x3820, 0x41},
+	{0x3821, 0x07},
+	{0x350a, 0x00},
+	{0x350b, 0x10},
+	{0x3500, 0x00},
+	{0x3501, 0x1a},
+	{0x3502, 0xf0},
+	{0x3212, 0xa0},
+	{0x0100, 0x01},
+};
+
+static struct regval_list ov5647_640x480_10bpp[] = {
+	{0x0100, 0x00},
+	{0x0103, 0x01},
+	{0x3035, 0x11},
+	{0x3036, 0x46},
+	{0x303c, 0x11},
+	{0x3821, 0x07},
+	{0x3820, 0x41},
+	{0x370c, 0x03},
+	{0x3612, 0x59},
+	{0x3618, 0x00},
+	{0x5000, 0x06},
+	{0x5003, 0x08},
+	{0x5a00, 0x08},
+	{0x3000, 0xff},
+	{0x3001, 0xff},
+	{0x3002, 0xff},
+	{0x301d, 0xf0},
+	{0x3a18, 0x00},
+	{0x3a19, 0xf8},
+	{0x3c01, 0x80},
+	{0x3b07, 0x0c},
+	{0x380c, 0x07},
+	{0x380d, 0x3c},
+	{0x3814, 0x35},
+	{0x3815, 0x35},
+	{0x3708, 0x64},
+	{0x3709, 0x52},
+	{0x3808, 0x02},
+	{0x3809, 0x80},
+	{0x380a, 0x01},
+	{0x380b, 0xe0},
+	{0x3800, 0x00},
+	{0x3801, 0x10},
+	{0x3802, 0x00},
+	{0x3803, 0x00},
+	{0x3804, 0x0a},
+	{0x3805, 0x2f},
+	{0x3806, 0x07},
+	{0x3807, 0x9f},
+	{0x3630, 0x2e},
+	{0x3632, 0xe2},
+	{0x3633, 0x23},
+	{0x3634, 0x44},
+	{0x3620, 0x64},
+	{0x3621, 0xe0},
+	{0x3600, 0x37},
+	{0x3704, 0xa0},
+	{0x3703, 0x5a},
+	{0x3715, 0x78},
+	{0x3717, 0x01},
+	{0x3731, 0x02},
+	{0x370b, 0x60},
+	{0x3705, 0x1a},
+	{0x3f05, 0x02},
+	{0x3f06, 0x10},
+	{0x3f01, 0x0a},
+	{0x3a08, 0x01},
+	{0x3a09, 0x2e},
+	{0x3a0a, 0x00},
+	{0x3a0b, 0xfb},
+	{0x3a0d, 0x02},
+	{0x3a0e, 0x01},
+	{0x3a0f, 0x58},
+	{0x3a10, 0x50},
+	{0x3a1b, 0x58},
+	{0x3a1e, 0x50},
+	{0x3a11, 0x60},
+	{0x3a1f, 0x28},
+	{0x4001, 0x02},
+	{0x4004, 0x02},
+	{0x4000, 0x09},
+	{0x3000, 0x00},
+	{0x3001, 0x00},
+	{0x3002, 0x00},
+	{0x3017, 0xe0},
+	{0x301c, 0xfc},
+	{0x3636, 0x06},
+	{0x3016, 0x08},
+	{0x3827, 0xec},
+	{0x3018, 0x44},
+	{0x3035, 0x21},
+	{0x3106, 0xf5},
+	{0x3034, 0x1a},
+	{0x301c, 0xf8},
+	{0x4800, 0x34},
+	{0x3503, 0x03},
+	{0x0100, 0x01},
+};
+
 static const struct ov5647_mode ov5647_8bpp_modes[] = {
 	/* 8-bit VGA mode: Uncentred crop 2x2 binned 1296x972 image. */
 	{
@@ -226,12 +587,92 @@ static const struct ov5647_mode ov5647_8bpp_modes[] = {
 	},
 };
 
+static const struct ov5647_mode ov5647_10bpp_modes[] = {
+	/* 2592x1944 full resolution full FOV 10-bit mode. */
+	{
+		.format = {
+			.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
+			.colorspace	= V4L2_COLORSPACE_SRGB,
+			.field		= V4L2_FIELD_NONE,
+			.width		= 2592,
+			.height		= 1944
+		},
+		.crop = {
+			.left		= OV5647_PIXEL_ARRAY_LEFT,
+			.top		= OV5647_PIXEL_ARRAY_TOP,
+			.width		= 2592,
+			.height		= 1944
+		},
+		.reg_list	= ov5647_2592x1944_10bpp,
+		.num_regs	= ARRAY_SIZE(ov5647_2592x1944_10bpp)
+	},
+	/* 1080p30 10-bit mode. Full resolution centre-cropped down to 1080p. */
+	{
+		.format = {
+			.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
+			.colorspace	= V4L2_COLORSPACE_SRGB,
+			.field		= V4L2_FIELD_NONE,
+			.width		= 1920,
+			.height		= 1080
+		},
+		.crop = {
+			.left		= 348 + OV5647_PIXEL_ARRAY_LEFT,
+			.top		= 434 + OV5647_PIXEL_ARRAY_TOP,
+			.width		= 1928,
+			.height		= 1080,
+		},
+		.reg_list	= ov5647_1080p30_10bpp,
+		.num_regs	= ARRAY_SIZE(ov5647_1080p30_10bpp)
+	},
+	/* 2x2 binned full FOV 10-bit mode. */
+	{
+		.format = {
+			.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
+			.colorspace	= V4L2_COLORSPACE_SRGB,
+			.field		= V4L2_FIELD_NONE,
+			.width		= 1296,
+			.height		= 972
+		},
+		.crop = {
+			.left		= OV5647_PIXEL_ARRAY_LEFT,
+			.top		= OV5647_PIXEL_ARRAY_TOP,
+			.width		= 2592,
+			.height		= 1944,
+		},
+		.reg_list	= ov5647_2x2binned_10bpp,
+		.num_regs	= ARRAY_SIZE(ov5647_2x2binned_10bpp)
+	},
+	/* 10-bit VGA full FOV 60fps. 2x2 binned and subsampled down to VGA. */
+	{
+		.format = {
+			.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
+			.colorspace	= V4L2_COLORSPACE_SRGB,
+			.field		= V4L2_FIELD_NONE,
+			.width		= 640,
+			.height		= 480
+		},
+		.crop = {
+			.left		= 16 + OV5647_PIXEL_ARRAY_LEFT,
+			.top		= OV5647_PIXEL_ARRAY_TOP,
+			.width		= 2560,
+			.height		= 1920,
+		},
+		.reg_list	= ov5647_640x480_10bpp,
+		.num_regs	= ARRAY_SIZE(ov5647_640x480_10bpp)
+	},
+};
+
 static const struct ov5647_format_list ov5647_formats[] = {
 	{
 		.mbus_code	= MEDIA_BUS_FMT_SBGGR8_1X8,
 		.modes		= ov5647_8bpp_modes,
 		.num_modes	= ARRAY_SIZE(ov5647_8bpp_modes),
 	},
+	{
+		.mbus_code	= MEDIA_BUS_FMT_SBGGR10_1X10,
+		.modes		= ov5647_10bpp_modes,
+		.num_modes	= ARRAY_SIZE(ov5647_10bpp_modes),
+	},
 };
 
 #define OV5647_NUM_FORMATS	(ARRAY_SIZE(ov5647_formats))
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 18/30] media: ov5647: Use SBGGR10_1X10 640x480 as default
  2020-11-19 16:32 ` [PATCH v4 10/30] media: ov5647: Implement enum_frame_size() Jacopo Mondi
                     ` (6 preceding siblings ...)
  2020-11-19 16:32   ` [PATCH v4 17/30] media: ov5647: Add SGGBR10_1X10 modes Jacopo Mondi
@ 2020-11-19 16:32   ` Jacopo Mondi
  2020-11-19 16:32   ` [PATCH v4 19/30] media: ov5647: Implement set_fmt pad operation Jacopo Mondi
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:32 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

The SBGGR10_1X10 formats supports more resolutions than SBGGR8_1X8.
Make it the default sensor format and set 2x2 binned 640x480 resolution
as default sensor size as it maximizes the FOV and framerate.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index e206656a5e883..bb570be487175 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -677,8 +677,9 @@ static const struct ov5647_format_list ov5647_formats[] = {
 
 #define OV5647_NUM_FORMATS	(ARRAY_SIZE(ov5647_formats))
 
-#define OV5647_DEFAULT_MODE	(&ov5647_formats[0].modes[0])
-#define OV5647_DEFAULT_FORMAT	(ov5647_formats[0].modes[0].format)
+/* Default sensor mode is 2x2 binned 640x480 SBGGR10_1X10. */
+#define OV5647_DEFAULT_MODE	(&ov5647_formats[1].modes[3])
+#define OV5647_DEFAULT_FORMAT	(ov5647_formats[1].modes[3].format)
 
 static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val)
 {
@@ -1026,7 +1027,6 @@ static int ov5647_set_get_fmt(struct v4l2_subdev *sd,
 {
 	struct v4l2_mbus_framefmt *fmt = &format->format;
 
-	/* Only one format is supported, so return that. */
 	*fmt = OV5647_DEFAULT_FORMAT;
 
 	return 0;
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 19/30] media: ov5647: Implement set_fmt pad operation
  2020-11-19 16:32 ` [PATCH v4 10/30] media: ov5647: Implement enum_frame_size() Jacopo Mondi
                     ` (7 preceding siblings ...)
  2020-11-19 16:32   ` [PATCH v4 18/30] media: ov5647: Use SBGGR10_1X10 640x480 as default Jacopo Mondi
@ 2020-11-19 16:32   ` Jacopo Mondi
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:32 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

Now that the driver supports more than a single mode, implement the
.set_fmt pad operation and adjust the existing .get_fmt one to report
the currently applied format.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 66 +++++++++++++++++++++++++++++++++++---
 1 file changed, 62 insertions(+), 4 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index bb570be487175..bb85e9c53c9cc 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -1021,13 +1021,71 @@ static int ov5647_enum_frame_size(struct v4l2_subdev *sd,
 	return 0;
 }
 
-static int ov5647_set_get_fmt(struct v4l2_subdev *sd,
+static int ov5647_get_pad_fmt(struct v4l2_subdev *sd,
 			      struct v4l2_subdev_pad_config *cfg,
 			      struct v4l2_subdev_format *format)
 {
 	struct v4l2_mbus_framefmt *fmt = &format->format;
+	const struct v4l2_mbus_framefmt *sensor_format;
+	struct ov5647 *sensor = to_sensor(sd);
+
+	mutex_lock(&sensor->lock);
+	switch (format->which) {
+	case V4L2_SUBDEV_FORMAT_TRY:
+		sensor_format = v4l2_subdev_get_try_format(sd, cfg, format->pad);
+		break;
+	default:
+		sensor_format = &sensor->mode->format;
+		break;
+	}
+
+	*fmt = *sensor_format;
+	mutex_unlock(&sensor->lock);
+
+	return 0;
+}
+
+static int ov5647_set_pad_fmt(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_pad_config *cfg,
+			      struct v4l2_subdev_format *format)
+{
+	struct v4l2_mbus_framefmt *fmt = &format->format;
+	const struct ov5647_mode *ov5647_mode_list;
+	struct ov5647 *sensor = to_sensor(sd);
+	const struct ov5647_mode *mode;
+	unsigned int num_modes;
+	unsigned int i;
+
+	for (i = 0; i < OV5647_NUM_FORMATS; ++i) {
+		if (ov5647_formats[i].mbus_code != fmt->code)
+			continue;
+
+		ov5647_mode_list = ov5647_formats[i].modes;
+		num_modes = ov5647_formats[i].num_modes;
+		break;
+	}
+
+	/*
+	 * Default mbus code MEDIA_BUS_FMT_SBGGR10_1X10 if the requested one is
+	 * not supported.
+	 */
+	if (i == OV5647_NUM_FORMATS) {
+		ov5647_mode_list = ov5647_10bpp_modes;
+		num_modes = ARRAY_SIZE(ov5647_10bpp_modes);
+	}
+
+	mode = v4l2_find_nearest_size(ov5647_mode_list, num_modes,
+				      format.width, format.height,
+				      fmt->width, fmt->height);
 
-	*fmt = OV5647_DEFAULT_FORMAT;
+	/* Update the sensor mode and apply at it at streamon time. */
+	mutex_lock(&sensor->lock);
+	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
+		*v4l2_subdev_get_try_format(sd, cfg, format->pad) = mode->format;
+	else
+		sensor->mode = mode;
+	*fmt = mode->format;
+	mutex_unlock(&sensor->lock);
 
 	return 0;
 }
@@ -1072,8 +1130,8 @@ static int ov5647_get_selection(struct v4l2_subdev *sd,
 static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = {
 	.enum_mbus_code		= ov5647_enum_mbus_code,
 	.enum_frame_size	= ov5647_enum_frame_size,
-	.set_fmt		= ov5647_set_get_fmt,
-	.get_fmt		= ov5647_set_get_fmt,
+	.set_fmt		= ov5647_set_pad_fmt,
+	.get_fmt		= ov5647_get_pad_fmt,
 	.get_selection		= ov5647_get_selection,
 };
 
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 20/30] media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag
  2020-11-19 16:19 [PATCH v4 00/30] media: ov5647: Support RaspberryPi Camera Module v1 Jacopo Mondi
                   ` (9 preceding siblings ...)
  2020-11-19 16:32 ` [PATCH v4 10/30] media: ov5647: Implement enum_frame_size() Jacopo Mondi
@ 2020-11-19 16:35 ` Jacopo Mondi
  2020-11-19 16:35   ` [PATCH v4 21/30] media: ov5647: Support V4L2_CID_PIXEL_RATE Jacopo Mondi
                     ` (8 more replies)
  2020-11-19 16:37 ` [PATCH v4 30/30] media: ov5647: Remove 640x480 SBGGR8 mode Jacopo Mondi
  11 siblings, 9 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:35 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Dave Stevenson, Jacopo Mondi

From: Dave Stevenson <dave.stevenson@raspberrypi.com>

The ov5647 subdev can generate control events, therefore set
the V4L2_SUBDEV_FL_HAS_EVENTS flag.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index bb85e9c53c9cc..45144a600c536 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -1416,7 +1416,7 @@ static int ov5647_probe(struct i2c_client *client)
 	sd = &sensor->sd;
 	v4l2_i2c_subdev_init(sd, client, &ov5647_subdev_ops);
 	sd->internal_ops = &ov5647_subdev_internal_ops;
-	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
 
 	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 21/30] media: ov5647: Support V4L2_CID_PIXEL_RATE
  2020-11-19 16:35 ` [PATCH v4 20/30] media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag Jacopo Mondi
@ 2020-11-19 16:35   ` Jacopo Mondi
  2020-11-19 16:35   ` [PATCH v4 22/30] media: ov5647: Support V4L2_CID_HBLANK control Jacopo Mondi
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:35 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Dave Stevenson, Jacopo Mondi

From: Dave Stevenson <dave.stevenson@raspberrypi.com>

Clients need to know the pixel rate in order to compute exposure
and frame rate values. Advertise it.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 43 ++++++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 11 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 45144a600c536..86612f941e891 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -76,6 +76,7 @@ struct regval_list {
 struct ov5647_mode {
 	struct v4l2_mbus_framefmt	format;
 	struct v4l2_rect		crop;
+	u64				pixel_rate;
 	const struct regval_list	*reg_list;
 	unsigned int			num_regs;
 };
@@ -96,6 +97,7 @@ struct ov5647 {
 	bool				clock_ncont;
 	struct v4l2_ctrl_handler	ctrls;
 	const struct ov5647_mode	*mode;
+	struct v4l2_ctrl		*pixel_rate;
 };
 
 static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd)
@@ -582,6 +584,7 @@ static const struct ov5647_mode ov5647_8bpp_modes[] = {
 			.width		= 1280,
 			.height		= 960,
 		},
+		.pixel_rate	= 77291670,
 		.reg_list	= ov5647_640x480_8bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_640x480_8bpp)
 	},
@@ -603,6 +606,7 @@ static const struct ov5647_mode ov5647_10bpp_modes[] = {
 			.width		= 2592,
 			.height		= 1944
 		},
+		.pixel_rate	= 87500000,
 		.reg_list	= ov5647_2592x1944_10bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_2592x1944_10bpp)
 	},
@@ -621,6 +625,7 @@ static const struct ov5647_mode ov5647_10bpp_modes[] = {
 			.width		= 1928,
 			.height		= 1080,
 		},
+		.pixel_rate	= 81666700,
 		.reg_list	= ov5647_1080p30_10bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_1080p30_10bpp)
 	},
@@ -639,6 +644,7 @@ static const struct ov5647_mode ov5647_10bpp_modes[] = {
 			.width		= 2592,
 			.height		= 1944,
 		},
+		.pixel_rate	= 81666700,
 		.reg_list	= ov5647_2x2binned_10bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_2x2binned_10bpp)
 	},
@@ -657,6 +663,7 @@ static const struct ov5647_mode ov5647_10bpp_modes[] = {
 			.width		= 2560,
 			.height		= 1920,
 		},
+		.pixel_rate	= 55000000,
 		.reg_list	= ov5647_640x480_10bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_640x480_10bpp)
 	},
@@ -1080,10 +1087,13 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd,
 
 	/* Update the sensor mode and apply at it at streamon time. */
 	mutex_lock(&sensor->lock);
-	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
+	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
 		*v4l2_subdev_get_try_format(sd, cfg, format->pad) = mode->format;
-	else
+	} else {
 		sensor->mode = mode;
+		__v4l2_ctrl_modify_range(sensor->pixel_rate, mode->pixel_rate,
+					 mode->pixel_rate, 1, mode->pixel_rate);
+	}
 	*fmt = mode->format;
 	mutex_unlock(&sensor->lock);
 
@@ -1288,6 +1298,9 @@ static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl)
 		return  ov5647_s_analogue_gain(sd, ctrl->val);
 	case V4L2_CID_EXPOSURE:
 		return ov5647_s_exposure(sd, ctrl->val);
+	case V4L2_CID_PIXEL_RATE:
+		/* Read-only, but we adjust it based on mode. */
+		return 0;
 	default:
 		dev_info(&client->dev,
 			 "Control (id:0x%x, val:0x%x) not supported\n",
@@ -1306,7 +1319,7 @@ static int ov5647_init_controls(struct ov5647 *sensor)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
 
-	v4l2_ctrl_handler_init(&sensor->ctrls, 5);
+	v4l2_ctrl_handler_init(&sensor->ctrls, 6);
 
 	v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
 			  V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
@@ -1326,18 +1339,26 @@ static int ov5647_init_controls(struct ov5647 *sensor)
 	v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
 			  V4L2_CID_ANALOGUE_GAIN, 16, 1023, 1, 32);
 
-	if (sensor->ctrls.error) {
-		dev_err(&client->dev,
-			"%s Controls initialization failed (%d)\n",
-			__func__, sensor->ctrls.error);
-		v4l2_ctrl_handler_free(&sensor->ctrls);
-
-		return sensor->ctrls.error;
-	}
+	/* By default, PIXEL_RATE is read only, but it does change per mode */
+	sensor->pixel_rate = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
+					       V4L2_CID_PIXEL_RATE,
+					       sensor->mode->pixel_rate,
+					       sensor->mode->pixel_rate, 1,
+					       sensor->mode->pixel_rate);
+	if (sensor->ctrls.error)
+		goto handler_free;
 
+	sensor->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 	sensor->sd.ctrl_handler = &sensor->ctrls;
 
 	return 0;
+
+handler_free:
+	dev_err(&client->dev, "%s Controls initialization failed (%d)\n",
+		__func__, sensor->ctrls.error);
+	v4l2_ctrl_handler_free(&sensor->ctrls);
+
+	return sensor->ctrls.error;
 }
 
 static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np)
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 22/30] media: ov5647: Support V4L2_CID_HBLANK control
  2020-11-19 16:35 ` [PATCH v4 20/30] media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag Jacopo Mondi
  2020-11-19 16:35   ` [PATCH v4 21/30] media: ov5647: Support V4L2_CID_PIXEL_RATE Jacopo Mondi
@ 2020-11-19 16:35   ` Jacopo Mondi
  2020-11-19 16:35   ` [PATCH v4 23/30] media: ov5647: Support V4L2_CID_VBLANK control Jacopo Mondi
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:35 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

Add support for the V4L2_CID_HBLANK read-only control.

The implementation has been upported from RaspberryPi BSP commit:
commit d82f202156605 ("media: i2c: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag")

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 86612f941e891..2ffca9f658bfa 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -77,6 +77,7 @@ struct ov5647_mode {
 	struct v4l2_mbus_framefmt	format;
 	struct v4l2_rect		crop;
 	u64				pixel_rate;
+	int				hts;
 	const struct regval_list	*reg_list;
 	unsigned int			num_regs;
 };
@@ -98,6 +99,7 @@ struct ov5647 {
 	struct v4l2_ctrl_handler	ctrls;
 	const struct ov5647_mode	*mode;
 	struct v4l2_ctrl		*pixel_rate;
+	struct v4l2_ctrl		*hblank;
 };
 
 static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd)
@@ -585,6 +587,7 @@ static const struct ov5647_mode ov5647_8bpp_modes[] = {
 			.height		= 960,
 		},
 		.pixel_rate	= 77291670,
+		.hts		= 1896,
 		.reg_list	= ov5647_640x480_8bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_640x480_8bpp)
 	},
@@ -607,6 +610,7 @@ static const struct ov5647_mode ov5647_10bpp_modes[] = {
 			.height		= 1944
 		},
 		.pixel_rate	= 87500000,
+		.hts		= 2844,
 		.reg_list	= ov5647_2592x1944_10bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_2592x1944_10bpp)
 	},
@@ -626,6 +630,7 @@ static const struct ov5647_mode ov5647_10bpp_modes[] = {
 			.height		= 1080,
 		},
 		.pixel_rate	= 81666700,
+		.hts		= 2416,
 		.reg_list	= ov5647_1080p30_10bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_1080p30_10bpp)
 	},
@@ -645,6 +650,7 @@ static const struct ov5647_mode ov5647_10bpp_modes[] = {
 			.height		= 1944,
 		},
 		.pixel_rate	= 81666700,
+		.hts		= 1896,
 		.reg_list	= ov5647_2x2binned_10bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_2x2binned_10bpp)
 	},
@@ -664,6 +670,7 @@ static const struct ov5647_mode ov5647_10bpp_modes[] = {
 			.height		= 1920,
 		},
 		.pixel_rate	= 55000000,
+		.hts		= 1852,
 		.reg_list	= ov5647_640x480_10bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_640x480_10bpp)
 	},
@@ -1090,9 +1097,15 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd,
 	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
 		*v4l2_subdev_get_try_format(sd, cfg, format->pad) = mode->format;
 	} else {
+		int hblank;
+
 		sensor->mode = mode;
 		__v4l2_ctrl_modify_range(sensor->pixel_rate, mode->pixel_rate,
 					 mode->pixel_rate, 1, mode->pixel_rate);
+
+		hblank = mode->hts - mode->format.width;
+		__v4l2_ctrl_modify_range(sensor->hblank, hblank, hblank, 1,
+					 hblank);
 	}
 	*fmt = mode->format;
 	mutex_unlock(&sensor->lock);
@@ -1301,6 +1314,9 @@ static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_PIXEL_RATE:
 		/* Read-only, but we adjust it based on mode. */
 		return 0;
+	case V4L2_CID_HBLANK:
+		/* Read-only, but we adjust it based on mode. */
+		return 0;
 	default:
 		dev_info(&client->dev,
 			 "Control (id:0x%x, val:0x%x) not supported\n",
@@ -1318,8 +1334,9 @@ static const struct v4l2_ctrl_ops ov5647_ctrl_ops = {
 static int ov5647_init_controls(struct ov5647 *sensor)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
+	int hblank;
 
-	v4l2_ctrl_handler_init(&sensor->ctrls, 6);
+	v4l2_ctrl_handler_init(&sensor->ctrls, 7);
 
 	v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
 			  V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
@@ -1345,10 +1362,18 @@ static int ov5647_init_controls(struct ov5647 *sensor)
 					       sensor->mode->pixel_rate,
 					       sensor->mode->pixel_rate, 1,
 					       sensor->mode->pixel_rate);
+
+	/* By default, HBLANK is read only, but it does change per mode. */
+	hblank = sensor->mode->hts - sensor->mode->format.width;
+	sensor->hblank = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
+					   V4L2_CID_HBLANK, hblank, hblank, 1,
+					   hblank);
+
 	if (sensor->ctrls.error)
 		goto handler_free;
 
 	sensor->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+	sensor->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 	sensor->sd.ctrl_handler = &sensor->ctrls;
 
 	return 0;
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 23/30] media: ov5647: Support V4L2_CID_VBLANK control
  2020-11-19 16:35 ` [PATCH v4 20/30] media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag Jacopo Mondi
  2020-11-19 16:35   ` [PATCH v4 21/30] media: ov5647: Support V4L2_CID_PIXEL_RATE Jacopo Mondi
  2020-11-19 16:35   ` [PATCH v4 22/30] media: ov5647: Support V4L2_CID_HBLANK control Jacopo Mondi
@ 2020-11-19 16:35   ` Jacopo Mondi
  2020-11-19 16:35   ` [PATCH v4 24/30] media: ov5647: Advertise the correct exposure range Jacopo Mondi
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:35 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Dave Stevenson, Jacopo Mondi

From: Dave Stevenson <dave.stevenson@raspberrypi.com>

Adds vblank control to allow for frame rate control.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 50 +++++++++++++++++++++++++++++++++++---
 1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 2ffca9f658bfa..654009be0d110 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -50,6 +50,8 @@
 #define OV5647_REG_AEC_AGC		0x3503
 #define OV5647_REG_GAIN_HI		0x350a
 #define OV5647_REG_GAIN_LO		0x350b
+#define OV5647_REG_VTS_HI		0x380e
+#define OV5647_REG_VTS_LO		0x380f
 #define OV5647_REG_FRAME_OFF_NUMBER	0x4202
 #define OV5647_REG_MIPI_CTRL00		0x4800
 #define OV5647_REG_MIPI_CTRL14		0x4814
@@ -68,6 +70,9 @@
 #define OV5647_PIXEL_ARRAY_WIDTH	2592U
 #define OV5647_PIXEL_ARRAY_HEIGHT	1944U
 
+#define OV5647_VBLANK_MIN		4
+#define OV5647_VTS_MAX			32767
+
 struct regval_list {
 	u16 addr;
 	u8 data;
@@ -78,6 +83,7 @@ struct ov5647_mode {
 	struct v4l2_rect		crop;
 	u64				pixel_rate;
 	int				hts;
+	int				vts;
 	const struct regval_list	*reg_list;
 	unsigned int			num_regs;
 };
@@ -100,6 +106,7 @@ struct ov5647 {
 	const struct ov5647_mode	*mode;
 	struct v4l2_ctrl		*pixel_rate;
 	struct v4l2_ctrl		*hblank;
+	struct v4l2_ctrl		*vblank;
 };
 
 static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd)
@@ -151,8 +158,6 @@ static const struct regval_list ov5647_640x480_8bpp[] = {
 	{0x3b07, 0x0c},
 	{0x380c, 0x07},
 	{0x380d, 0x68},
-	{0x380e, 0x03},
-	{0x380f, 0xd8},
 	{0x3814, 0x31},
 	{0x3815, 0x31},
 	{0x3708, 0x64},
@@ -588,6 +593,7 @@ static const struct ov5647_mode ov5647_8bpp_modes[] = {
 		},
 		.pixel_rate	= 77291670,
 		.hts		= 1896,
+		.vts		= 0x3d8,
 		.reg_list	= ov5647_640x480_8bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_640x480_8bpp)
 	},
@@ -611,6 +617,7 @@ static const struct ov5647_mode ov5647_10bpp_modes[] = {
 		},
 		.pixel_rate	= 87500000,
 		.hts		= 2844,
+		.vts		= 0x7b0,
 		.reg_list	= ov5647_2592x1944_10bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_2592x1944_10bpp)
 	},
@@ -631,6 +638,7 @@ static const struct ov5647_mode ov5647_10bpp_modes[] = {
 		},
 		.pixel_rate	= 81666700,
 		.hts		= 2416,
+		.vts		= 0x450,
 		.reg_list	= ov5647_1080p30_10bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_1080p30_10bpp)
 	},
@@ -651,6 +659,7 @@ static const struct ov5647_mode ov5647_10bpp_modes[] = {
 		},
 		.pixel_rate	= 81666700,
 		.hts		= 1896,
+		.vts		= 0x59b,
 		.reg_list	= ov5647_2x2binned_10bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_2x2binned_10bpp)
 	},
@@ -671,6 +680,7 @@ static const struct ov5647_mode ov5647_10bpp_modes[] = {
 		},
 		.pixel_rate	= 55000000,
 		.hts		= 1852,
+		.vts		= 0x1f8,
 		.reg_list	= ov5647_640x480_10bpp,
 		.num_regs	= ARRAY_SIZE(ov5647_640x480_10bpp)
 	},
@@ -695,6 +705,22 @@ static const struct ov5647_format_list ov5647_formats[] = {
 #define OV5647_DEFAULT_MODE	(&ov5647_formats[1].modes[3])
 #define OV5647_DEFAULT_FORMAT	(ov5647_formats[1].modes[3].format)
 
+static int ov5647_write16(struct v4l2_subdev *sd, u16 reg, u16 val)
+{
+	unsigned char data[4] = { reg >> 8, reg & 0xff, val >> 8, val & 0xff};
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret;
+
+	ret = i2c_master_send(client, data, 4);
+	if (ret < 0) {
+		dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
+			__func__, reg);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val)
 {
 	unsigned char data[3] = { reg >> 8, reg & 0xff, val};
@@ -1097,7 +1123,7 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd,
 	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
 		*v4l2_subdev_get_try_format(sd, cfg, format->pad) = mode->format;
 	} else {
-		int hblank;
+		int hblank, vblank;
 
 		sensor->mode = mode;
 		__v4l2_ctrl_modify_range(sensor->pixel_rate, mode->pixel_rate,
@@ -1106,6 +1132,12 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd,
 		hblank = mode->hts - mode->format.width;
 		__v4l2_ctrl_modify_range(sensor->hblank, hblank, hblank, 1,
 					 hblank);
+
+		vblank = mode->vts - mode->format.height;
+		__v4l2_ctrl_modify_range(sensor->vblank, OV5647_VBLANK_MIN,
+					 OV5647_VTS_MAX - mode->format.height,
+					 1, vblank);
+		__v4l2_ctrl_s_ctrl(sensor->vblank, vblank);
 	}
 	*fmt = mode->format;
 	mutex_unlock(&sensor->lock);
@@ -1317,6 +1349,9 @@ static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_HBLANK:
 		/* Read-only, but we adjust it based on mode. */
 		return 0;
+	case V4L2_CID_VBLANK:
+		return ov5647_write16(sd, OV5647_REG_VTS_HI,
+				      sensor->mode->format.height + ctrl->val);
 	default:
 		dev_info(&client->dev,
 			 "Control (id:0x%x, val:0x%x) not supported\n",
@@ -1336,7 +1371,7 @@ static int ov5647_init_controls(struct ov5647 *sensor)
 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
 	int hblank;
 
-	v4l2_ctrl_handler_init(&sensor->ctrls, 7);
+	v4l2_ctrl_handler_init(&sensor->ctrls, 8);
 
 	v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
 			  V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
@@ -1369,6 +1404,13 @@ static int ov5647_init_controls(struct ov5647 *sensor)
 					   V4L2_CID_HBLANK, hblank, hblank, 1,
 					   hblank);
 
+	sensor->vblank = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
+					   V4L2_CID_VBLANK, OV5647_VBLANK_MIN,
+					   OV5647_VTS_MAX -
+					   sensor->mode->format.height, 1,
+					   sensor->mode->vts -
+					   sensor->mode->format.height);
+
 	if (sensor->ctrls.error)
 		goto handler_free;
 
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 24/30] media: ov5647: Advertise the correct exposure range
  2020-11-19 16:35 ` [PATCH v4 20/30] media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag Jacopo Mondi
                     ` (2 preceding siblings ...)
  2020-11-19 16:35   ` [PATCH v4 23/30] media: ov5647: Support V4L2_CID_VBLANK control Jacopo Mondi
@ 2020-11-19 16:35   ` Jacopo Mondi
  2020-11-19 16:35   ` [PATCH v4 25/30] media: ov5647: Use pm_runtime infrastructure Jacopo Mondi
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:35 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Dave Stevenson, Jacopo Mondi

From: Dave Stevenson <dave.stevenson@raspberrypi.com>

Exposure is clipped by the VTS of the mode, so it needs to be updated
when this is changed.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 39 ++++++++++++++++++++++++++++++++++----
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 654009be0d110..70eafc5390e1f 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -73,6 +73,11 @@
 #define OV5647_VBLANK_MIN		4
 #define OV5647_VTS_MAX			32767
 
+#define OV5647_EXPOSURE_MIN		4
+#define OV5647_EXPOSURE_STEP		1
+#define OV5647_EXPOSURE_DEFAULT		1000
+#define OV5647_EXPOSURE_MAX		65535
+
 struct regval_list {
 	u16 addr;
 	u8 data;
@@ -107,6 +112,7 @@ struct ov5647 {
 	struct v4l2_ctrl		*pixel_rate;
 	struct v4l2_ctrl		*hblank;
 	struct v4l2_ctrl		*vblank;
+	struct v4l2_ctrl		*exposure;
 };
 
 static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd)
@@ -1092,6 +1098,7 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd,
 	struct v4l2_mbus_framefmt *fmt = &format->format;
 	const struct ov5647_mode *ov5647_mode_list;
 	struct ov5647 *sensor = to_sensor(sd);
+
 	const struct ov5647_mode *mode;
 	unsigned int num_modes;
 	unsigned int i;
@@ -1123,6 +1130,7 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd,
 	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
 		*v4l2_subdev_get_try_format(sd, cfg, format->pad) = mode->format;
 	} else {
+		int exposure_max, exposure_def;
 		int hblank, vblank;
 
 		sensor->mode = mode;
@@ -1138,6 +1146,13 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd,
 					 OV5647_VTS_MAX - mode->format.height,
 					 1, vblank);
 		__v4l2_ctrl_s_ctrl(sensor->vblank, vblank);
+
+		exposure_max = mode->vts - 4;
+		exposure_def = min(exposure_max, OV5647_EXPOSURE_DEFAULT);
+		__v4l2_ctrl_modify_range(sensor->exposure,
+					 sensor->exposure->minimum,
+					 exposure_max, sensor->exposure->step,
+					 exposure_def);
 	}
 	*fmt = mode->format;
 	mutex_unlock(&sensor->lock);
@@ -1324,6 +1339,18 @@ static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl)
 
 	/* v4l2_ctrl_lock() locks our own mutex */
 
+	if (ctrl->id == V4L2_CID_VBLANK) {
+		int exposure_max, exposure_def;
+
+		/* Update max exposure while meeting expected vblanking */
+		exposure_max = sensor->mode->format.height + ctrl->val - 4;
+		exposure_def = min(exposure_max, OV5647_EXPOSURE_DEFAULT);
+		__v4l2_ctrl_modify_range(sensor->exposure,
+					 sensor->exposure->minimum,
+					 exposure_max, sensor->exposure->step,
+					 exposure_def);
+	}
+
 	/*
 	 * If the device is not powered up by the host driver do
 	 * not apply any controls to H/W at this time. Instead
@@ -1369,7 +1396,7 @@ static const struct v4l2_ctrl_ops ov5647_ctrl_ops = {
 static int ov5647_init_controls(struct ov5647 *sensor)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
-	int hblank;
+	int hblank, exposure_max, exposure_def;
 
 	v4l2_ctrl_handler_init(&sensor->ctrls, 8);
 
@@ -1383,9 +1410,13 @@ static int ov5647_init_controls(struct ov5647 *sensor)
 			       V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL,
 			       0, V4L2_EXPOSURE_MANUAL);
 
-	/* min: 4 lines; max: 0xffff lines; default: 1000 lines. */
-	v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
-			  V4L2_CID_EXPOSURE, 4, 65535, 1, 1000);
+	exposure_max = sensor->mode->vts - 4;
+	exposure_def = min(exposure_max, OV5647_EXPOSURE_DEFAULT);
+	sensor->exposure = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
+					     V4L2_CID_EXPOSURE,
+					     OV5647_EXPOSURE_MIN,
+					     exposure_max, OV5647_EXPOSURE_STEP,
+					     exposure_def);
 
 	/* min: 16 = 1.0x; max (10 bits); default: 32 = 2.0x. */
 	v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 25/30] media: ov5647: Use pm_runtime infrastructure
  2020-11-19 16:35 ` [PATCH v4 20/30] media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag Jacopo Mondi
                     ` (3 preceding siblings ...)
  2020-11-19 16:35   ` [PATCH v4 24/30] media: ov5647: Advertise the correct exposure range Jacopo Mondi
@ 2020-11-19 16:35   ` Jacopo Mondi
  2020-11-19 16:35   ` [PATCH v4 26/30] media: ov5647: Rework s_stream() operation Jacopo Mondi
                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:35 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

Use the pm_runtime framework to replace the legacy s_power() operation.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 142 ++++++++++++++++++-------------------
 1 file changed, 71 insertions(+), 71 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 70eafc5390e1f..777c7b30bafd7 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -19,6 +19,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of_graph.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-ctrls.h>
@@ -881,86 +882,75 @@ static int ov5647_stream_off(struct v4l2_subdev *sd)
 	return ov5647_write(sd, OV5640_REG_PAD_OUT, 0x01);
 }
 
-static int set_sw_standby(struct v4l2_subdev *sd, bool standby)
+static int ov5647_power_on(struct device *dev)
 {
+	struct ov5647 *sensor = dev_get_drvdata(dev);
 	int ret;
-	u8 rdval;
 
-	ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval);
-	if (ret < 0)
-		return ret;
+	dev_dbg(dev, "OV5647 power on\n");
 
-	if (standby)
-		rdval &= ~0x01;
-	else
-		rdval |= 0x01;
-
-	return ov5647_write(sd, OV5647_SW_STANDBY, rdval);
-}
+	if (sensor->pwdn) {
+		gpiod_set_value_cansleep(sensor->pwdn, 0);
+		msleep(PWDN_ACTIVE_DELAY_MS);
+	}
 
-static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct ov5647 *sensor = to_sensor(sd);
-	int ret = 0;
+	ret = clk_prepare_enable(sensor->xclk);
+	if (ret < 0) {
+		dev_err(dev, "clk prepare enable failed\n");
+		goto error_pwdn;
+	}
 
-	mutex_lock(&sensor->lock);
+	ret = ov5647_write_array(&sensor->sd, sensor_oe_enable_regs,
+				 ARRAY_SIZE(sensor_oe_enable_regs));
+	if (ret < 0) {
+		dev_err(dev, "write sensor_oe_enable_regs error\n");
+		goto error_clk_disable;
+	}
 
-	if (on && !sensor->power_count)	{
-		dev_dbg(&client->dev, "OV5647 power on\n");
+	/* Stream off to coax lanes into LP-11 state. */
+	ret = ov5647_stream_off(&sensor->sd);
+	if (ret < 0) {
+		dev_err(dev, "camera not available, check power\n");
+		goto error_clk_disable;
+	}
 
-		if (sensor->pwdn) {
-			gpiod_set_value_cansleep(sensor->pwdn, 0);
-			msleep(PWDN_ACTIVE_DELAY_MS);
-		}
+	return 0;
 
-		ret = clk_prepare_enable(sensor->xclk);
-		if (ret < 0) {
-			dev_err(&client->dev, "clk prepare enable failed\n");
-			goto out;
-		}
+error_clk_disable:
+	clk_disable_unprepare(sensor->xclk);
+error_pwdn:
+	gpiod_set_value_cansleep(sensor->pwdn, 1);
 
-		ret = ov5647_write_array(sd, sensor_oe_enable_regs,
-					 ARRAY_SIZE(sensor_oe_enable_regs));
-		if (ret < 0) {
-			clk_disable_unprepare(sensor->xclk);
-			dev_err(&client->dev,
-				"write sensor_oe_enable_regs error\n");
-			goto out;
-		}
+	return ret;
+}
 
-		/* Stream off to coax lanes into LP-11 state. */
-		ret = ov5647_stream_off(sd);
-		if (ret < 0) {
-			clk_disable_unprepare(sensor->xclk);
-			dev_err(&client->dev,
-				"Camera not available, check Power\n");
-			goto out;
-		}
-	} else if (!on && sensor->power_count == 1) {
-		dev_dbg(&client->dev, "OV5647 power off\n");
+static int ov5647_power_off(struct device *dev)
+{
+	struct ov5647 *sensor = dev_get_drvdata(dev);
+	u8 rdval;
+	int ret;
 
-		ret = ov5647_write_array(sd, sensor_oe_disable_regs,
-					 ARRAY_SIZE(sensor_oe_disable_regs));
-		if (ret < 0)
-			dev_dbg(&client->dev, "disable oe failed\n");
+	dev_dbg(dev, "OV5647 power off\n");
 
-		ret = set_sw_standby(sd, true);
-		if (ret < 0)
-			dev_dbg(&client->dev, "soft stby failed\n");
+	ret = ov5647_write_array(&sensor->sd, sensor_oe_disable_regs,
+				 ARRAY_SIZE(sensor_oe_disable_regs));
+	if (ret < 0)
+		dev_dbg(dev, "disable oe failed\n");
 
-		clk_disable_unprepare(sensor->xclk);
-		gpiod_set_value_cansleep(sensor->pwdn, 1);
-	}
+	/* Enter software standby */
+	ret = ov5647_read(&sensor->sd, OV5647_SW_STANDBY, &rdval);
+	if (ret < 0)
+		dev_dbg(dev, "software standby failed\n");
 
-	/* Update the power count. */
-	sensor->power_count += on ? 1 : -1;
-	WARN_ON(sensor->power_count < 0);
+	rdval &= ~0x01;
+	ret = ov5647_write(&sensor->sd, OV5647_SW_STANDBY, rdval);
+	if (ret < 0)
+		dev_dbg(dev, "software standby failed\n");
 
-out:
-	mutex_unlock(&sensor->lock);
+	clk_disable_unprepare(sensor->xclk);
+	gpiod_set_value_cansleep(sensor->pwdn, 1);
 
-	return ret;
+	return 0;
 }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -989,7 +979,6 @@ static int ov5647_sensor_set_register(struct v4l2_subdev *sd,
 
 /* Subdev core operations registration */
 static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = {
-	.s_power		= ov5647_sensor_power,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register		= ov5647_sensor_get_register,
 	.s_register		= ov5647_sensor_set_register,
@@ -1543,24 +1532,29 @@ static int ov5647_probe(struct i2c_client *client)
 	if (ret < 0)
 		goto ctrl_handler_free;
 
-	if (sensor->pwdn) {
-		gpiod_set_value_cansleep(sensor->pwdn, 0);
-		msleep(PWDN_ACTIVE_DELAY_MS);
-	}
+	ret = ov5647_power_on(dev);
+	if (ret)
+		goto entity_cleanup;
 
 	ret = ov5647_detect(sd);
-	gpiod_set_value_cansleep(sensor->pwdn, 1);
 	if (ret < 0)
-		goto entity_cleanup;
+		goto power_off;
 
 	ret = v4l2_async_register_subdev(sd);
 	if (ret < 0)
-		goto entity_cleanup;
+		goto power_off;
+
+	/* Enable runtime PM and turn off the device */
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_idle(dev);
 
 	dev_dbg(dev, "OmniVision OV5647 camera driver probed\n");
 
 	return 0;
 
+power_off:
+	ov5647_power_off(dev);
 entity_cleanup:
 	media_entity_cleanup(&sd->entity);
 ctrl_handler_free:
@@ -1580,11 +1574,16 @@ static int ov5647_remove(struct i2c_client *client)
 	media_entity_cleanup(&sensor->sd.entity);
 	v4l2_ctrl_handler_free(&sensor->ctrls);
 	v4l2_device_unregister_subdev(sd);
+	pm_runtime_disable(&client->dev);
 	mutex_destroy(&sensor->lock);
 
 	return 0;
 }
 
+static const struct dev_pm_ops ov5647_pm_ops = {
+	SET_RUNTIME_PM_OPS(ov5647_power_off, ov5647_power_on, NULL)
+};
+
 static const struct i2c_device_id ov5647_id[] = {
 	{ "ov5647", 0 },
 	{ /* sentinel */ }
@@ -1603,6 +1602,7 @@ static struct i2c_driver ov5647_driver = {
 	.driver = {
 		.of_match_table = of_match_ptr(ov5647_of_match),
 		.name	= "ov5647",
+		.pm	= &ov5647_pm_ops,
 	},
 	.probe_new	= ov5647_probe,
 	.remove		= ov5647_remove,
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 26/30] media: ov5647: Rework s_stream() operation
  2020-11-19 16:35 ` [PATCH v4 20/30] media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag Jacopo Mondi
                     ` (4 preceding siblings ...)
  2020-11-19 16:35   ` [PATCH v4 25/30] media: ov5647: Use pm_runtime infrastructure Jacopo Mondi
@ 2020-11-19 16:35   ` Jacopo Mondi
  2020-11-19 16:35   ` [PATCH v4 27/30] media: ov5647: Apply controls only when powered Jacopo Mondi
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:35 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

Rework the s_stream() operation to turn the sensor on and
off at stream enable/disable time using the pm_runtime infrastructure.

Protect the stream on/off from being called multiple times in
sequence with a 'streaming' flag.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 777c7b30bafd7..1ac1538a3951f 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -114,6 +114,7 @@ struct ov5647 {
 	struct v4l2_ctrl		*hblank;
 	struct v4l2_ctrl		*vblank;
 	struct v4l2_ctrl		*exposure;
+	bool				streaming;
 };
 
 static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd)
@@ -1001,14 +1002,42 @@ __ov5647_get_pad_crop(struct ov5647 *ov5647, struct v4l2_subdev_pad_config *cfg,
 
 static int ov5647_s_stream(struct v4l2_subdev *sd, int enable)
 {
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct ov5647 *sensor = to_sensor(sd);
 	int ret;
 
 	mutex_lock(&sensor->lock);
-	if (enable)
+	if (sensor->streaming == enable) {
+		mutex_unlock(&sensor->lock);
+		return 0;
+	}
+
+	if (enable) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0)
+			goto error_unlock;
+
 		ret = ov5647_stream_on(sd);
-	else
+		if (ret < 0) {
+			dev_err(&client->dev, "stream start failed: %d\n", ret);
+			goto error_unlock;
+		}
+	} else {
 		ret = ov5647_stream_off(sd);
+		if (ret < 0) {
+			dev_err(&client->dev, "stream stop failed: %d\n", ret);
+			goto error_unlock;
+		}
+		pm_runtime_put(&client->dev);
+	}
+
+	sensor->streaming = enable;
+	mutex_unlock(&sensor->lock);
+
+	return 0;
+
+error_unlock:
+	pm_runtime_put(&client->dev);
 	mutex_unlock(&sensor->lock);
 
 	return ret;
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 27/30] media: ov5647: Apply controls only when powered
  2020-11-19 16:35 ` [PATCH v4 20/30] media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag Jacopo Mondi
                     ` (5 preceding siblings ...)
  2020-11-19 16:35   ` [PATCH v4 26/30] media: ov5647: Rework s_stream() operation Jacopo Mondi
@ 2020-11-19 16:35   ` Jacopo Mondi
  2020-11-19 16:35   ` [PATCH v4 28/30] media: ov5647: Constify oe_enable/disable reglist Jacopo Mondi
  2020-11-19 16:35   ` [PATCH v4 29/30] media: ov5647: Support VIDIOC_SUBSCRIBE_EVENT Jacopo Mondi
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:35 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

Use pm_runtime_get_if_in_use() in s_ctrl to apply controls
only when the device is powered on.

Rework the control set function to balance the
pm_runtime_get_if_in_use() call with
pm_runtime_put() at the end of the function.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 44 +++++++++++++++++++++++---------------
 1 file changed, 27 insertions(+), 17 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 1ac1538a3951f..8061058e6df85 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -104,7 +104,6 @@ struct ov5647 {
 	struct v4l2_subdev		sd;
 	struct media_pad		pad;
 	struct mutex			lock;
-	int				power_count;
 	struct clk			*xclk;
 	struct gpio_desc		*pwdn;
 	bool				clock_ncont;
@@ -1354,6 +1353,8 @@ static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl)
 					    struct ov5647, ctrls);
 	struct v4l2_subdev *sd = &sensor->sd;
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret = 0;
+
 
 	/* v4l2_ctrl_lock() locks our own mutex */
 
@@ -1370,33 +1371,40 @@ static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl)
 	}
 
 	/*
-	 * If the device is not powered up by the host driver do
-	 * not apply any controls to H/W at this time. Instead
-	 * the controls will be restored at s_stream(1) time.
+	 * If the device is not powered up do not apply any controls
+	 * to H/W at this time. Instead the controls will be restored
+	 * at s_stream(1) time.
 	 */
-	if (!sensor->power_count)
+	if (pm_runtime_get_if_in_use(&client->dev) == 0)
 		return 0;
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUTO_WHITE_BALANCE:
-		return ov5647_s_auto_white_balance(sd, ctrl->val);
+		ret = ov5647_s_auto_white_balance(sd, ctrl->val);
+		break;
 	case V4L2_CID_AUTOGAIN:
-		return ov5647_s_autogain(sd, ctrl->val);
+		ret = ov5647_s_autogain(sd, ctrl->val);
+		break;
 	case V4L2_CID_EXPOSURE_AUTO:
-		return ov5647_s_exposure_auto(sd, ctrl->val);
+		ret = ov5647_s_exposure_auto(sd, ctrl->val);
+		break;
 	case V4L2_CID_ANALOGUE_GAIN:
-		return  ov5647_s_analogue_gain(sd, ctrl->val);
+		ret =  ov5647_s_analogue_gain(sd, ctrl->val);
+		break;
 	case V4L2_CID_EXPOSURE:
-		return ov5647_s_exposure(sd, ctrl->val);
+		ret = ov5647_s_exposure(sd, ctrl->val);
+		break;
+	case V4L2_CID_VBLANK:
+		ret = ov5647_write16(sd, OV5647_REG_VTS_HI,
+				     sensor->mode->format.height + ctrl->val);
+		break;
+
+	/* Read-only, but we adjust it based on mode. */
 	case V4L2_CID_PIXEL_RATE:
-		/* Read-only, but we adjust it based on mode. */
-		return 0;
 	case V4L2_CID_HBLANK:
 		/* Read-only, but we adjust it based on mode. */
-		return 0;
-	case V4L2_CID_VBLANK:
-		return ov5647_write16(sd, OV5647_REG_VTS_HI,
-				      sensor->mode->format.height + ctrl->val);
+		break;
+
 	default:
 		dev_info(&client->dev,
 			 "Control (id:0x%x, val:0x%x) not supported\n",
@@ -1404,7 +1412,9 @@ static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl)
 		return -EINVAL;
 	}
 
-	return 0;
+	pm_runtime_put(&client->dev);
+
+	return ret;
 }
 
 static const struct v4l2_ctrl_ops ov5647_ctrl_ops = {
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 28/30] media: ov5647: Constify oe_enable/disable reglist
  2020-11-19 16:35 ` [PATCH v4 20/30] media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag Jacopo Mondi
                     ` (6 preceding siblings ...)
  2020-11-19 16:35   ` [PATCH v4 27/30] media: ov5647: Apply controls only when powered Jacopo Mondi
@ 2020-11-19 16:35   ` Jacopo Mondi
  2020-11-19 16:35   ` [PATCH v4 29/30] media: ov5647: Support VIDIOC_SUBSCRIBE_EVENT Jacopo Mondi
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:35 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

Make the two register-value lists const.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 8061058e6df85..963f516562667 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -121,13 +121,13 @@ static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd)
 	return container_of(sd, struct ov5647, sd);
 }
 
-static struct regval_list sensor_oe_disable_regs[] = {
+static const struct regval_list sensor_oe_disable_regs[] = {
 	{0x3000, 0x00},
 	{0x3001, 0x00},
 	{0x3002, 0x00},
 };
 
-static struct regval_list sensor_oe_enable_regs[] = {
+static const struct regval_list sensor_oe_enable_regs[] = {
 	{0x3000, 0x0f},
 	{0x3001, 0xff},
 	{0x3002, 0xe4},
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 29/30] media: ov5647: Support VIDIOC_SUBSCRIBE_EVENT
  2020-11-19 16:35 ` [PATCH v4 20/30] media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag Jacopo Mondi
                     ` (7 preceding siblings ...)
  2020-11-19 16:35   ` [PATCH v4 28/30] media: ov5647: Constify oe_enable/disable reglist Jacopo Mondi
@ 2020-11-19 16:35   ` Jacopo Mondi
  8 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:35 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

The driver reports the V4L2_SUBDEV_FL_HAS_EVENTS flag but does not
support subscribing and unsubscribing to events.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 963f516562667..be40c60ab7ee6 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -24,6 +24,7 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-image-sizes.h>
 #include <media/v4l2-mediabus.h>
@@ -979,6 +980,8 @@ static int ov5647_sensor_set_register(struct v4l2_subdev *sd,
 
 /* Subdev core operations registration */
 static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = {
+	.subscribe_event	= v4l2_ctrl_subdev_subscribe_event,
+	.unsubscribe_event	= v4l2_event_subdev_unsubscribe,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register		= ov5647_sensor_get_register,
 	.s_register		= ov5647_sensor_set_register,
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 30/30] media: ov5647: Remove 640x480 SBGGR8 mode
  2020-11-19 16:19 [PATCH v4 00/30] media: ov5647: Support RaspberryPi Camera Module v1 Jacopo Mondi
                   ` (10 preceding siblings ...)
  2020-11-19 16:35 ` [PATCH v4 20/30] media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag Jacopo Mondi
@ 2020-11-19 16:37 ` Jacopo Mondi
  11 siblings, 0 replies; 39+ messages in thread
From: Jacopo Mondi @ 2020-11-19 16:37 UTC (permalink / raw)
  To: linux-media
  Cc: mchehab, sakari.ailus, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, Jacopo Mondi

Capturing in 640x480 SBGGR8_1X8 hangs the system when capturing
with the unicam driver on RaspberryPi 4 platform.

Remove it and remove the support for multiple media bus codes in
the driver.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 drivers/media/i2c/ov5647.c | 180 ++-----------------------------------
 1 file changed, 9 insertions(+), 171 deletions(-)

diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index be40c60ab7ee6..1cefa15729ce3 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -95,12 +95,6 @@ struct ov5647_mode {
 	unsigned int			num_regs;
 };
 
-struct ov5647_format_list {
-	unsigned int			mbus_code;
-	const struct ov5647_mode	*modes;
-	unsigned int			num_modes;
-};
-
 struct ov5647 {
 	struct v4l2_subdev		sd;
 	struct media_pad		pad;
@@ -134,94 +128,6 @@ static const struct regval_list sensor_oe_enable_regs[] = {
 	{0x3002, 0xe4},
 };
 
-static const struct regval_list ov5647_640x480_8bpp[] = {
-	{0x0100, 0x00},
-	{0x0103, 0x01},
-	{0x3034, 0x08},
-	{0x3035, 0x21},
-	{0x3036, 0x46},
-	{0x303c, 0x11},
-	{0x3106, 0xf5},
-	{0x3821, 0x07},
-	{0x3820, 0x41},
-	{0x3827, 0xec},
-	{0x370c, 0x0f},
-	{0x3612, 0x59},
-	{0x3618, 0x00},
-	{0x5000, 0x06},
-	{0x5002, 0x41},
-	{0x5003, 0x08},
-	{0x5a00, 0x08},
-	{0x3000, 0x00},
-	{0x3001, 0x00},
-	{0x3002, 0x00},
-	{0x3016, 0x08},
-	{0x3017, 0xe0},
-	{0x3018, 0x44},
-	{0x301c, 0xf8},
-	{0x301d, 0xf0},
-	{0x3a18, 0x00},
-	{0x3a19, 0xf8},
-	{0x3c01, 0x80},
-	{0x3b07, 0x0c},
-	{0x380c, 0x07},
-	{0x380d, 0x68},
-	{0x3814, 0x31},
-	{0x3815, 0x31},
-	{0x3708, 0x64},
-	{0x3709, 0x52},
-	{0x3808, 0x02},
-	{0x3809, 0x80},
-	{0x380a, 0x01},
-	{0x380b, 0xe0},
-	{0x3801, 0x00},
-	{0x3802, 0x00},
-	{0x3803, 0x00},
-	{0x3804, 0x0a},
-	{0x3805, 0x3f},
-	{0x3806, 0x07},
-	{0x3807, 0xa1},
-	{0x3811, 0x08},
-	{0x3813, 0x02},
-	{0x3630, 0x2e},
-	{0x3632, 0xe2},
-	{0x3633, 0x23},
-	{0x3634, 0x44},
-	{0x3636, 0x06},
-	{0x3620, 0x64},
-	{0x3621, 0xe0},
-	{0x3600, 0x37},
-	{0x3704, 0xa0},
-	{0x3703, 0x5a},
-	{0x3715, 0x78},
-	{0x3717, 0x01},
-	{0x3731, 0x02},
-	{0x370b, 0x60},
-	{0x3705, 0x1a},
-	{0x3f05, 0x02},
-	{0x3f06, 0x10},
-	{0x3f01, 0x0a},
-	{0x3a08, 0x01},
-	{0x3a09, 0x27},
-	{0x3a0a, 0x00},
-	{0x3a0b, 0xf6},
-	{0x3a0d, 0x04},
-	{0x3a0e, 0x03},
-	{0x3a0f, 0x58},
-	{0x3a10, 0x50},
-	{0x3a1b, 0x58},
-	{0x3a1e, 0x50},
-	{0x3a11, 0x60},
-	{0x3a1f, 0x28},
-	{0x4001, 0x02},
-	{0x4004, 0x02},
-	{0x4000, 0x09},
-	{0x4837, 0x24},
-	{0x4050, 0x6e},
-	{0x4051, 0x8f},
-	{0x0100, 0x01},
-};
-
 static struct regval_list ov5647_2592x1944_10bpp[] = {
 	{0x0100, 0x00},
 	{0x0103, 0x01},
@@ -583,31 +489,7 @@ static struct regval_list ov5647_640x480_10bpp[] = {
 	{0x0100, 0x01},
 };
 
-static const struct ov5647_mode ov5647_8bpp_modes[] = {
-	/* 8-bit VGA mode: Uncentred crop 2x2 binned 1296x972 image. */
-	{
-		.format	= {
-			.code		= MEDIA_BUS_FMT_SBGGR8_1X8,
-			.colorspace	= V4L2_COLORSPACE_SRGB,
-			.field		= V4L2_FIELD_NONE,
-			.width		= 640,
-			.height		= 480
-		},
-		.crop = {
-			.left		= OV5647_PIXEL_ARRAY_LEFT,
-			.top		= OV5647_PIXEL_ARRAY_TOP,
-			.width		= 1280,
-			.height		= 960,
-		},
-		.pixel_rate	= 77291670,
-		.hts		= 1896,
-		.vts		= 0x3d8,
-		.reg_list	= ov5647_640x480_8bpp,
-		.num_regs	= ARRAY_SIZE(ov5647_640x480_8bpp)
-	},
-};
-
-static const struct ov5647_mode ov5647_10bpp_modes[] = {
+static const struct ov5647_mode ov5647_modes[] = {
 	/* 2592x1944 full resolution full FOV 10-bit mode. */
 	{
 		.format = {
@@ -694,24 +576,9 @@ static const struct ov5647_mode ov5647_10bpp_modes[] = {
 	},
 };
 
-static const struct ov5647_format_list ov5647_formats[] = {
-	{
-		.mbus_code	= MEDIA_BUS_FMT_SBGGR8_1X8,
-		.modes		= ov5647_8bpp_modes,
-		.num_modes	= ARRAY_SIZE(ov5647_8bpp_modes),
-	},
-	{
-		.mbus_code	= MEDIA_BUS_FMT_SBGGR10_1X10,
-		.modes		= ov5647_10bpp_modes,
-		.num_modes	= ARRAY_SIZE(ov5647_10bpp_modes),
-	},
-};
-
-#define OV5647_NUM_FORMATS	(ARRAY_SIZE(ov5647_formats))
-
 /* Default sensor mode is 2x2 binned 640x480 SBGGR10_1X10. */
-#define OV5647_DEFAULT_MODE	(&ov5647_formats[1].modes[3])
-#define OV5647_DEFAULT_FORMAT	(ov5647_formats[1].modes[3].format)
+#define OV5647_DEFAULT_MODE	(&ov5647_modes[3])
+#define OV5647_DEFAULT_FORMAT	(ov5647_modes[3].format)
 
 static int ov5647_write16(struct v4l2_subdev *sd, u16 reg, u16 val)
 {
@@ -1053,10 +920,10 @@ static int ov5647_enum_mbus_code(struct v4l2_subdev *sd,
 				 struct v4l2_subdev_pad_config *cfg,
 				 struct v4l2_subdev_mbus_code_enum *code)
 {
-	if (code->index >= OV5647_NUM_FORMATS)
+	if (code->index > 0)
 		return -EINVAL;
 
-	code->code = ov5647_formats[code->index].mbus_code;
+	code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
 
 	return 0;
 }
@@ -1066,19 +933,12 @@ static int ov5647_enum_frame_size(struct v4l2_subdev *sd,
 				  struct v4l2_subdev_frame_size_enum *fse)
 {
 	const struct v4l2_mbus_framefmt *fmt;
-	unsigned int i = 0;
 
-	for (; i < OV5647_NUM_FORMATS; ++i) {
-		if (ov5647_formats[i].mbus_code == fse->code)
-			break;
-	}
-	if (i == OV5647_NUM_FORMATS)
+	if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10 ||
+	    fse->index >= ARRAY_SIZE(ov5647_modes))
 		return -EINVAL;
 
-	if (fse->index >= ov5647_formats[i].num_modes)
-		return -EINVAL;
-
-	fmt = &ov5647_formats[i].modes[fse->index].format;
+	fmt = &ov5647_modes[fse->index].format;
 	fse->min_width = fmt->width;
 	fse->max_width = fmt->width;
 	fse->min_height = fmt->height;
@@ -1116,32 +976,10 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd,
 			      struct v4l2_subdev_format *format)
 {
 	struct v4l2_mbus_framefmt *fmt = &format->format;
-	const struct ov5647_mode *ov5647_mode_list;
 	struct ov5647 *sensor = to_sensor(sd);
-
 	const struct ov5647_mode *mode;
-	unsigned int num_modes;
-	unsigned int i;
-
-	for (i = 0; i < OV5647_NUM_FORMATS; ++i) {
-		if (ov5647_formats[i].mbus_code != fmt->code)
-			continue;
-
-		ov5647_mode_list = ov5647_formats[i].modes;
-		num_modes = ov5647_formats[i].num_modes;
-		break;
-	}
-
-	/*
-	 * Default mbus code MEDIA_BUS_FMT_SBGGR10_1X10 if the requested one is
-	 * not supported.
-	 */
-	if (i == OV5647_NUM_FORMATS) {
-		ov5647_mode_list = ov5647_10bpp_modes;
-		num_modes = ARRAY_SIZE(ov5647_10bpp_modes);
-	}
 
-	mode = v4l2_find_nearest_size(ov5647_mode_list, num_modes,
+	mode = v4l2_find_nearest_size(ov5647_modes, ARRAY_SIZE(ov5647_modes),
 				      format.width, format.height,
 				      fmt->width, fmt->height);
 
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 01/30] dt-bindings: media: i2c: Rename ov5647.yaml
  2020-11-19 16:19 ` [PATCH v4 01/30] dt-bindings: media: i2c: Rename ov5647.yaml Jacopo Mondi
@ 2020-11-25  9:15   ` Sakari Ailus
  2020-12-21 17:34     ` Jacopo Mondi
  2020-12-21 20:23     ` Rob Herring
  0 siblings, 2 replies; 39+ messages in thread
From: Sakari Ailus @ 2020-11-25  9:15 UTC (permalink / raw)
  To: Jacopo Mondi
  Cc: linux-media, mchehab, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, devicetree, Rob Herring

Cc Rob + DT list.

On Thu, Nov 19, 2020 at 05:19:27PM +0100, Jacopo Mondi wrote:
> Rename 'ov5647.yaml' as 'ovti,ov5647.yaml' and update the
> MAINTAINERS file entry accordingly.
> 
> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> ---
>  .../bindings/media/i2c/{ov5647.yaml => ovti,ov5647.yaml}        | 0
>  MAINTAINERS                                                     | 2 +-
>  2 files changed, 1 insertion(+), 1 deletion(-)
>  rename Documentation/devicetree/bindings/media/i2c/{ov5647.yaml => ovti,ov5647.yaml} (100%)
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml
> similarity index 100%
> rename from Documentation/devicetree/bindings/media/i2c/ov5647.yaml
> rename to Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 69d55ed67e1cf..3f2acc3a78687 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -12928,7 +12928,7 @@ M:	Jacopo Mondi <jacopo@jmondi.org>
>  L:	linux-media@vger.kernel.org
>  S:	Maintained
>  T:	git git://linuxtv.org/media_tree.git
> -F:	Documentation/devicetree/bindings/media/i2c/ov5647.yaml
> +F:	Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml
>  F:	drivers/media/i2c/ov5647.c
>  
>  OMNIVISION OV5670 SENSOR DRIVER
> -- 
> 2.29.1
> 

-- 
Sakari Ailus

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 01/30] dt-bindings: media: i2c: Rename ov5647.yaml
  2020-11-25  9:15   ` Sakari Ailus
@ 2020-12-21 17:34     ` Jacopo Mondi
  2020-12-22  9:43       ` Sakari Ailus
  2020-12-21 20:23     ` Rob Herring
  1 sibling, 1 reply; 39+ messages in thread
From: Jacopo Mondi @ 2020-12-21 17:34 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, mchehab, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, devicetree, Rob Herring

Hello,

On Wed, Nov 25, 2020 at 11:15:26AM +0200, Sakari Ailus wrote:
> Cc Rob + DT list.
>

Gentle ping.

Sakari, am I mistaken or last time we discussed this, the series is
ready for being collected (pending this ack I assume)

I wonder if it needs a rebase (pretty sure it does)

Thanks
  j

> On Thu, Nov 19, 2020 at 05:19:27PM +0100, Jacopo Mondi wrote:
> > Rename 'ov5647.yaml' as 'ovti,ov5647.yaml' and update the
> > MAINTAINERS file entry accordingly.
> >
> > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> > ---
> >  .../bindings/media/i2c/{ov5647.yaml => ovti,ov5647.yaml}        | 0
> >  MAINTAINERS                                                     | 2 +-
> >  2 files changed, 1 insertion(+), 1 deletion(-)
> >  rename Documentation/devicetree/bindings/media/i2c/{ov5647.yaml => ovti,ov5647.yaml} (100%)
> >
> > diff --git a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml
> > similarity index 100%
> > rename from Documentation/devicetree/bindings/media/i2c/ov5647.yaml
> > rename to Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 69d55ed67e1cf..3f2acc3a78687 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -12928,7 +12928,7 @@ M:	Jacopo Mondi <jacopo@jmondi.org>
> >  L:	linux-media@vger.kernel.org
> >  S:	Maintained
> >  T:	git git://linuxtv.org/media_tree.git
> > -F:	Documentation/devicetree/bindings/media/i2c/ov5647.yaml
> > +F:	Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml
> >  F:	drivers/media/i2c/ov5647.c
> >
> >  OMNIVISION OV5670 SENSOR DRIVER
> > --
> > 2.29.1
> >
>
> --
> Sakari Ailus

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 01/30] dt-bindings: media: i2c: Rename ov5647.yaml
  2020-11-25  9:15   ` Sakari Ailus
  2020-12-21 17:34     ` Jacopo Mondi
@ 2020-12-21 20:23     ` Rob Herring
  2020-12-22  9:50       ` Sakari Ailus
  1 sibling, 1 reply; 39+ messages in thread
From: Rob Herring @ 2020-12-21 20:23 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Jacopo Mondi, Linux Media Mailing List, Mauro Carvalho Chehab,
	Hans Verkuil, Laurent Pinchart, roman.kovalivskyi,
	Dafna Hirschfeld, Dave Stevenson, naush, Eugeniu Rosca,
	devicetree

On Wed, Nov 25, 2020 at 2:15 AM Sakari Ailus
<sakari.ailus@linux.intel.com> wrote:
>
> Cc Rob + DT list.

You have to resend if you really want me to see things. In this case,
I don't think you need to wait on me for a rename.

Acked-by: Rob Herring <robh@kernel.org>

>
> On Thu, Nov 19, 2020 at 05:19:27PM +0100, Jacopo Mondi wrote:
> > Rename 'ov5647.yaml' as 'ovti,ov5647.yaml' and update the
> > MAINTAINERS file entry accordingly.
> >
> > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> > ---
> >  .../bindings/media/i2c/{ov5647.yaml => ovti,ov5647.yaml}        | 0
> >  MAINTAINERS                                                     | 2 +-
> >  2 files changed, 1 insertion(+), 1 deletion(-)
> >  rename Documentation/devicetree/bindings/media/i2c/{ov5647.yaml => ovti,ov5647.yaml} (100%)
> >
> > diff --git a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml
> > similarity index 100%
> > rename from Documentation/devicetree/bindings/media/i2c/ov5647.yaml
> > rename to Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 69d55ed67e1cf..3f2acc3a78687 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -12928,7 +12928,7 @@ M:    Jacopo Mondi <jacopo@jmondi.org>
> >  L:   linux-media@vger.kernel.org
> >  S:   Maintained
> >  T:   git git://linuxtv.org/media_tree.git
> > -F:   Documentation/devicetree/bindings/media/i2c/ov5647.yaml
> > +F:   Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml
> >  F:   drivers/media/i2c/ov5647.c
> >
> >  OMNIVISION OV5670 SENSOR DRIVER
> > --
> > 2.29.1
> >
>
> --
> Sakari Ailus

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 01/30] dt-bindings: media: i2c: Rename ov5647.yaml
  2020-12-21 17:34     ` Jacopo Mondi
@ 2020-12-22  9:43       ` Sakari Ailus
  0 siblings, 0 replies; 39+ messages in thread
From: Sakari Ailus @ 2020-12-22  9:43 UTC (permalink / raw)
  To: Jacopo Mondi
  Cc: linux-media, mchehab, hverkuil, laurent.pinchart,
	roman.kovalivskyi, dafna.hirschfeld, dave.stevenson, naush,
	erosca, devicetree, Rob Herring

Hi Jacopo,

On Mon, Dec 21, 2020 at 06:34:46PM +0100, Jacopo Mondi wrote:
> Hello,
> 
> On Wed, Nov 25, 2020 at 11:15:26AM +0200, Sakari Ailus wrote:
> > Cc Rob + DT list.
> >
> 
> Gentle ping.
> 
> Sakari, am I mistaken or last time we discussed this, the series is
> ready for being collected (pending this ack I assume)
> 
> I wonder if it needs a rebase (pretty sure it does)

The set is in my tree already.

-- 
Sakari Ailus

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 01/30] dt-bindings: media: i2c: Rename ov5647.yaml
  2020-12-21 20:23     ` Rob Herring
@ 2020-12-22  9:50       ` Sakari Ailus
  2021-01-14 20:20         ` Rob Herring
  0 siblings, 1 reply; 39+ messages in thread
From: Sakari Ailus @ 2020-12-22  9:50 UTC (permalink / raw)
  To: Rob Herring
  Cc: Jacopo Mondi, Linux Media Mailing List, Mauro Carvalho Chehab,
	Hans Verkuil, Laurent Pinchart, roman.kovalivskyi,
	Dafna Hirschfeld, Dave Stevenson, naush, Eugeniu Rosca,
	devicetree

Hi Rob,

On Mon, Dec 21, 2020 at 01:23:29PM -0700, Rob Herring wrote:
> On Wed, Nov 25, 2020 at 2:15 AM Sakari Ailus
> <sakari.ailus@linux.intel.com> wrote:
> >
> > Cc Rob + DT list.
> 
> You have to resend if you really want me to see things. In this case,
> I don't think you need to wait on me for a rename.

I merged the patch earlier based on the IRC discussion.

-- 
Regards,

Sakari Ailus

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 01/30] dt-bindings: media: i2c: Rename ov5647.yaml
  2020-12-22  9:50       ` Sakari Ailus
@ 2021-01-14 20:20         ` Rob Herring
  2021-01-15  9:03           ` Jacopo Mondi
  0 siblings, 1 reply; 39+ messages in thread
From: Rob Herring @ 2021-01-14 20:20 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Jacopo Mondi, Linux Media Mailing List, Mauro Carvalho Chehab,
	Hans Verkuil, Laurent Pinchart, roman.kovalivskyi,
	Dafna Hirschfeld, Dave Stevenson, naush, Eugeniu Rosca,
	devicetree

On Tue, Dec 22, 2020 at 3:50 AM Sakari Ailus
<sakari.ailus@linux.intel.com> wrote:
>
> Hi Rob,
>
> On Mon, Dec 21, 2020 at 01:23:29PM -0700, Rob Herring wrote:
> > On Wed, Nov 25, 2020 at 2:15 AM Sakari Ailus
> > <sakari.ailus@linux.intel.com> wrote:
> > >
> > > Cc Rob + DT list.
> >
> > You have to resend if you really want me to see things. In this case,
> > I don't think you need to wait on me for a rename.
>
> I merged the patch earlier based on the IRC discussion.

Seems this landed in -next:

./Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml: $id:
relative path/filename doesn't match actual path or filename
expected: http://devicetree.org/schemas/media/i2c/ovti,ov5647.yaml#

Rob

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 01/30] dt-bindings: media: i2c: Rename ov5647.yaml
  2021-01-14 20:20         ` Rob Herring
@ 2021-01-15  9:03           ` Jacopo Mondi
  2021-01-15  9:26             ` Sakari Ailus
  0 siblings, 1 reply; 39+ messages in thread
From: Jacopo Mondi @ 2021-01-15  9:03 UTC (permalink / raw)
  To: Rob Herring, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Linux Media Mailing List, Mauro Carvalho Chehab,
	Hans Verkuil, Laurent Pinchart, roman.kovalivskyi,
	Dafna Hirschfeld, Dave Stevenson, naush, Eugeniu Rosca,
	devicetree

Ups,

   I'll fix. A question for Mauro though

On Thu, Jan 14, 2021 at 02:20:34PM -0600, Rob Herring wrote:
> On Tue, Dec 22, 2020 at 3:50 AM Sakari Ailus
> <sakari.ailus@linux.intel.com> wrote:
> >
> > Hi Rob,
> >
> > On Mon, Dec 21, 2020 at 01:23:29PM -0700, Rob Herring wrote:
> > > On Wed, Nov 25, 2020 at 2:15 AM Sakari Ailus
> > > <sakari.ailus@linux.intel.com> wrote:
> > > >
> > > > Cc Rob + DT list.
> > >
> > > You have to resend if you really want me to see things. In this case,
> > > I don't think you need to wait on me for a rename.
> >
> > I merged the patch earlier based on the IRC discussion.
>
> Seems this landed in -next:
>
> ./Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml: $id:
> relative path/filename doesn't match actual path or filename
> expected: http://devicetree.org/schemas/media/i2c/ovti,ov5647.yaml#
>

The fix is worth a Fixes: tag, should I refer to the current commit
sha1 in linux-media/master or is there any risk for a rebase before
the tree is merged in the v5.12 merge window ?

Thanks
    j

> Rob

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v4 01/30] dt-bindings: media: i2c: Rename ov5647.yaml
  2021-01-15  9:03           ` Jacopo Mondi
@ 2021-01-15  9:26             ` Sakari Ailus
  0 siblings, 0 replies; 39+ messages in thread
From: Sakari Ailus @ 2021-01-15  9:26 UTC (permalink / raw)
  To: Jacopo Mondi
  Cc: Rob Herring, Mauro Carvalho Chehab, Linux Media Mailing List,
	Hans Verkuil, Laurent Pinchart, roman.kovalivskyi,
	Dafna Hirschfeld, Dave Stevenson, naush, Eugeniu Rosca,
	devicetree

Hi Jacopo,

On Fri, Jan 15, 2021 at 10:03:26AM +0100, Jacopo Mondi wrote:
> Ups,
> 
>    I'll fix. A question for Mauro though
> 
> On Thu, Jan 14, 2021 at 02:20:34PM -0600, Rob Herring wrote:
> > On Tue, Dec 22, 2020 at 3:50 AM Sakari Ailus
> > <sakari.ailus@linux.intel.com> wrote:
> > >
> > > Hi Rob,
> > >
> > > On Mon, Dec 21, 2020 at 01:23:29PM -0700, Rob Herring wrote:
> > > > On Wed, Nov 25, 2020 at 2:15 AM Sakari Ailus
> > > > <sakari.ailus@linux.intel.com> wrote:
> > > > >
> > > > > Cc Rob + DT list.
> > > >
> > > > You have to resend if you really want me to see things. In this case,
> > > > I don't think you need to wait on me for a rename.
> > >
> > > I merged the patch earlier based on the IRC discussion.
> >
> > Seems this landed in -next:
> >
> > ./Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml: $id:
> > relative path/filename doesn't match actual path or filename
> > expected: http://devicetree.org/schemas/media/i2c/ovti,ov5647.yaml#
> >
> 
> The fix is worth a Fixes: tag, should I refer to the current commit
> sha1 in linux-media/master or is there any risk for a rebase before
> the tree is merged in the v5.12 merge window ?

I'd say that happens only in exceptional circumstances. I think you can do
that.

-- 
Regards,

Sakari Ailus

^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2021-01-15  9:28 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-19 16:19 [PATCH v4 00/30] media: ov5647: Support RaspberryPi Camera Module v1 Jacopo Mondi
2020-11-19 16:19 ` [PATCH v4 01/30] dt-bindings: media: i2c: Rename ov5647.yaml Jacopo Mondi
2020-11-25  9:15   ` Sakari Ailus
2020-12-21 17:34     ` Jacopo Mondi
2020-12-22  9:43       ` Sakari Ailus
2020-12-21 20:23     ` Rob Herring
2020-12-22  9:50       ` Sakari Ailus
2021-01-14 20:20         ` Rob Herring
2021-01-15  9:03           ` Jacopo Mondi
2021-01-15  9:26             ` Sakari Ailus
2020-11-19 16:19 ` [PATCH v4 02/30] media: ov5647: Add support for PWDN GPIO Jacopo Mondi
2020-11-19 16:19 ` [PATCH v4 03/30] media: ov5647: Add support for non-continuous clock mode Jacopo Mondi
2020-11-19 16:19 ` [PATCH v4 04/30] media: ov5647: Add set_fmt and get_fmt calls Jacopo Mondi
2020-11-19 16:19 ` [PATCH v4 05/30] media: ov5647: Fix format initialization Jacopo Mondi
2020-11-19 16:19 ` [PATCH v4 06/30] media: ov5647: Fix style issues Jacopo Mondi
2020-11-19 16:19 ` [PATCH v4 07/30] media: ov5647: Replace license with SPDX identifier Jacopo Mondi
2020-11-19 16:19 ` [PATCH v4 08/30] media: ov5647: Fix return value from read/write Jacopo Mondi
2020-11-19 16:19 ` [PATCH v4 09/30] media: ov5647: Program mode at s_stream(1) time Jacopo Mondi
2020-11-19 16:32 ` [PATCH v4 10/30] media: ov5647: Implement enum_frame_size() Jacopo Mondi
2020-11-19 16:32   ` [PATCH v4 11/30] media: ov5647: Protect s_stream() with mutex Jacopo Mondi
2020-11-19 16:32   ` [PATCH v4 12/30] media: ov5647: Support gain, exposure and AWB controls Jacopo Mondi
2020-11-19 16:32   ` [PATCH v4 13/30] media: ov5647: Rationalize driver structure name Jacopo Mondi
2020-11-19 16:32   ` [PATCH v4 14/30] media: ov5647: Break out format handling Jacopo Mondi
2020-11-19 16:32   ` [PATCH v4 15/30] media: ov5647: Add support for get_selection() Jacopo Mondi
2020-11-19 16:32   ` [PATCH v4 16/30] media: ov5647: Rename SBGGR8 VGA mode Jacopo Mondi
2020-11-19 16:32   ` [PATCH v4 17/30] media: ov5647: Add SGGBR10_1X10 modes Jacopo Mondi
2020-11-19 16:32   ` [PATCH v4 18/30] media: ov5647: Use SBGGR10_1X10 640x480 as default Jacopo Mondi
2020-11-19 16:32   ` [PATCH v4 19/30] media: ov5647: Implement set_fmt pad operation Jacopo Mondi
2020-11-19 16:35 ` [PATCH v4 20/30] media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag Jacopo Mondi
2020-11-19 16:35   ` [PATCH v4 21/30] media: ov5647: Support V4L2_CID_PIXEL_RATE Jacopo Mondi
2020-11-19 16:35   ` [PATCH v4 22/30] media: ov5647: Support V4L2_CID_HBLANK control Jacopo Mondi
2020-11-19 16:35   ` [PATCH v4 23/30] media: ov5647: Support V4L2_CID_VBLANK control Jacopo Mondi
2020-11-19 16:35   ` [PATCH v4 24/30] media: ov5647: Advertise the correct exposure range Jacopo Mondi
2020-11-19 16:35   ` [PATCH v4 25/30] media: ov5647: Use pm_runtime infrastructure Jacopo Mondi
2020-11-19 16:35   ` [PATCH v4 26/30] media: ov5647: Rework s_stream() operation Jacopo Mondi
2020-11-19 16:35   ` [PATCH v4 27/30] media: ov5647: Apply controls only when powered Jacopo Mondi
2020-11-19 16:35   ` [PATCH v4 28/30] media: ov5647: Constify oe_enable/disable reglist Jacopo Mondi
2020-11-19 16:35   ` [PATCH v4 29/30] media: ov5647: Support VIDIOC_SUBSCRIBE_EVENT Jacopo Mondi
2020-11-19 16:37 ` [PATCH v4 30/30] media: ov5647: Remove 640x480 SBGGR8 mode Jacopo Mondi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.