All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/17] Extensions to ov8865 driver
@ 2021-11-23  0:00 Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 01/17] media: i2c: Re-order runtime pm initialisation Daniel Scally
                   ` (18 more replies)
  0 siblings, 19 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

Hello all

This series extends the ov8865 driver with:

* Support for binding to ACPI enumerated devices.
* Support for a 19.2MHz clock in addition to existing 24MHz clock support
* Another v4l2_subdev_pad_ops callback
* 4 more V4L2 controls
* makes the driver supported by the cio2-bridge

There's also a little bit of tidying that I did along the way.

The series is tested on an MS Surface Go 2.

Thanks
Dan

Series level changes since v4:

	- Moved the two patches fixing issues to the head of the series and
	added Fixes tags
	- Added a new patch fixing the maximum gain value

Daniel Scally (16):
  media: i2c: Re-order runtime pm initialisation
  media: i2c: Add ACPI support to ov8865
  media: i2c: Fix incorrect value in comment
  media: i2c: Defer probe if not endpoint found
  media: i2c: Support 19.2MHz input clock in ov8865
  media: i2c: Add .get_selection() support to ov8865
  media: i2c: Switch control to V4L2_CID_ANALOGUE_GAIN
  media: i2c: Add vblank control to ov8865
  media: i2c: Add hblank control to ov8865
  media: i2c: Update HTS values in ov8865
  media: i2c: cap exposure at height + vblank in ov8865
  media: i2c: Add controls from fwnode to ov8865
  media: i2c: Switch exposure control unit to lines
  media: i2c: Use dev_err_probe() in ov8865
  media: i2c: Fix max gain in ov8865
  media: ipu3-cio2: Add INT347A to cio2-bridge

Hans de Goede (1):
  media: i2c: ov8865: Fix lockdep error

 drivers/media/i2c/ov8865.c                 | 466 +++++++++++++++------
 drivers/media/pci/intel/ipu3/cio2-bridge.c |   2 +
 2 files changed, 334 insertions(+), 134 deletions(-)

-- 
2.25.1


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

* [PATCH v5 01/17] media: i2c: Re-order runtime pm initialisation
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 02/17] media: i2c: ov8865: Fix lockdep error Daniel Scally
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

The kerneldoc for pm_runtime_set_suspended() says:

"It is not valid to call this function for devices with runtime PM
enabled"

To satisfy that requirement, re-order the calls so that
pm_runtime_enable() is the last one.

Fixes: 11c0d8fdccc5 ("media: i2c: Add support for the OV8865 image sensor")
Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- None

 drivers/media/i2c/ov8865.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index ce50f3ea87b8..490832cdb831 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -2897,8 +2897,8 @@ static int ov8865_probe(struct i2c_client *client)
 
 	/* Runtime PM */
 
-	pm_runtime_enable(sensor->dev);
 	pm_runtime_set_suspended(sensor->dev);
+	pm_runtime_enable(sensor->dev);
 
 	/* V4L2 subdev register */
 
-- 
2.25.1


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

* [PATCH v5 02/17] media: i2c: ov8865: Fix lockdep error
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 01/17] media: i2c: Re-order runtime pm initialisation Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 03/17] media: i2c: Add ACPI support to ov8865 Daniel Scally
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

From: Hans de Goede <hdegoede@redhat.com>

ov8865_state_init() calls ov8865_state_mipi_configure() which uses
__v4l2_ctrl_s_ctrl[_int64](). This means that sensor->mutex (which
is also sensor->ctrls.handler.lock) must be locked before calling
ov8865_state_init().

Note ov8865_state_mipi_configure() is also used in other places where
the lock is already held so it cannot be changed itself.

This fixes the following lockdep kernel WARN:

[   13.233421] WARNING: CPU: 0 PID: 8 at drivers/media/v4l2-core/v4l2-ctrls-api.c:833 __v4l2_ctrl_s_ctrl+0x4d/0x60 [videodev]
...
[   13.234063] Call Trace:
[   13.234074]  ov8865_state_configure+0x98b/0xc00 [ov8865]
[   13.234095]  ov8865_probe+0x4b1/0x54c [ov8865]
[   13.234117]  i2c_device_probe+0x13c/0x2d0

Fixes: 11c0d8fdccc5 ("media: i2c: Add support for the OV8865 image sensor")
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v5: 

	- None

 drivers/media/i2c/ov8865.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index 490832cdb831..fe064e716ea8 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -2891,7 +2891,9 @@ static int ov8865_probe(struct i2c_client *client)
 	if (ret)
 		goto error_mutex;
 
+	mutex_lock(&sensor->mutex);
 	ret = ov8865_state_init(sensor);
+	mutex_unlock(&sensor->mutex);
 	if (ret)
 		goto error_ctrls;
 
-- 
2.25.1


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

* [PATCH v5 03/17] media: i2c: Add ACPI support to ov8865
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 01/17] media: i2c: Re-order runtime pm initialisation Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 02/17] media: i2c: ov8865: Fix lockdep error Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 04/17] media: i2c: Fix incorrect value in comment Daniel Scally
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

The ov8865 sensor is sometimes found on x86 platforms enumerated via ACPI.
Add an ACPI match table to the driver so that it's probed on those
platforms.

Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- None

 drivers/media/i2c/ov8865.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index fe064e716ea8..9f1c0d66c4f9 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -9,6 +9,7 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/i2c.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/of_graph.h>
 #include <linux/pm_runtime.h>
@@ -2948,6 +2949,12 @@ static const struct dev_pm_ops ov8865_pm_ops = {
 	SET_RUNTIME_PM_OPS(ov8865_suspend, ov8865_resume, NULL)
 };
 
+static const struct acpi_device_id ov8865_acpi_match[] = {
+	{"INT347A"},
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, ov8865_acpi_match);
+
 static const struct of_device_id ov8865_of_match[] = {
 	{ .compatible = "ovti,ov8865" },
 	{ }
@@ -2958,6 +2965,7 @@ static struct i2c_driver ov8865_driver = {
 	.driver = {
 		.name = "ov8865",
 		.of_match_table = ov8865_of_match,
+		.acpi_match_table = ov8865_acpi_match,
 		.pm = &ov8865_pm_ops,
 	},
 	.probe_new = ov8865_probe,
-- 
2.25.1


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

* [PATCH v5 04/17] media: i2c: Fix incorrect value in comment
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (2 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 03/17] media: i2c: Add ACPI support to ov8865 Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 05/17] media: i2c: Defer probe if not endpoint found Daniel Scally
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

The PLL configuration defined here sets 72MHz (which is correct), not
80MHz. Correct the comment.

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
 drivers/media/i2c/ov8865.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index 9f1c0d66c4f9..a6372a0989e1 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -713,7 +713,7 @@ static const struct ov8865_pll2_config ov8865_pll2_config_native = {
 /*
  * EXTCLK = 24 MHz
  * DAC_CLK = 360 MHz
- * SCLK = 80 MHz
+ * SCLK = 72 MHz
  */
 
 static const struct ov8865_pll2_config ov8865_pll2_config_binning = {
-- 
2.25.1


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

* [PATCH v5 05/17] media: i2c: Defer probe if not endpoint found
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (3 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 04/17] media: i2c: Fix incorrect value in comment Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 06/17] media: i2c: Support 19.2MHz input clock in ov8865 Daniel Scally
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

The ov8865 driver is one of those that can be connected to a CIO2
device by the cio2-bridge code. This means that the absence of an
endpoint for this device is not necessarily fatal, as one might be
built by the cio2-bridge when it probes. Return -EPROBE_DEFER if no
endpoint is found rather than a fatal error.

Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- None

 drivers/media/i2c/ov8865.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index a6372a0989e1..68fdb1ce1e94 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -2796,10 +2796,8 @@ static int ov8865_probe(struct i2c_client *client)
 	/* Graph Endpoint */
 
 	handle = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
-	if (!handle) {
-		dev_err(dev, "unable to find endpoint node\n");
-		return -EINVAL;
-	}
+	if (!handle)
+		return -EPROBE_DEFER;
 
 	sensor->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;
 
-- 
2.25.1


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

* [PATCH v5 06/17] media: i2c: Support 19.2MHz input clock in ov8865
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (4 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 05/17] media: i2c: Defer probe if not endpoint found Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 07/17] media: i2c: Add .get_selection() support to ov8865 Daniel Scally
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

The ov8865 driver as written expects a 24MHz input clock, but the sensor
is sometimes found on x86 platforms with a 19.2MHz input clock supplied.
Add a set of PLL configurations to the driver to support that rate too.
As ACPI doesn't auto-configure the clock rate, check for a clock-frequency
during probe and set that rate if one is found.

Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- (Sakari) Constified some new structs
	- (Sakari) Reworked .probe() to account for the possibility of no
	clock being acquired, provided a clock-frequency is present in fwnode
	properties.

 drivers/media/i2c/ov8865.c | 195 +++++++++++++++++++++++++++----------
 1 file changed, 143 insertions(+), 52 deletions(-)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index 68fdb1ce1e94..e52e43bd7787 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -21,10 +21,6 @@
 #include <media/v4l2-image-sizes.h>
 #include <media/v4l2-mediabus.h>
 
-/* Clock rate */
-
-#define OV8865_EXTCLK_RATE			24000000
-
 /* Register definitions */
 
 /* System */
@@ -567,6 +563,25 @@ struct ov8865_sclk_config {
 	unsigned int sclk_div;
 };
 
+struct ov8865_pll_configs {
+	const struct ov8865_pll1_config *pll1_config;
+	const struct ov8865_pll2_config *pll2_config_native;
+	const struct ov8865_pll2_config *pll2_config_binning;
+};
+
+/* Clock rate */
+
+enum extclk_rate {
+	OV8865_19_2_MHZ,
+	OV8865_24_MHZ,
+	OV8865_NUM_SUPPORTED_RATES
+};
+
+static const unsigned long supported_extclk_rates[] = {
+	[OV8865_19_2_MHZ] = 19200000,
+	[OV8865_24_MHZ] = 24000000,
+};
+
 /*
  * General formulas for (array-centered) mode calculation:
  * - photo_array_width = 3296
@@ -635,9 +650,7 @@ struct ov8865_mode {
 
 	struct v4l2_fract frame_interval;
 
-	const struct ov8865_pll1_config *pll1_config;
-	const struct ov8865_pll2_config *pll2_config;
-	const struct ov8865_sclk_config *sclk_config;
+	bool pll2_binning;
 
 	const struct ov8865_register_value *register_values;
 	unsigned int register_values_count;
@@ -665,6 +678,9 @@ struct ov8865_sensor {
 	struct regulator *avdd;
 	struct regulator *dvdd;
 	struct regulator *dovdd;
+
+	unsigned long extclk_rate;
+	const struct ov8865_pll_configs *pll_configs;
 	struct clk *extclk;
 
 	struct v4l2_fwnode_endpoint endpoint;
@@ -680,43 +696,70 @@ struct ov8865_sensor {
 /* Static definitions */
 
 /*
- * EXTCLK = 24 MHz
  * PHY_SCLK = 720 MHz
  * MIPI_PCLK = 90 MHz
  */
-static const struct ov8865_pll1_config ov8865_pll1_config_native = {
-	.pll_pre_div_half	= 1,
-	.pll_pre_div		= 0,
-	.pll_mul		= 30,
-	.m_div			= 1,
-	.mipi_div		= 3,
-	.pclk_div		= 1,
-	.sys_pre_div		= 1,
-	.sys_div		= 2,
+
+static const struct ov8865_pll1_config ov8865_pll1_config_native_19_2mhz = {
+		.pll_pre_div_half	= 1,
+		.pll_pre_div		= 2,
+		.pll_mul		= 75,
+		.m_div			= 1,
+		.mipi_div		= 3,
+		.pclk_div		= 1,
+		.sys_pre_div		= 1,
+		.sys_div		= 2,
+};
+
+static const struct ov8865_pll1_config ov8865_pll1_config_native_24mhz = {
+		.pll_pre_div_half	= 1,
+		.pll_pre_div		= 0,
+		.pll_mul		= 30,
+		.m_div			= 1,
+		.mipi_div		= 3,
+		.pclk_div		= 1,
+		.sys_pre_div		= 1,
+		.sys_div		= 2,
 };
 
 /*
- * EXTCLK = 24 MHz
  * DAC_CLK = 360 MHz
  * SCLK = 144 MHz
  */
 
-static const struct ov8865_pll2_config ov8865_pll2_config_native = {
-	.pll_pre_div_half	= 1,
-	.pll_pre_div		= 0,
-	.pll_mul		= 30,
-	.dac_div		= 2,
-	.sys_pre_div		= 5,
-	.sys_div		= 0,
+static const struct ov8865_pll2_config ov8865_pll2_config_native_19_2mhz = {
+		.pll_pre_div_half	= 1,
+		.pll_pre_div		= 5,
+		.pll_mul		= 75,
+		.dac_div		= 1,
+		.sys_pre_div		= 1,
+		.sys_div		= 3,
+};
+
+static const struct ov8865_pll2_config ov8865_pll2_config_native_24mhz = {
+		.pll_pre_div_half	= 1,
+		.pll_pre_div		= 0,
+		.pll_mul		= 30,
+		.dac_div		= 2,
+		.sys_pre_div		= 5,
+		.sys_div		= 0,
 };
 
 /*
- * EXTCLK = 24 MHz
  * DAC_CLK = 360 MHz
  * SCLK = 72 MHz
  */
 
-static const struct ov8865_pll2_config ov8865_pll2_config_binning = {
+static const struct ov8865_pll2_config ov8865_pll2_config_binning_19_2mhz = {
+	.pll_pre_div_half	= 1,
+	.pll_pre_div		= 2,
+	.pll_mul		= 75,
+	.dac_div		= 2,
+	.sys_pre_div		= 10,
+	.sys_div		= 0,
+};
+
+static const struct ov8865_pll2_config ov8865_pll2_config_binning_24mhz = {
 	.pll_pre_div_half	= 1,
 	.pll_pre_div		= 0,
 	.pll_mul		= 30,
@@ -725,6 +768,23 @@ static const struct ov8865_pll2_config ov8865_pll2_config_binning = {
 	.sys_div		= 0,
 };
 
+static const struct ov8865_pll_configs ov8865_pll_configs_19_2mhz = {
+	.pll1_config = &ov8865_pll1_config_native_19_2mhz,
+	.pll2_config_native = &ov8865_pll2_config_native_19_2mhz,
+	.pll2_config_binning = &ov8865_pll2_config_binning_19_2mhz,
+};
+
+static const struct ov8865_pll_configs ov8865_pll_configs_24mhz = {
+	.pll1_config = &ov8865_pll1_config_native_24mhz,
+	.pll2_config_native = &ov8865_pll2_config_native_24mhz,
+	.pll2_config_binning = &ov8865_pll2_config_binning_24mhz,
+};
+
+static const struct ov8865_pll_configs *ov8865_pll_configs[] = {
+	&ov8865_pll_configs_19_2mhz,
+	&ov8865_pll_configs_24mhz,
+};
+
 static const struct ov8865_sclk_config ov8865_sclk_config_native = {
 	.sys_sel		= 1,
 	.sclk_sel		= 0,
@@ -934,9 +994,7 @@ static const struct ov8865_mode ov8865_modes[] = {
 		.frame_interval			= { 1, 30 },
 
 		/* PLL */
-		.pll1_config			= &ov8865_pll1_config_native,
-		.pll2_config			= &ov8865_pll2_config_native,
-		.sclk_config			= &ov8865_sclk_config_native,
+		.pll2_binning			= false,
 
 		/* Registers */
 		.register_values	= ov8865_register_values_native,
@@ -990,9 +1048,7 @@ static const struct ov8865_mode ov8865_modes[] = {
 		.frame_interval			= { 1, 30 },
 
 		/* PLL */
-		.pll1_config			= &ov8865_pll1_config_native,
-		.pll2_config			= &ov8865_pll2_config_native,
-		.sclk_config			= &ov8865_sclk_config_native,
+		.pll2_binning			= false,
 
 		/* Registers */
 		.register_values	= ov8865_register_values_native,
@@ -1050,9 +1106,7 @@ static const struct ov8865_mode ov8865_modes[] = {
 		.frame_interval			= { 1, 30 },
 
 		/* PLL */
-		.pll1_config			= &ov8865_pll1_config_native,
-		.pll2_config			= &ov8865_pll2_config_binning,
-		.sclk_config			= &ov8865_sclk_config_native,
+		.pll2_binning			= true,
 
 		/* Registers */
 		.register_values	= ov8865_register_values_binning,
@@ -1116,9 +1170,7 @@ static const struct ov8865_mode ov8865_modes[] = {
 		.frame_interval			= { 1, 90 },
 
 		/* PLL */
-		.pll1_config			= &ov8865_pll1_config_native,
-		.pll2_config			= &ov8865_pll2_config_binning,
-		.sclk_config			= &ov8865_sclk_config_native,
+		.pll2_binning			= true,
 
 		/* Registers */
 		.register_values	= ov8865_register_values_binning,
@@ -1513,12 +1565,11 @@ static int ov8865_isp_configure(struct ov8865_sensor *sensor)
 static unsigned long ov8865_mode_pll1_rate(struct ov8865_sensor *sensor,
 					   const struct ov8865_mode *mode)
 {
-	const struct ov8865_pll1_config *config = mode->pll1_config;
-	unsigned long extclk_rate;
+	const struct ov8865_pll1_config *config;
 	unsigned long pll1_rate;
 
-	extclk_rate = clk_get_rate(sensor->extclk);
-	pll1_rate = extclk_rate * config->pll_mul / config->pll_pre_div_half;
+	config = sensor->pll_configs->pll1_config;
+	pll1_rate = sensor->extclk_rate * config->pll_mul / config->pll_pre_div_half;
 
 	switch (config->pll_pre_div) {
 	case 0:
@@ -1552,10 +1603,12 @@ static int ov8865_mode_pll1_configure(struct ov8865_sensor *sensor,
 				      const struct ov8865_mode *mode,
 				      u32 mbus_code)
 {
-	const struct ov8865_pll1_config *config = mode->pll1_config;
+	const struct ov8865_pll1_config *config;
 	u8 value;
 	int ret;
 
+	config = sensor->pll_configs->pll1_config;
+
 	switch (mbus_code) {
 	case MEDIA_BUS_FMT_SBGGR10_1X10:
 		value = OV8865_MIPI_BIT_SEL(10);
@@ -1622,9 +1675,12 @@ static int ov8865_mode_pll1_configure(struct ov8865_sensor *sensor,
 static int ov8865_mode_pll2_configure(struct ov8865_sensor *sensor,
 				      const struct ov8865_mode *mode)
 {
-	const struct ov8865_pll2_config *config = mode->pll2_config;
+	const struct ov8865_pll2_config *config;
 	int ret;
 
+	config = mode->pll2_binning ? sensor->pll_configs->pll2_config_binning :
+				      sensor->pll_configs->pll2_config_native;
+
 	ret = ov8865_write(sensor, OV8865_PLL_CTRL12_REG,
 			   OV8865_PLL_CTRL12_PRE_DIV_HALF(config->pll_pre_div_half) |
 			   OV8865_PLL_CTRL12_DAC_DIV(config->dac_div));
@@ -1658,7 +1714,7 @@ static int ov8865_mode_pll2_configure(struct ov8865_sensor *sensor,
 static int ov8865_mode_sclk_configure(struct ov8865_sensor *sensor,
 				      const struct ov8865_mode *mode)
 {
-	const struct ov8865_sclk_config *config = mode->sclk_config;
+	const struct ov8865_sclk_config *config = &ov8865_sclk_config_native;
 	int ret;
 
 	ret = ov8865_write(sensor, OV8865_CLK_SEL0_REG,
@@ -2053,9 +2109,11 @@ static int ov8865_mode_configure(struct ov8865_sensor *sensor,
 static unsigned long ov8865_mode_mipi_clk_rate(struct ov8865_sensor *sensor,
 					       const struct ov8865_mode *mode)
 {
-	const struct ov8865_pll1_config *config = mode->pll1_config;
+	const struct ov8865_pll1_config *config;
 	unsigned long pll1_rate;
 
+	config = sensor->pll_configs->pll1_config;
+
 	pll1_rate = ov8865_mode_pll1_rate(sensor, mode);
 
 	return pll1_rate / config->m_div / 2;
@@ -2783,7 +2841,8 @@ static int ov8865_probe(struct i2c_client *client)
 	struct ov8865_sensor *sensor;
 	struct v4l2_subdev *subdev;
 	struct media_pad *pad;
-	unsigned long rate;
+	unsigned int rate = 0;
+	unsigned int i;
 	int ret;
 
 	sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
@@ -2852,19 +2911,51 @@ static int ov8865_probe(struct i2c_client *client)
 	/* External Clock */
 
 	sensor->extclk = devm_clk_get(dev, NULL);
-	if (IS_ERR(sensor->extclk)) {
+	if (PTR_ERR(sensor->extclk) == -ENOENT) {
+		dev_info(dev, "no external clock found, continuing...\n");
+		sensor->extclk = NULL;
+	} else if (IS_ERR(sensor->extclk)) {
 		dev_err(dev, "failed to get external clock\n");
 		ret = PTR_ERR(sensor->extclk);
 		goto error_endpoint;
 	}
 
-	rate = clk_get_rate(sensor->extclk);
-	if (rate != OV8865_EXTCLK_RATE) {
-		dev_err(dev, "clock rate %lu Hz is unsupported\n", rate);
+	/*
+	 * We could have either a 24MHz or 19.2MHz clock rate from either dt or
+	 * ACPI...but we also need to support the weird IPU3 case which will
+	 * have an external clock AND a clock-frequency property. Check for the
+	 * clock-frequency property and if found, set that rate if we managed
+	 * to acquire a clock. This should cover the ACPI case. If the system
+	 * uses devicetree then the configured rate should already be set, so
+	 * we can just read it.
+	 */
+	ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
+				       &rate);
+	if (!ret && sensor->extclk) {
+		ret = clk_set_rate(sensor->extclk, rate);
+		if (ret)
+			return dev_err_probe(dev, ret,
+					     "failed to set clock rate\n");
+	} else if (ret && !sensor->extclk) {
+		return dev_err_probe(dev, ret, "invalid clock config\n");
+	}
+
+	sensor->extclk_rate = rate ? rate : clk_get_rate(sensor->extclk);
+
+	for (i = 0; i < ARRAY_SIZE(supported_extclk_rates); i++) {
+		if (sensor->extclk_rate == supported_extclk_rates[i])
+			break;
+	}
+
+	if (i == ARRAY_SIZE(supported_extclk_rates)) {
+		dev_err(dev, "clock rate %lu Hz is unsupported\n",
+			sensor->extclk_rate);
 		ret = -EINVAL;
 		goto error_endpoint;
 	}
 
+	sensor->pll_configs = ov8865_pll_configs[i];
+
 	/* Subdev, entity and pad */
 
 	subdev = &sensor->subdev;
-- 
2.25.1


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

* [PATCH v5 07/17] media: i2c: Add .get_selection() support to ov8865
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (5 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 06/17] media: i2c: Support 19.2MHz input clock in ov8865 Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 08/17] media: i2c: Switch control to V4L2_CID_ANALOGUE_GAIN Daniel Scally
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

The ov8865 driver's v4l2_subdev_pad_ops currently does not include
.get_selection() - add support for that callback.

Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- None

 drivers/media/i2c/ov8865.c | 64 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index e52e43bd7787..87e34ad9c9a6 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -450,6 +450,15 @@
 #define OV8865_PRE_CTRL0_PATTERN_COLOR_SQUARES	2
 #define OV8865_PRE_CTRL0_PATTERN_BLACK		3
 
+/* Pixel Array */
+
+#define OV8865_NATIVE_WIDTH			3296
+#define OV8865_NATIVE_HEIGHT			2528
+#define OV8865_ACTIVE_START_TOP			32
+#define OV8865_ACTIVE_START_LEFT		80
+#define OV8865_ACTIVE_WIDTH			3264
+#define OV8865_ACTIVE_HEIGHT			2448
+
 /* Macros */
 
 #define ov8865_subdev_sensor(s) \
@@ -2756,12 +2765,67 @@ static int ov8865_enum_frame_interval(struct v4l2_subdev *subdev,
 	return 0;
 }
 
+static void
+__ov8865_get_pad_crop(struct ov8865_sensor *sensor,
+		      struct v4l2_subdev_state *state, unsigned int pad,
+		      enum v4l2_subdev_format_whence which, struct v4l2_rect *r)
+{
+	const struct ov8865_mode *mode = sensor->state.mode;
+
+	switch (which) {
+	case V4L2_SUBDEV_FORMAT_TRY:
+		*r = *v4l2_subdev_get_try_crop(&sensor->subdev, state, pad);
+		break;
+	case V4L2_SUBDEV_FORMAT_ACTIVE:
+		r->height = mode->output_size_y;
+		r->width = mode->output_size_x;
+		r->top = (OV8865_NATIVE_HEIGHT - mode->output_size_y) / 2;
+		r->left = (OV8865_NATIVE_WIDTH - mode->output_size_x) / 2;
+		break;
+	}
+}
+
+static int ov8865_get_selection(struct v4l2_subdev *subdev,
+				struct v4l2_subdev_state *state,
+				struct v4l2_subdev_selection *sel)
+{
+	struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
+
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP:
+		mutex_lock(&sensor->mutex);
+			__ov8865_get_pad_crop(sensor, state, sel->pad,
+					      sel->which, &sel->r);
+		mutex_unlock(&sensor->mutex);
+		break;
+	case V4L2_SEL_TGT_NATIVE_SIZE:
+		sel->r.top = 0;
+		sel->r.left = 0;
+		sel->r.width = OV8865_NATIVE_WIDTH;
+		sel->r.height = OV8865_NATIVE_HEIGHT;
+		break;
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+		sel->r.top = OV8865_ACTIVE_START_TOP;
+		sel->r.left = OV8865_ACTIVE_START_LEFT;
+		sel->r.width = OV8865_ACTIVE_WIDTH;
+		sel->r.height = OV8865_ACTIVE_HEIGHT;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static const struct v4l2_subdev_pad_ops ov8865_subdev_pad_ops = {
 	.enum_mbus_code		= ov8865_enum_mbus_code,
 	.get_fmt		= ov8865_get_fmt,
 	.set_fmt		= ov8865_set_fmt,
 	.enum_frame_size	= ov8865_enum_frame_size,
 	.enum_frame_interval	= ov8865_enum_frame_interval,
+	.get_selection		= ov8865_get_selection,
+	.set_selection		= ov8865_get_selection,
 };
 
 static const struct v4l2_subdev_ops ov8865_subdev_ops = {
-- 
2.25.1


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

* [PATCH v5 08/17] media: i2c: Switch control to V4L2_CID_ANALOGUE_GAIN
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (6 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 07/17] media: i2c: Add .get_selection() support to ov8865 Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 09/17] media: i2c: Add vblank control to ov8865 Daniel Scally
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

The V4L2_CID_GAIN control for this driver configures registers that
the datasheet specifies as analogue gain. Switch the control's ID
to V4L2_CID_ANALOGUE_GAIN.

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- None

 drivers/media/i2c/ov8865.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index 87e34ad9c9a6..2d5b7b8c2c9e 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -2150,7 +2150,7 @@ static int ov8865_exposure_configure(struct ov8865_sensor *sensor, u32 exposure)
 
 /* Gain */
 
-static int ov8865_gain_configure(struct ov8865_sensor *sensor, u32 gain)
+static int ov8865_analog_gain_configure(struct ov8865_sensor *sensor, u32 gain)
 {
 	int ret;
 
@@ -2460,8 +2460,8 @@ static int ov8865_s_ctrl(struct v4l2_ctrl *ctrl)
 		if (ret)
 			return ret;
 		break;
-	case V4L2_CID_GAIN:
-		ret = ov8865_gain_configure(sensor, ctrl->val);
+	case V4L2_CID_ANALOGUE_GAIN:
+		ret = ov8865_analog_gain_configure(sensor, ctrl->val);
 		if (ret)
 			return ret;
 		break;
@@ -2506,7 +2506,8 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
 
 	/* Gain */
 
-	v4l2_ctrl_new_std(handler, ops, V4L2_CID_GAIN, 128, 8191, 128, 128);
+	v4l2_ctrl_new_std(handler, ops, V4L2_CID_ANALOGUE_GAIN, 128, 8191, 128,
+			  128);
 
 	/* White Balance */
 
-- 
2.25.1


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

* [PATCH v5 09/17] media: i2c: Add vblank control to ov8865
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (7 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 08/17] media: i2c: Switch control to V4L2_CID_ANALOGUE_GAIN Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 10/17] media: i2c: Add hblank " Daniel Scally
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

Add a V4L2_CID_VBLANK control to the ov8865 driver.

Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- None

 drivers/media/i2c/ov8865.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index 2d5b7b8c2c9e..27043b9426a1 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -183,6 +183,8 @@
 #define OV8865_VTS_H(v)				(((v) & GENMASK(11, 8)) >> 8)
 #define OV8865_VTS_L_REG			0x380f
 #define OV8865_VTS_L(v)				((v) & GENMASK(7, 0))
+#define OV8865_TIMING_MAX_VTS			0xffff
+#define OV8865_TIMING_MIN_VTS			0x04
 #define OV8865_OFFSET_X_H_REG			0x3810
 #define OV8865_OFFSET_X_H(v)			(((v) & GENMASK(15, 8)) >> 8)
 #define OV8865_OFFSET_X_L_REG			0x3811
@@ -675,6 +677,7 @@ struct ov8865_state {
 struct ov8865_ctrls {
 	struct v4l2_ctrl *link_freq;
 	struct v4l2_ctrl *pixel_rate;
+	struct v4l2_ctrl *vblank;
 
 	struct v4l2_ctrl_handler handler;
 };
@@ -2225,6 +2228,20 @@ static int ov8865_test_pattern_configure(struct ov8865_sensor *sensor,
 			    ov8865_test_pattern_bits[index]);
 }
 
+/* Blanking */
+
+static int ov8865_vts_configure(struct ov8865_sensor *sensor, u32 vblank)
+{
+	u16 vts = sensor->state.mode->output_size_y + vblank;
+	int ret;
+
+	ret = ov8865_write(sensor, OV8865_VTS_H_REG, OV8865_VTS_H(vts));
+	if (ret)
+		return ret;
+
+	return ov8865_write(sensor, OV8865_VTS_L_REG, OV8865_VTS_L(vts));
+}
+
 /* State */
 
 static int ov8865_state_mipi_configure(struct ov8865_sensor *sensor,
@@ -2476,6 +2493,8 @@ static int ov8865_s_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_TEST_PATTERN:
 		index = (unsigned int)ctrl->val;
 		return ov8865_test_pattern_configure(sensor, index);
+	case V4L2_CID_VBLANK:
+		return ov8865_vts_configure(sensor, ctrl->val);
 	default:
 		return -EINVAL;
 	}
@@ -2492,6 +2511,8 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
 	struct ov8865_ctrls *ctrls = &sensor->ctrls;
 	struct v4l2_ctrl_handler *handler = &ctrls->handler;
 	const struct v4l2_ctrl_ops *ops = &ov8865_ctrl_ops;
+	const struct ov8865_mode *mode = &ov8865_modes[0];
+	unsigned int vblank_max, vblank_def;
 	int ret;
 
 	v4l2_ctrl_handler_init(handler, 32);
@@ -2528,6 +2549,13 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
 				     ARRAY_SIZE(ov8865_test_pattern_menu) - 1,
 				     0, 0, ov8865_test_pattern_menu);
 
+	/* Blanking */
+	vblank_max = OV8865_TIMING_MAX_VTS - mode->output_size_y;
+	vblank_def = mode->vts - mode->output_size_y;
+	ctrls->vblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_VBLANK,
+					  OV8865_TIMING_MIN_VTS, vblank_max, 1,
+					  vblank_def);
+
 	/* MIPI CSI-2 */
 
 	ctrls->link_freq =
@@ -2708,6 +2736,10 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
 		 sensor->state.mbus_code != mbus_code)
 		ret = ov8865_state_configure(sensor, mode, mbus_code);
 
+	__v4l2_ctrl_modify_range(sensor->ctrls.vblank, OV8865_TIMING_MIN_VTS,
+				 OV8865_TIMING_MAX_VTS - mode->output_size_y,
+				 1, mode->vts - mode->output_size_y);
+
 complete:
 	mutex_unlock(&sensor->mutex);
 
-- 
2.25.1


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

* [PATCH v5 10/17] media: i2c: Add hblank control to ov8865
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (8 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 09/17] media: i2c: Add vblank control to ov8865 Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 11/17] media: i2c: Update HTS values in ov8865 Daniel Scally
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

Add a V4L2_CID_HBLANK control to the ov8865 driver. This is read only
with timing control intended to be done via vblanking alone.

Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- None

 drivers/media/i2c/ov8865.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index 27043b9426a1..f1ee0e425adf 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -677,6 +677,7 @@ struct ov8865_state {
 struct ov8865_ctrls {
 	struct v4l2_ctrl *link_freq;
 	struct v4l2_ctrl *pixel_rate;
+	struct v4l2_ctrl *hblank;
 	struct v4l2_ctrl *vblank;
 
 	struct v4l2_ctrl_handler handler;
@@ -2513,6 +2514,7 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
 	const struct v4l2_ctrl_ops *ops = &ov8865_ctrl_ops;
 	const struct ov8865_mode *mode = &ov8865_modes[0];
 	unsigned int vblank_max, vblank_def;
+	unsigned int hblank;
 	int ret;
 
 	v4l2_ctrl_handler_init(handler, 32);
@@ -2550,6 +2552,13 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
 				     0, 0, ov8865_test_pattern_menu);
 
 	/* Blanking */
+	hblank = mode->hts - mode->output_size_x;
+	ctrls->hblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_HBLANK, hblank,
+					  hblank, 1, hblank);
+
+	if (ctrls->hblank)
+		ctrls->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
 	vblank_max = OV8865_TIMING_MAX_VTS - mode->output_size_y;
 	vblank_def = mode->vts - mode->output_size_y;
 	ctrls->vblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_VBLANK,
@@ -2696,6 +2705,7 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
 	struct v4l2_mbus_framefmt *mbus_format = &format->format;
 	const struct ov8865_mode *mode;
 	u32 mbus_code = 0;
+	unsigned int hblank;
 	unsigned int index;
 	int ret = 0;
 
@@ -2740,6 +2750,10 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
 				 OV8865_TIMING_MAX_VTS - mode->output_size_y,
 				 1, mode->vts - mode->output_size_y);
 
+	hblank = mode->hts - mode->output_size_x;
+	__v4l2_ctrl_modify_range(sensor->ctrls.hblank, hblank, hblank, 1,
+				 hblank);
+
 complete:
 	mutex_unlock(&sensor->mutex);
 
-- 
2.25.1


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

* [PATCH v5 11/17] media: i2c: Update HTS values in ov8865
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (9 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 10/17] media: i2c: Add hblank " Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 12/17] media: i2c: cap exposure at height + vblank " Daniel Scally
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

The HTS values for some of the modes in the ov8865 driver are a bit
unusual, coming in lower than the output_size_x is set to. It seems
like they might be calculated to fit the desired framerate into a
configuration with just two data lanes. To bring this more in line
with expected behaviour, raise the HTS values above the output_size_x.

The corollary of that change is that the hardcoded frame intervals
against the modes no longer make sense, so remove those entirely.
Update the .g/s_frame_interval() callbacks to calculate the frame
interval based on the current mode and the vblank and hblank settings.

The implementation of the .enum_frame_interval() callback is no longer
suitable since the possible frame rate is now a continuous range depending
on the vblank control setting, so remove that callback entirely.

Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- None

 drivers/media/i2c/ov8865.c | 65 +++++++-------------------------------
 1 file changed, 11 insertions(+), 54 deletions(-)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index f1ee0e425adf..f4a899e463de 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -659,8 +659,6 @@ struct ov8865_mode {
 	unsigned int blc_anchor_right_start;
 	unsigned int blc_anchor_right_end;
 
-	struct v4l2_fract frame_interval;
-
 	bool pll2_binning;
 
 	const struct ov8865_register_value *register_values;
@@ -964,7 +962,7 @@ static const struct ov8865_mode ov8865_modes[] = {
 	{
 		/* Horizontal */
 		.output_size_x			= 3264,
-		.hts				= 1944,
+		.hts				= 3888,
 
 		/* Vertical */
 		.output_size_y			= 2448,
@@ -1003,9 +1001,6 @@ static const struct ov8865_mode ov8865_modes[] = {
 		.blc_anchor_right_start		= 1984,
 		.blc_anchor_right_end		= 2239,
 
-		/* Frame Interval */
-		.frame_interval			= { 1, 30 },
-
 		/* PLL */
 		.pll2_binning			= false,
 
@@ -1018,11 +1013,11 @@ static const struct ov8865_mode ov8865_modes[] = {
 	{
 		/* Horizontal */
 		.output_size_x			= 3264,
-		.hts				= 2582,
+		.hts				= 3888,
 
 		/* Vertical */
 		.output_size_y			= 1836,
-		.vts				= 2002,
+		.vts				= 2470,
 
 		.size_auto			= true,
 		.size_auto_boundary_x		= 8,
@@ -1057,9 +1052,6 @@ static const struct ov8865_mode ov8865_modes[] = {
 		.blc_anchor_right_start		= 1984,
 		.blc_anchor_right_end		= 2239,
 
-		/* Frame Interval */
-		.frame_interval			= { 1, 30 },
-
 		/* PLL */
 		.pll2_binning			= false,
 
@@ -1115,9 +1107,6 @@ static const struct ov8865_mode ov8865_modes[] = {
 		.blc_anchor_right_start		= 992,
 		.blc_anchor_right_end		= 1119,
 
-		/* Frame Interval */
-		.frame_interval			= { 1, 30 },
-
 		/* PLL */
 		.pll2_binning			= true,
 
@@ -1179,9 +1168,6 @@ static const struct ov8865_mode ov8865_modes[] = {
 		.blc_anchor_right_start		= 992,
 		.blc_anchor_right_end		= 1119,
 
-		/* Frame Interval */
-		.frame_interval			= { 1, 90 },
-
 		/* PLL */
 		.pll2_binning			= true,
 
@@ -2628,11 +2614,18 @@ static int ov8865_g_frame_interval(struct v4l2_subdev *subdev,
 {
 	struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
 	const struct ov8865_mode *mode;
+	unsigned int framesize;
+	unsigned int fps;
 
 	mutex_lock(&sensor->mutex);
 
 	mode = sensor->state.mode;
-	interval->interval = mode->frame_interval;
+	framesize = mode->hts * (mode->output_size_y +
+				 sensor->ctrls.vblank->val);
+	fps = DIV_ROUND_CLOSEST(sensor->ctrls.pixel_rate->val, framesize);
+
+	interval->interval.numerator = 1;
+	interval->interval.denominator = fps;
 
 	mutex_unlock(&sensor->mutex);
 
@@ -2777,41 +2770,6 @@ static int ov8865_enum_frame_size(struct v4l2_subdev *subdev,
 	return 0;
 }
 
-static int ov8865_enum_frame_interval(struct v4l2_subdev *subdev,
-				      struct v4l2_subdev_state *sd_state,
-				      struct v4l2_subdev_frame_interval_enum *interval_enum)
-{
-	const struct ov8865_mode *mode = NULL;
-	unsigned int mode_index;
-	unsigned int interval_index;
-
-	if (interval_enum->index > 0)
-		return -EINVAL;
-	/*
-	 * Multiple modes with the same dimensions may have different frame
-	 * intervals, so look up each relevant mode.
-	 */
-	for (mode_index = 0, interval_index = 0;
-	     mode_index < ARRAY_SIZE(ov8865_modes); mode_index++) {
-		mode = &ov8865_modes[mode_index];
-
-		if (mode->output_size_x == interval_enum->width &&
-		    mode->output_size_y == interval_enum->height) {
-			if (interval_index == interval_enum->index)
-				break;
-
-			interval_index++;
-		}
-	}
-
-	if (mode_index == ARRAY_SIZE(ov8865_modes))
-		return -EINVAL;
-
-	interval_enum->interval = mode->frame_interval;
-
-	return 0;
-}
-
 static void
 __ov8865_get_pad_crop(struct ov8865_sensor *sensor,
 		      struct v4l2_subdev_state *state, unsigned int pad,
@@ -2870,7 +2828,6 @@ static const struct v4l2_subdev_pad_ops ov8865_subdev_pad_ops = {
 	.get_fmt		= ov8865_get_fmt,
 	.set_fmt		= ov8865_set_fmt,
 	.enum_frame_size	= ov8865_enum_frame_size,
-	.enum_frame_interval	= ov8865_enum_frame_interval,
 	.get_selection		= ov8865_get_selection,
 	.set_selection		= ov8865_get_selection,
 };
-- 
2.25.1


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

* [PATCH v5 12/17] media: i2c: cap exposure at height + vblank in ov8865
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (10 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 11/17] media: i2c: Update HTS values in ov8865 Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 13/17] media: i2c: Add controls from fwnode to ov8865 Daniel Scally
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

Exposure limits depend on the total height; when vblank is altered (and
thus the total height is altered), change the exposure limits to reflect
the new cap.

Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- (JM) Added OV8865_INTEGRATION_TIME_MARGIN to reduce the maximum
	possible exposure, without which setting values within 8 lines of max
	causes an entirely black image.

 drivers/media/i2c/ov8865.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index f4a899e463de..811438c44b58 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -143,6 +143,7 @@
 #define OV8865_EXPOSURE_CTRL_L_REG		0x3502
 #define OV8865_EXPOSURE_CTRL_L(v)		((v) & GENMASK(7, 0))
 #define OV8865_EXPOSURE_GAIN_MANUAL_REG		0x3503
+#define OV8865_INTEGRATION_TIME_MARGIN		8
 
 #define OV8865_GAIN_CTRL_H_REG			0x3508
 #define OV8865_GAIN_CTRL_H(v)			(((v) & GENMASK(12, 8)) >> 8)
@@ -677,6 +678,7 @@ struct ov8865_ctrls {
 	struct v4l2_ctrl *pixel_rate;
 	struct v4l2_ctrl *hblank;
 	struct v4l2_ctrl *vblank;
+	struct v4l2_ctrl *exposure;
 
 	struct v4l2_ctrl_handler handler;
 };
@@ -2454,6 +2456,20 @@ static int ov8865_s_ctrl(struct v4l2_ctrl *ctrl)
 	unsigned int index;
 	int ret;
 
+	/* If VBLANK is altered we need to update exposure to compensate */
+	if (ctrl->id == V4L2_CID_VBLANK) {
+		int exposure_max;
+
+		exposure_max = sensor->state.mode->output_size_y + ctrl->val -
+			       OV8865_INTEGRATION_TIME_MARGIN;
+		__v4l2_ctrl_modify_range(sensor->ctrls.exposure,
+					 sensor->ctrls.exposure->minimum,
+					 exposure_max,
+					 sensor->ctrls.exposure->step,
+					 min(sensor->ctrls.exposure->val,
+					     exposure_max));
+	}
+
 	/* Wait for the sensor to be on before setting controls. */
 	if (pm_runtime_suspended(sensor->dev))
 		return 0;
@@ -2510,8 +2526,8 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
 
 	/* Exposure */
 
-	v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 16, 1048575, 16,
-			  512);
+	ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 16,
+					    1048575, 16, 512);
 
 	/* Gain */
 
@@ -2700,6 +2716,7 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
 	u32 mbus_code = 0;
 	unsigned int hblank;
 	unsigned int index;
+	int exposure_max;
 	int ret = 0;
 
 	mutex_lock(&sensor->mutex);
@@ -2747,6 +2764,13 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
 	__v4l2_ctrl_modify_range(sensor->ctrls.hblank, hblank, hblank, 1,
 				 hblank);
 
+	exposure_max = mode->vts - OV8865_INTEGRATION_TIME_MARGIN;
+	__v4l2_ctrl_modify_range(sensor->ctrls.exposure,
+				 sensor->ctrls.exposure->minimum, exposure_max,
+				 sensor->ctrls.exposure->step,
+				 min(sensor->ctrls.exposure->val,
+				     exposure_max));
+
 complete:
 	mutex_unlock(&sensor->mutex);
 
-- 
2.25.1


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

* [PATCH v5 13/17] media: i2c: Add controls from fwnode to ov8865
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (11 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 12/17] media: i2c: cap exposure at height + vblank " Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 14/17] media: i2c: Switch exposure control unit to lines Daniel Scally
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

Add V4L2_CID_CAMERA_ORIENTATION and V4L2_CID_CAMERA_SENSOR_ROTATION
controls to the ov8865 driver by attempting to parse them from firmware.

Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- None

 drivers/media/i2c/ov8865.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index 811438c44b58..45b569f1e7c0 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -2515,6 +2515,7 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
 	struct v4l2_ctrl_handler *handler = &ctrls->handler;
 	const struct v4l2_ctrl_ops *ops = &ov8865_ctrl_ops;
 	const struct ov8865_mode *mode = &ov8865_modes[0];
+	struct v4l2_fwnode_device_properties props;
 	unsigned int vblank_max, vblank_def;
 	unsigned int hblank;
 	int ret;
@@ -2578,6 +2579,15 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
 		v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, 1,
 				  INT_MAX, 1, 1);
 
+	/* set properties from fwnode (e.g. rotation, orientation) */
+	ret = v4l2_fwnode_device_parse(sensor->dev, &props);
+	if (ret)
+		goto error_ctrls;
+
+	ret = v4l2_ctrl_new_fwnode_properties(handler, ops, &props);
+	if (ret)
+		goto error_ctrls;
+
 	if (handler->error) {
 		ret = handler->error;
 		goto error_ctrls;
-- 
2.25.1


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

* [PATCH v5 14/17] media: i2c: Switch exposure control unit to lines
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (12 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 13/17] media: i2c: Add controls from fwnode to ov8865 Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  6:24   ` Jean-Michel Hautbois
  2021-11-23  0:00 ` [PATCH v5 15/17] media: i2c: Use dev_err_probe() in ov8865 Daniel Scally
                   ` (4 subsequent siblings)
  18 siblings, 1 reply; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

The ov8865 driver currently has the unit of the V4L2_CID_EXPOSURE control
as 1/16th of a line. This is what the sensor expects, but isn't very
intuitive. Switch the control to be in units of a line and simply do the
16x multiplication before passing the value to the sensor.

The datasheet for this sensor gives minimum exposure as 2 lines, so take
the opportunity to correct the lower bounds of the control.

Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- None

 drivers/media/i2c/ov8865.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index 45b569f1e7c0..1cc9f78bb97a 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -2126,6 +2126,9 @@ static int ov8865_exposure_configure(struct ov8865_sensor *sensor, u32 exposure)
 {
 	int ret;
 
+	/* The sensor stores exposure in units of 1/16th of a line */
+	exposure *= 16;
+
 	ret = ov8865_write(sensor, OV8865_EXPOSURE_CTRL_HH_REG,
 			   OV8865_EXPOSURE_CTRL_HH(exposure));
 	if (ret)
@@ -2527,8 +2530,8 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
 
 	/* Exposure */
 
-	ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 16,
-					    1048575, 16, 512);
+	ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 2,
+					    65535, 1, 32);
 
 	/* Gain */
 
-- 
2.25.1


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

* [PATCH v5 15/17] media: i2c: Use dev_err_probe() in ov8865
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (13 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 14/17] media: i2c: Switch exposure control unit to lines Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 16/17] media: i2c: Fix max gain " Daniel Scally
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

There is a chance that regulator_get() returns -EPROBE_DEFER, in which
case printing an error message is undesirable. To avoid spurious messages
in dmesg in the event that -EPROBE_DEFER is returned, use dev_err_probe()
on error paths for regulator_get().

Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- None

 drivers/media/i2c/ov8865.c | 46 +++++++++++++++++---------------------
 1 file changed, 20 insertions(+), 26 deletions(-)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index 1cc9f78bb97a..1aa577dba0a3 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -2957,6 +2957,26 @@ static int ov8865_probe(struct i2c_client *client)
 	sensor->dev = dev;
 	sensor->i2c_client = client;
 
+	/* Regulators */
+
+	/* DVDD: digital core */
+	sensor->dvdd = devm_regulator_get(dev, "dvdd");
+	if (IS_ERR(sensor->dvdd))
+		return dev_err_probe(dev, PTR_ERR(sensor->dvdd),
+				     "cannot get DVDD regulator\n");
+
+	/* DOVDD: digital I/O */
+	sensor->dovdd = devm_regulator_get(dev, "dovdd");
+	if (IS_ERR(sensor->dovdd))
+		return dev_err_probe(dev, PTR_ERR(sensor->dovdd),
+				     "cannot get DOVDD regulator\n");
+
+	/* AVDD: analog */
+	sensor->avdd = devm_regulator_get(dev, "avdd");
+	if (IS_ERR(sensor->avdd))
+		return dev_err_probe(dev, PTR_ERR(sensor->avdd),
+				     "cannot get AVDD (analog) regulator\n");
+
 	/* Graph Endpoint */
 
 	handle = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
@@ -2987,32 +3007,6 @@ static int ov8865_probe(struct i2c_client *client)
 		goto error_endpoint;
 	}
 
-	/* Regulators */
-
-	/* DVDD: digital core */
-	sensor->dvdd = devm_regulator_get(dev, "dvdd");
-	if (IS_ERR(sensor->dvdd)) {
-		dev_err(dev, "cannot get DVDD (digital core) regulator\n");
-		ret = PTR_ERR(sensor->dvdd);
-		goto error_endpoint;
-	}
-
-	/* DOVDD: digital I/O */
-	sensor->dovdd = devm_regulator_get(dev, "dovdd");
-	if (IS_ERR(sensor->dovdd)) {
-		dev_err(dev, "cannot get DOVDD (digital I/O) regulator\n");
-		ret = PTR_ERR(sensor->dovdd);
-		goto error_endpoint;
-	}
-
-	/* AVDD: analog */
-	sensor->avdd = devm_regulator_get(dev, "avdd");
-	if (IS_ERR(sensor->avdd)) {
-		dev_err(dev, "cannot get AVDD (analog) regulator\n");
-		ret = PTR_ERR(sensor->avdd);
-		goto error_endpoint;
-	}
-
 	/* External Clock */
 
 	sensor->extclk = devm_clk_get(dev, NULL);
-- 
2.25.1


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

* [PATCH v5 16/17] media: i2c: Fix max gain in ov8865
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (14 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 15/17] media: i2c: Use dev_err_probe() in ov8865 Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23  0:00 ` [PATCH v5 17/17] media: ipu3-cio2: Add INT347A to cio2-bridge Daniel Scally
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede

The maximum gain figure in the v4l2 ctrl is wrong. The field is 12 bits
wide, which is where the 8191 figure comes from, but the datasheet is
specific that maximum gain is 16x (the low seven bits are fractional, so
16x gain is 2048)

Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- Patch added

 drivers/media/i2c/ov8865.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index 1aa577dba0a3..ebdb20d3fe9d 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -2535,7 +2535,7 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
 
 	/* Gain */
 
-	v4l2_ctrl_new_std(handler, ops, V4L2_CID_ANALOGUE_GAIN, 128, 8191, 128,
+	v4l2_ctrl_new_std(handler, ops, V4L2_CID_ANALOGUE_GAIN, 128, 2048, 128,
 			  128);
 
 	/* White Balance */
-- 
2.25.1


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

* [PATCH v5 17/17] media: ipu3-cio2: Add INT347A to cio2-bridge
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (15 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 16/17] media: i2c: Fix max gain " Daniel Scally
@ 2021-11-23  0:00 ` Daniel Scally
  2021-11-23 10:47 ` [PATCH v5 00/17] Extensions to ov8865 driver Sakari Ailus
  2021-11-25 20:37 ` Hans de Goede
  18 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23  0:00 UTC (permalink / raw)
  To: linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham, hdegoede,
	Andy Shevchenko

ACPI _HID INT347A represents the OV8865 sensor, the driver for which can
support the platforms that the cio2-bridge serves. Add it to the array
of supported sensors so the bridge will connect the sensor to the CIO2
device.

Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes in v5: 

	- None

 drivers/media/pci/intel/ipu3/cio2-bridge.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
index 0b586b4e537e..4550be801311 100644
--- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
+++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
@@ -22,6 +22,8 @@
 static const struct cio2_sensor_config cio2_supported_sensors[] = {
 	/* Omnivision OV5693 */
 	CIO2_SENSOR_CONFIG("INT33BE", 0),
+	/* Omnivision OV8865 */
+	CIO2_SENSOR_CONFIG("INT347A", 1, 360000000),
 	/* Omnivision OV2680 */
 	CIO2_SENSOR_CONFIG("OVTI2680", 0),
 };
-- 
2.25.1


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

* Re: [PATCH v5 14/17] media: i2c: Switch exposure control unit to lines
  2021-11-23  0:00 ` [PATCH v5 14/17] media: i2c: Switch exposure control unit to lines Daniel Scally
@ 2021-11-23  6:24   ` Jean-Michel Hautbois
  0 siblings, 0 replies; 22+ messages in thread
From: Jean-Michel Hautbois @ 2021-11-23  6:24 UTC (permalink / raw)
  To: Daniel Scally, linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, kieran.bingham, hdegoede

Hi Daniel,

Thanks for the patch !

On 23/11/2021 01:00, Daniel Scally wrote:
> The ov8865 driver currently has the unit of the V4L2_CID_EXPOSURE control
> as 1/16th of a line. This is what the sensor expects, but isn't very
> intuitive. Switch the control to be in units of a line and simply do the
> 16x multiplication before passing the value to the sensor.
> 
> The datasheet for this sensor gives minimum exposure as 2 lines, so take
> the opportunity to correct the lower bounds of the control.
> 
> Signed-off-by: Daniel Scally <djrscally@gmail.com>
Tested-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>

> ---
> Changes in v5:
> 
> 	- None
> 
>   drivers/media/i2c/ov8865.c | 7 +++++--
>   1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
> index 45b569f1e7c0..1cc9f78bb97a 100644
> --- a/drivers/media/i2c/ov8865.c
> +++ b/drivers/media/i2c/ov8865.c
> @@ -2126,6 +2126,9 @@ static int ov8865_exposure_configure(struct ov8865_sensor *sensor, u32 exposure)
>   {
>   	int ret;
>   
> +	/* The sensor stores exposure in units of 1/16th of a line */
> +	exposure *= 16;
> +
>   	ret = ov8865_write(sensor, OV8865_EXPOSURE_CTRL_HH_REG,
>   			   OV8865_EXPOSURE_CTRL_HH(exposure));
>   	if (ret)
> @@ -2527,8 +2530,8 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
>   
>   	/* Exposure */
>   
> -	ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 16,
> -					    1048575, 16, 512);
> +	ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 2,
> +					    65535, 1, 32);
>   
>   	/* Gain */
>   
> 

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

* Re: [PATCH v5 00/17] Extensions to ov8865 driver
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (16 preceding siblings ...)
  2021-11-23  0:00 ` [PATCH v5 17/17] media: ipu3-cio2: Add INT347A to cio2-bridge Daniel Scally
@ 2021-11-23 10:47 ` Sakari Ailus
  2021-11-23 12:10   ` Daniel Scally
  2021-11-25 20:37 ` Hans de Goede
  18 siblings, 1 reply; 22+ messages in thread
From: Sakari Ailus @ 2021-11-23 10:47 UTC (permalink / raw)
  To: Daniel Scally
  Cc: linux-media, paul.kocialkowski, andriy.shevchenko,
	laurent.pinchart, yong.zhi, bingbu.cao, jeanmichel.hautbois,
	kieran.bingham, hdegoede

On Tue, Nov 23, 2021 at 12:00:00AM +0000, Daniel Scally wrote:
> Hello all
> 
> This series extends the ov8865 driver with:
> 
> * Support for binding to ACPI enumerated devices.
> * Support for a 19.2MHz clock in addition to existing 24MHz clock support
> * Another v4l2_subdev_pad_ops callback
> * 4 more V4L2 controls
> * makes the driver supported by the cio2-bridge
> 
> There's also a little bit of tidying that I did along the way.
> 
> The series is tested on an MS Surface Go 2.

Nice patches.

Thanks, Daniel!

-- 
Sakari Ailus

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

* Re: [PATCH v5 00/17] Extensions to ov8865 driver
  2021-11-23 10:47 ` [PATCH v5 00/17] Extensions to ov8865 driver Sakari Ailus
@ 2021-11-23 12:10   ` Daniel Scally
  0 siblings, 0 replies; 22+ messages in thread
From: Daniel Scally @ 2021-11-23 12:10 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, paul.kocialkowski, andriy.shevchenko,
	laurent.pinchart, yong.zhi, bingbu.cao, jeanmichel.hautbois,
	kieran.bingham, hdegoede


On 23/11/2021 10:47, Sakari Ailus wrote:
> On Tue, Nov 23, 2021 at 12:00:00AM +0000, Daniel Scally wrote:
>> Hello all
>>
>> This series extends the ov8865 driver with:
>>
>> * Support for binding to ACPI enumerated devices.
>> * Support for a 19.2MHz clock in addition to existing 24MHz clock support
>> * Another v4l2_subdev_pad_ops callback
>> * 4 more V4L2 controls
>> * makes the driver supported by the cio2-bridge
>>
>> There's also a little bit of tidying that I did along the way.
>>
>> The series is tested on an MS Surface Go 2.
> Nice patches.
>
> Thanks, Daniel!
>
Thank you :)

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

* Re: [PATCH v5 00/17] Extensions to ov8865 driver
  2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
                   ` (17 preceding siblings ...)
  2021-11-23 10:47 ` [PATCH v5 00/17] Extensions to ov8865 driver Sakari Ailus
@ 2021-11-25 20:37 ` Hans de Goede
  18 siblings, 0 replies; 22+ messages in thread
From: Hans de Goede @ 2021-11-25 20:37 UTC (permalink / raw)
  To: Daniel Scally, linux-media, paul.kocialkowski
  Cc: sakari.ailus, andriy.shevchenko, laurent.pinchart, yong.zhi,
	bingbu.cao, jeanmichel.hautbois, kieran.bingham

Hi,

On 11/23/21 01:00, Daniel Scally wrote:
> Hello all
> 
> This series extends the ov8865 driver with:
> 
> * Support for binding to ACPI enumerated devices.
> * Support for a 19.2MHz clock in addition to existing 24MHz clock support
> * Another v4l2_subdev_pad_ops callback
> * 4 more V4L2 controls
> * makes the driver supported by the cio2-bridge
> 
> There's also a little bit of tidying that I did along the way.
> 
> The series is tested on an MS Surface Go 2.


Thank you.

The patches look good to me and I've tested this series on a Microsoft Surface
Go (version 1) and everything works as it should:

Acked-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans




> Series level changes since v4:
> 
> 	- Moved the two patches fixing issues to the head of the series and
> 	added Fixes tags
> 	- Added a new patch fixing the maximum gain value
> 
> Daniel Scally (16):
>   media: i2c: Re-order runtime pm initialisation
>   media: i2c: Add ACPI support to ov8865
>   media: i2c: Fix incorrect value in comment
>   media: i2c: Defer probe if not endpoint found
>   media: i2c: Support 19.2MHz input clock in ov8865
>   media: i2c: Add .get_selection() support to ov8865
>   media: i2c: Switch control to V4L2_CID_ANALOGUE_GAIN
>   media: i2c: Add vblank control to ov8865
>   media: i2c: Add hblank control to ov8865
>   media: i2c: Update HTS values in ov8865
>   media: i2c: cap exposure at height + vblank in ov8865
>   media: i2c: Add controls from fwnode to ov8865
>   media: i2c: Switch exposure control unit to lines
>   media: i2c: Use dev_err_probe() in ov8865
>   media: i2c: Fix max gain in ov8865
>   media: ipu3-cio2: Add INT347A to cio2-bridge
> 
> Hans de Goede (1):
>   media: i2c: ov8865: Fix lockdep error
> 
>  drivers/media/i2c/ov8865.c                 | 466 +++++++++++++++------
>  drivers/media/pci/intel/ipu3/cio2-bridge.c |   2 +
>  2 files changed, 334 insertions(+), 134 deletions(-)
> 


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

end of thread, other threads:[~2021-11-25 20:39 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-23  0:00 [PATCH v5 00/17] Extensions to ov8865 driver Daniel Scally
2021-11-23  0:00 ` [PATCH v5 01/17] media: i2c: Re-order runtime pm initialisation Daniel Scally
2021-11-23  0:00 ` [PATCH v5 02/17] media: i2c: ov8865: Fix lockdep error Daniel Scally
2021-11-23  0:00 ` [PATCH v5 03/17] media: i2c: Add ACPI support to ov8865 Daniel Scally
2021-11-23  0:00 ` [PATCH v5 04/17] media: i2c: Fix incorrect value in comment Daniel Scally
2021-11-23  0:00 ` [PATCH v5 05/17] media: i2c: Defer probe if not endpoint found Daniel Scally
2021-11-23  0:00 ` [PATCH v5 06/17] media: i2c: Support 19.2MHz input clock in ov8865 Daniel Scally
2021-11-23  0:00 ` [PATCH v5 07/17] media: i2c: Add .get_selection() support to ov8865 Daniel Scally
2021-11-23  0:00 ` [PATCH v5 08/17] media: i2c: Switch control to V4L2_CID_ANALOGUE_GAIN Daniel Scally
2021-11-23  0:00 ` [PATCH v5 09/17] media: i2c: Add vblank control to ov8865 Daniel Scally
2021-11-23  0:00 ` [PATCH v5 10/17] media: i2c: Add hblank " Daniel Scally
2021-11-23  0:00 ` [PATCH v5 11/17] media: i2c: Update HTS values in ov8865 Daniel Scally
2021-11-23  0:00 ` [PATCH v5 12/17] media: i2c: cap exposure at height + vblank " Daniel Scally
2021-11-23  0:00 ` [PATCH v5 13/17] media: i2c: Add controls from fwnode to ov8865 Daniel Scally
2021-11-23  0:00 ` [PATCH v5 14/17] media: i2c: Switch exposure control unit to lines Daniel Scally
2021-11-23  6:24   ` Jean-Michel Hautbois
2021-11-23  0:00 ` [PATCH v5 15/17] media: i2c: Use dev_err_probe() in ov8865 Daniel Scally
2021-11-23  0:00 ` [PATCH v5 16/17] media: i2c: Fix max gain " Daniel Scally
2021-11-23  0:00 ` [PATCH v5 17/17] media: ipu3-cio2: Add INT347A to cio2-bridge Daniel Scally
2021-11-23 10:47 ` [PATCH v5 00/17] Extensions to ov8865 driver Sakari Ailus
2021-11-23 12:10   ` Daniel Scally
2021-11-25 20:37 ` Hans de Goede

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.