All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/11] media: i2c: max9286: Small new features
@ 2022-01-01 18:27 Laurent Pinchart
  2022-01-01 18:27 ` [PATCH v2 01/11] dt-bindings: media: i2c: max9286: Add support for per-port supplies Laurent Pinchart
                   ` (11 more replies)
  0 siblings, 12 replies; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-01 18:27 UTC (permalink / raw)
  To: linux-media
  Cc: linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan, Rob Herring, devicetree,
	Mark Brown, Liam Girdwood

Hello,

This small patch series adds a few new features to the max9286 driver:

- Support for per-port supplies (01/11 and 04/11)
- Remote I2C bus speed selection (02/11 and 09/11)
- GMSL bus width selection (03/11 and 10/11)
- Manual framesync operation (05/11)
- RAW12 support (06/11 and 07/11)

The remaining patches are small cleanups. Please see individual patches
for details.

I'm in two minds about the bus width selection. It would be possible to
query the information from the connected serializers at runtime, using
for instance the .g_mbus_config() subdev operation. On the other hand,
there's *lots* of GMSL-specific bus configuration options, which would
require a rework of .g_mbus_config() to pass a bus-specific structure.
We would then end up having many configuration parameters not specific
to video there (such as the I2C speed for instance). Furthermore, while
some parameters may be different between cameras (high-immunity mode,
for instance, can be configured per port), many need to be identical on
all ports. I'm not sure yet what the best way to address that without an
overcomplicated implementation would be (one option would be to get the
parameters from the first camera and simply ignore conflicting values
reported by other cameras). Thoughts are welcome.

Could someone with RDACM20 cameras test the series ? I'm a bit worried
about patch 11/11 in particular, there's a small risk of regression.

Laurent Pinchart (10):
  dt-bindings: media: i2c: max9286: Add support for per-port supplies
  dt-bindings: media: i2c: max9286: Add property to select I2C speed
  dt-bindings: media: i2c: max9286: Add property to select bus width
  media: i2c: max9286: Support manual framesync operation
  media: i2c: max9286: Rename MAX9286_DATATYPE_RAW11 to RAW12
  media: i2c: max9286: Support 12-bit raw bayer formats
  media: i2c: max9286: Define macros for all bits of register 0x15
  media: i2c: max9286: Configure remote I2C speed from device tree
  media: i2c: max9286: Configure bus width from device tree
  media: i2c: max9286: Select HS as data enable signal

Thomas Nizan (1):
  media: i2c: max9286: Add support for port regulators

 .../bindings/media/i2c/maxim,max9286.yaml     |  28 +-
 drivers/media/i2c/max9286.c                   | 425 +++++++++++++++---
 2 files changed, 387 insertions(+), 66 deletions(-)


base-commit: 68b9bcc8a534cd11fe55f8bc82f948aae7d81b3c
-- 
Regards,

Laurent Pinchart


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

* [PATCH v2 01/11] dt-bindings: media: i2c: max9286: Add support for per-port supplies
  2022-01-01 18:27 [PATCH v2 00/11] media: i2c: max9286: Small new features Laurent Pinchart
@ 2022-01-01 18:27 ` Laurent Pinchart
  2022-01-09 11:48   ` Jacopo Mondi
  2022-01-10 20:47   ` Rob Herring
  2022-01-01 18:27 ` [PATCH v2 02/11] dt-bindings: media: i2c: max9286: Add property to select I2C speed Laurent Pinchart
                   ` (10 subsequent siblings)
  11 siblings, 2 replies; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-01 18:27 UTC (permalink / raw)
  To: linux-media
  Cc: linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan, Rob Herring, devicetree,
	Mark Brown, Liam Girdwood

Power supplies for the ports can be controlled per port depending on the
hardware design. Support per-port supplies in the DT bindings, mutually
exclusive with the global supply.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
Changes since v1:

- Simplify mutual exclusion condition
---
 .../bindings/media/i2c/maxim,max9286.yaml          | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
index 02f656e78700..c20557b52e45 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
@@ -39,7 +39,7 @@ properties:
     maxItems: 1
 
   poc-supply:
-    description: Regulator providing Power over Coax to the cameras
+    description: Regulator providing Power over Coax to all the ports
 
   enable-gpios:
     description: GPIO connected to the \#PWDN pin with inverted polarity
@@ -160,6 +160,10 @@ properties:
 
             additionalProperties: false
 
+patternProperties:
+  "^port[0-3]-poc-supply$":
+    description: Regulator providing Power over Coax for a particular port
+
 required:
   - compatible
   - reg
@@ -167,6 +171,14 @@ required:
   - i2c-mux
   - gpio-controller
 
+allOf:
+  - if:
+      required:
+        - poc-supply
+    then:
+      patternProperties:
+        "^port[0-3]-poc-supply$": false
+
 additionalProperties: false
 
 examples:
-- 
Regards,

Laurent Pinchart


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

* [PATCH v2 02/11] dt-bindings: media: i2c: max9286: Add property to select I2C speed
  2022-01-01 18:27 [PATCH v2 00/11] media: i2c: max9286: Small new features Laurent Pinchart
  2022-01-01 18:27 ` [PATCH v2 01/11] dt-bindings: media: i2c: max9286: Add support for per-port supplies Laurent Pinchart
@ 2022-01-01 18:27 ` Laurent Pinchart
  2022-01-01 22:01   ` Rob Herring
  2022-01-04 15:56   ` Rob Herring
  2022-01-01 18:27 ` [PATCH v2 03/11] dt-bindings: media: i2c: max9286: Add property to select bus width Laurent Pinchart
                   ` (9 subsequent siblings)
  11 siblings, 2 replies; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-01 18:27 UTC (permalink / raw)
  To: linux-media
  Cc: linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan, Rob Herring, devicetree

The I2C speed on the remote side (the I2C master bus of the connected
serializers) is configurable, and doesn't need to match the speed of the
local bus (the slave bus of the MAX9286). All remote buses must use the
same speed, and the MAX9286 needs to be programmed accordingly. Add a
new DT property to select the speed to make it configurable.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 .../devicetree/bindings/media/i2c/maxim,max9286.yaml       | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
index c20557b52e45..5d3e99027a79 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
@@ -50,6 +50,13 @@ properties:
   '#gpio-cells':
     const: 2
 
+  maxim,i2c-clock-frequency:
+    enum: [ 8470, 28300, 84700, 105000, 173000, 339000, 533000, 837000 ]
+    default: 105000
+    description: |
+      The I2C clock frequency for the remote I2C buses. The value must match
+      the configuration of the remote serializers.
+
   maxim,reverse-channel-microvolt:
     minimum: 30000
     maximum: 200000
-- 
Regards,

Laurent Pinchart


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

* [PATCH v2 03/11] dt-bindings: media: i2c: max9286: Add property to select bus width
  2022-01-01 18:27 [PATCH v2 00/11] media: i2c: max9286: Small new features Laurent Pinchart
  2022-01-01 18:27 ` [PATCH v2 01/11] dt-bindings: media: i2c: max9286: Add support for per-port supplies Laurent Pinchart
  2022-01-01 18:27 ` [PATCH v2 02/11] dt-bindings: media: i2c: max9286: Add property to select I2C speed Laurent Pinchart
@ 2022-01-01 18:27 ` Laurent Pinchart
  2022-01-09 11:47   ` Jacopo Mondi
                     ` (2 more replies)
  2022-01-01 18:27 ` [PATCH v2 04/11] media: i2c: max9286: Add support for port regulators Laurent Pinchart
                   ` (8 subsequent siblings)
  11 siblings, 3 replies; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-01 18:27 UTC (permalink / raw)
  To: linux-media
  Cc: linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan, Rob Herring, devicetree

The GMSL serial data bus width is normally selected by the BWS pin, but
it can also be configured by software. Add a DT property that allows
overriding the value of the BWS-selected bus width to support systems
whose BWS pin doesn't result in the correct value.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 .../devicetree/bindings/media/i2c/maxim,max9286.yaml       | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
index 5d3e99027a79..123e98cdb7b6 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
@@ -50,6 +50,13 @@ properties:
   '#gpio-cells':
     const: 2
 
+  maxim,bus-width:
+    enum: [ 24, 27, 32 ]
+    description: |
+      The GMSL serial data bus width. This setting is normally controlled by
+      the BWS pin, but may be overridden with this property. The value must
+      match the configuration of the remote serializers.
+
   maxim,i2c-clock-frequency:
     enum: [ 8470, 28300, 84700, 105000, 173000, 339000, 533000, 837000 ]
     default: 105000
-- 
Regards,

Laurent Pinchart


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

* [PATCH v2 04/11] media: i2c: max9286: Add support for port regulators
  2022-01-01 18:27 [PATCH v2 00/11] media: i2c: max9286: Small new features Laurent Pinchart
                   ` (2 preceding siblings ...)
  2022-01-01 18:27 ` [PATCH v2 03/11] dt-bindings: media: i2c: max9286: Add property to select bus width Laurent Pinchart
@ 2022-01-01 18:27 ` Laurent Pinchart
  2022-01-09 10:04   ` Jacopo Mondi
  2022-01-01 18:28 ` [PATCH v2 05/11] media: i2c: max9286: Support manual framesync operation Laurent Pinchart
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-01 18:27 UTC (permalink / raw)
  To: linux-media
  Cc: linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan, Mark Brown, Liam Girdwood

From: Thomas Nizan <tnizan@witekio.com>

Allow users to use one PoC regulator per port, instead of a global
regulator.

The properties '^port[0-3]-poc-supply$' in the DT node are used to
indicate the regulators for individual ports.

Signed-off-by: Thomas Nizan <tnizan@witekio.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
Changes since v1:

- Use to_index()
- Use dev_err_probe()
- Fix error path in probe()
- Use devm_regulator_get_optional() instead of
  devm_regulator_get_exclusive()
---
 drivers/media/i2c/max9286.c | 107 +++++++++++++++++++++++++++++++-----
 1 file changed, 94 insertions(+), 13 deletions(-)

diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index eb2b8e42335b..15c80034e3a4 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -138,6 +138,7 @@
 struct max9286_source {
 	struct v4l2_subdev *sd;
 	struct fwnode_handle *fwnode;
+	struct regulator *regulator;
 };
 
 struct max9286_asd {
@@ -1071,6 +1072,49 @@ static int max9286_register_gpio(struct max9286_priv *priv)
 	return ret;
 }
 
+static int max9286_poc_power_on(struct max9286_priv *priv)
+{
+	struct max9286_source *source;
+	unsigned int enabled = 0;
+	int ret;
+
+	/* Enable the global regulator if available. */
+	if (priv->regulator)
+		return regulator_enable(priv->regulator);
+
+	/* Otherwise use the per-port regulators. */
+	for_each_source(priv, source) {
+		ret = regulator_enable(source->regulator);
+		if (ret < 0)
+			goto error;
+
+		enabled |= BIT(to_index(priv, source));
+	}
+
+	return 0;
+
+error:
+	for_each_source(priv, source) {
+		if (enabled & BIT(to_index(priv, source)))
+			regulator_disable(source->regulator);
+	}
+
+	return ret;
+}
+
+static void max9286_poc_power_off(struct max9286_priv *priv)
+{
+	struct max9286_source *source;
+
+	if (priv->regulator) {
+		regulator_disable(priv->regulator);
+		return;
+	}
+
+	for_each_source(priv, source)
+		regulator_disable(source->regulator);
+}
+
 static int max9286_init(struct device *dev)
 {
 	struct max9286_priv *priv;
@@ -1081,9 +1125,9 @@ static int max9286_init(struct device *dev)
 	priv = i2c_get_clientdata(client);
 
 	/* Enable the bus power. */
-	ret = regulator_enable(priv->regulator);
+	ret = max9286_poc_power_on(priv);
 	if (ret < 0) {
-		dev_err(&client->dev, "Unable to turn PoC on\n");
+		dev_err(dev, "Unable to turn PoC on\n");
 		return ret;
 	}
 
@@ -1117,7 +1161,7 @@ static int max9286_init(struct device *dev)
 err_v4l2_register:
 	max9286_v4l2_unregister(priv);
 err_regulator:
-	regulator_disable(priv->regulator);
+	max9286_poc_power_off(priv);
 
 	return ret;
 }
@@ -1248,6 +1292,47 @@ static int max9286_parse_dt(struct max9286_priv *priv)
 	return 0;
 }
 
+static int max9286_get_poc_supplies(struct max9286_priv *priv)
+{
+	struct device *dev = &priv->client->dev;
+	struct max9286_source *source;
+	int ret;
+
+	/* Start by getting the global regulator. */
+	priv->regulator = devm_regulator_get_optional(dev, "poc");
+	if (!IS_ERR(priv->regulator))
+		return 0;
+
+	if (PTR_ERR(priv->regulator) != -ENODEV) {
+		if (PTR_ERR(priv->regulator) != -EPROBE_DEFER)
+			dev_err(dev, "Unable to get PoC regulator: %ld\n",
+				PTR_ERR(priv->regulator));
+		return PTR_ERR(priv->regulator);
+	}
+
+	/* If there's no global regulator, get per-port regulators. */
+	dev_dbg(dev,
+		"No global PoC regulator, looking for per-port regulators\n");
+	priv->regulator = NULL;
+
+	for_each_source(priv, source) {
+		unsigned int index = to_index(priv, source);
+		char name[10];
+
+		snprintf(name, sizeof(name), "port%u-poc", index);
+		source->regulator = devm_regulator_get(dev, name);
+		if (IS_ERR(source->regulator)) {
+			ret = PTR_ERR(source->regulator);
+			dev_err_probe(dev, ret,
+				      "Unable to get port %u PoC regulator\n",
+				      index);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static int max9286_probe(struct i2c_client *client)
 {
 	struct max9286_priv *priv;
@@ -1292,17 +1377,13 @@ static int max9286_probe(struct i2c_client *client)
 	if (ret)
 		goto err_powerdown;
 
-	priv->regulator = devm_regulator_get(&client->dev, "poc");
-	if (IS_ERR(priv->regulator)) {
-		ret = PTR_ERR(priv->regulator);
-		dev_err_probe(&client->dev, ret,
-			      "Unable to get PoC regulator\n");
-		goto err_powerdown;
-	}
-
 	ret = max9286_parse_dt(priv);
 	if (ret)
-		goto err_powerdown;
+		goto err_cleanup_dt;
+
+	ret = max9286_get_poc_supplies(priv);
+	if (ret)
+		goto err_cleanup_dt;
 
 	ret = max9286_init(&client->dev);
 	if (ret < 0)
@@ -1326,7 +1407,7 @@ static int max9286_remove(struct i2c_client *client)
 
 	max9286_v4l2_unregister(priv);
 
-	regulator_disable(priv->regulator);
+	max9286_poc_power_off(priv);
 
 	gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
 
-- 
Regards,

Laurent Pinchart


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

* [PATCH v2 05/11] media: i2c: max9286: Support manual framesync operation
  2022-01-01 18:27 [PATCH v2 00/11] media: i2c: max9286: Small new features Laurent Pinchart
                   ` (3 preceding siblings ...)
  2022-01-01 18:27 ` [PATCH v2 04/11] media: i2c: max9286: Add support for port regulators Laurent Pinchart
@ 2022-01-01 18:28 ` Laurent Pinchart
  2022-01-09 10:26   ` Jacopo Mondi
  2022-01-01 18:28 ` [PATCH v2 06/11] media: i2c: max9286: Rename MAX9286_DATATYPE_RAW11 to RAW12 Laurent Pinchart
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-01 18:28 UTC (permalink / raw)
  To: linux-media
  Cc: linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

The MAX9286 can generate a framesync signal to synchronize the cameras,
using an internal timer. Support this mode of operation and configure it
through the .s_frameinterval() operation. If the frame interval is not
0, framesync is switched to manual mode with the specified interval,
otherwise automatic mode is used.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
Changes since v1:

- Use pixel rate to calculate frame sync counter
---
 drivers/media/i2c/max9286.c | 84 +++++++++++++++++++++++++++++++++----
 1 file changed, 75 insertions(+), 9 deletions(-)

diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index 15c80034e3a4..75374034724f 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -170,9 +170,11 @@ struct max9286_priv {
 	u32 rev_chan_mv;
 
 	struct v4l2_ctrl_handler ctrls;
-	struct v4l2_ctrl *pixelrate;
+	struct v4l2_ctrl *pixelrate_ctrl;
+	unsigned int pixelrate;
 
 	struct v4l2_mbus_framefmt fmt[MAX9286_N_SINKS];
+	struct v4l2_fract interval;
 
 	/* Protects controls and fmt structures */
 	struct mutex mutex;
@@ -473,6 +475,40 @@ static int max9286_check_config_link(struct max9286_priv *priv,
 	return 0;
 }
 
+static void max9286_set_fsync_period(struct max9286_priv *priv)
+{
+	u32 fsync;
+
+	if (!priv->interval.numerator || !priv->interval.denominator) {
+		/*
+		 * Special case, a null interval enables automatic FRAMESYNC
+		 * mode. FRAMESYNC is taken from the slowest link.
+		 */
+		max9286_write(priv, 0x01, MAX9286_FSYNCMODE_INT_HIZ |
+			      MAX9286_FSYNCMETH_AUTO);
+		return;
+	}
+
+	/*
+	 * Manual FRAMESYNC
+	 *
+	 * The FRAMESYNC generator is configured with a period expressed as a
+	 * number of PCLK periods.
+	 */
+	fsync = div_u64((u64)priv->pixelrate * priv->interval.numerator,
+			priv->interval.denominator);
+
+	dev_dbg(&priv->client->dev, "fsync period %u (pclk %u)\n", fsync,
+		priv->pixelrate);
+
+	max9286_write(priv, 0x01, MAX9286_FSYNCMODE_INT_OUT |
+		      MAX9286_FSYNCMETH_MANUAL);
+
+	max9286_write(priv, 0x06, (fsync >> 0) & 0xff);
+	max9286_write(priv, 0x07, (fsync >> 8) & 0xff);
+	max9286_write(priv, 0x08, (fsync >> 16) & 0xff);
+}
+
 /* -----------------------------------------------------------------------------
  * V4L2 Subdev
  */
@@ -511,11 +547,13 @@ static int max9286_set_pixelrate(struct max9286_priv *priv)
 		return -EINVAL;
 	}
 
+	priv->pixelrate = pixelrate;
+
 	/*
 	 * The CSI-2 transmitter pixel rate is the single source rate multiplied
 	 * by the number of available sources.
 	 */
-	return v4l2_ctrl_s_ctrl_int64(priv->pixelrate,
+	return v4l2_ctrl_s_ctrl_int64(priv->pixelrate_ctrl,
 				      pixelrate * priv->nsources);
 }
 
@@ -655,6 +693,8 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
 	int ret;
 
 	if (enable) {
+		max9286_set_fsync_period(priv);
+
 		/*
 		 * The frame sync between cameras is transmitted across the
 		 * reverse channel as GPIO. We must open all channels while
@@ -714,6 +754,32 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
 	return 0;
 }
 
+static int max9286_g_frame_interval(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_frame_interval *interval)
+{
+	struct max9286_priv *priv = sd_to_max9286(sd);
+
+	if (interval->pad != MAX9286_SRC_PAD)
+		return -EINVAL;
+
+	interval->interval = priv->interval;
+
+	return 0;
+}
+
+static int max9286_s_frame_interval(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_frame_interval *interval)
+{
+	struct max9286_priv *priv = sd_to_max9286(sd);
+
+	if (interval->pad != MAX9286_SRC_PAD)
+		return -EINVAL;
+
+	priv->interval = interval->interval;
+
+	return 0;
+}
+
 static int max9286_enum_mbus_code(struct v4l2_subdev *sd,
 				  struct v4l2_subdev_state *sd_state,
 				  struct v4l2_subdev_mbus_code_enum *code)
@@ -805,6 +871,8 @@ static int max9286_get_fmt(struct v4l2_subdev *sd,
 
 static const struct v4l2_subdev_video_ops max9286_video_ops = {
 	.s_stream	= max9286_s_stream,
+	.g_frame_interval = max9286_g_frame_interval,
+	.s_frame_interval = max9286_s_frame_interval,
 };
 
 static const struct v4l2_subdev_pad_ops max9286_pad_ops = {
@@ -885,10 +953,10 @@ static int max9286_v4l2_register(struct max9286_priv *priv)
 	priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 
 	v4l2_ctrl_handler_init(&priv->ctrls, 1);
-	priv->pixelrate = v4l2_ctrl_new_std(&priv->ctrls,
-					    &max9286_ctrl_ops,
-					    V4L2_CID_PIXEL_RATE,
-					    1, INT_MAX, 1, 50000000);
+	priv->pixelrate_ctrl = v4l2_ctrl_new_std(&priv->ctrls,
+						 &max9286_ctrl_ops,
+						 V4L2_CID_PIXEL_RATE,
+						 1, INT_MAX, 1, 50000000);
 
 	priv->sd.ctrl_handler = &priv->ctrls;
 	ret = priv->ctrls.error;
@@ -997,9 +1065,7 @@ static int max9286_setup(struct max9286_priv *priv)
 		      MAX9286_CSILANECNT(priv->csi2_data_lanes) |
 		      MAX9286_DATATYPE_YUV422_8BIT);
 
-	/* Automatic: FRAMESYNC taken from the slowest Link. */
-	max9286_write(priv, 0x01, MAX9286_FSYNCMODE_INT_HIZ |
-		      MAX9286_FSYNCMETH_AUTO);
+	max9286_set_fsync_period(priv);
 
 	/* Enable HS/VS encoding, use D14/15 for HS/VS, invert VS. */
 	max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_INVVS |
-- 
Regards,

Laurent Pinchart


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

* [PATCH v2 06/11] media: i2c: max9286: Rename MAX9286_DATATYPE_RAW11 to RAW12
  2022-01-01 18:27 [PATCH v2 00/11] media: i2c: max9286: Small new features Laurent Pinchart
                   ` (4 preceding siblings ...)
  2022-01-01 18:28 ` [PATCH v2 05/11] media: i2c: max9286: Support manual framesync operation Laurent Pinchart
@ 2022-01-01 18:28 ` Laurent Pinchart
  2022-01-09 10:26   ` Jacopo Mondi
  2022-01-01 18:28 ` [PATCH v2 07/11] media: i2c: max9286: Support 12-bit raw bayer formats Laurent Pinchart
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-01 18:28 UTC (permalink / raw)
  To: linux-media
  Cc: linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

The MAX9286_DATATYPE_RAW11 value is used to configure the MAX9286 for
11-bit or 12-bit input data. While 11-bit data is supported on the GMSL
side, CSI-2 doesn't have a RAW11 format. 11-bit data is transferred over
CSI-2 as RAW12. Rename the macro accordingly to avoid confusion.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/i2c/max9286.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index 75374034724f..576d9c6fac14 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -71,7 +71,7 @@
 #define MAX9286_DATATYPE_USER_YUV_12BIT	(10 << 0)
 #define MAX9286_DATATYPE_USER_24BIT	(9 << 0)
 #define MAX9286_DATATYPE_RAW14		(8 << 0)
-#define MAX9286_DATATYPE_RAW11		(7 << 0)
+#define MAX9286_DATATYPE_RAW12		(7 << 0)
 #define MAX9286_DATATYPE_RAW10		(6 << 0)
 #define MAX9286_DATATYPE_RAW8		(5 << 0)
 #define MAX9286_DATATYPE_YUV422_10BIT	(4 << 0)
-- 
Regards,

Laurent Pinchart


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

* [PATCH v2 07/11] media: i2c: max9286: Support 12-bit raw bayer formats
  2022-01-01 18:27 [PATCH v2 00/11] media: i2c: max9286: Small new features Laurent Pinchart
                   ` (5 preceding siblings ...)
  2022-01-01 18:28 ` [PATCH v2 06/11] media: i2c: max9286: Rename MAX9286_DATATYPE_RAW11 to RAW12 Laurent Pinchart
@ 2022-01-01 18:28 ` Laurent Pinchart
  2022-01-09 10:34   ` Jacopo Mondi
  2022-01-01 18:28 ` [PATCH v2 08/11] media: i2c: max9286: Define macros for all bits of register 0x15 Laurent Pinchart
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-01 18:28 UTC (permalink / raw)
  To: linux-media
  Cc: linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Add support for 12-bit raw bayer formats to the driver, configuring the
GMSL format accordingly.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/i2c/max9286.c | 128 ++++++++++++++++++++++++++----------
 1 file changed, 95 insertions(+), 33 deletions(-)

diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index 576d9c6fac14..24c2bf4fda53 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -135,6 +135,11 @@
 #define MAX9286_N_PADS			5
 #define MAX9286_SRC_PAD			4
 
+struct max9286_format_info {
+	u32 code;
+	u8 datatype;
+};
+
 struct max9286_source {
 	struct v4l2_subdev *sd;
 	struct fwnode_handle *fwnode;
@@ -214,6 +219,34 @@ static inline struct max9286_priv *sd_to_max9286(struct v4l2_subdev *sd)
 	return container_of(sd, struct max9286_priv, sd);
 }
 
+static const struct max9286_format_info max9286_formats[] = {
+	{
+		.code = MEDIA_BUS_FMT_UYVY8_1X16,
+		.datatype = MAX9286_DATATYPE_YUV422_8BIT,
+	}, {
+		.code = MEDIA_BUS_FMT_VYUY8_1X16,
+		.datatype = MAX9286_DATATYPE_YUV422_8BIT,
+	}, {
+		.code = MEDIA_BUS_FMT_YUYV8_1X16,
+		.datatype = MAX9286_DATATYPE_YUV422_8BIT,
+	}, {
+		.code = MEDIA_BUS_FMT_YVYU8_1X16,
+		.datatype = MAX9286_DATATYPE_YUV422_8BIT,
+	}, {
+		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
+		.datatype = MAX9286_DATATYPE_RAW12,
+	}, {
+		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.datatype = MAX9286_DATATYPE_RAW12,
+	}, {
+		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
+		.datatype = MAX9286_DATATYPE_RAW12,
+	}, {
+		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
+		.datatype = MAX9286_DATATYPE_RAW12,
+	},
+};
+
 /* -----------------------------------------------------------------------------
  * I2C IO
  */
@@ -475,6 +508,38 @@ static int max9286_check_config_link(struct max9286_priv *priv,
 	return 0;
 }
 
+static void max9286_set_video_format(struct max9286_priv *priv,
+				     const struct v4l2_mbus_framefmt *format)
+{
+	const struct max9286_format_info *info = NULL;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(max9286_formats); ++i) {
+		if (max9286_formats[i].code == format->code) {
+			info = &max9286_formats[i];
+			break;
+		}
+	}
+
+	if (WARN_ON(!info))
+		return;
+
+	/*
+	 * Video format setup:
+	 * Disable CSI output, VC is set according to Link number.
+	 */
+	max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
+
+	/* Enable CSI-2 Lane D0-D3 only, DBL mode. */
+	max9286_write(priv, 0x12, MAX9286_CSIDBL | MAX9286_DBL |
+		      MAX9286_CSILANECNT(priv->csi2_data_lanes) |
+		      info->datatype);
+
+	/* Enable HS/VS encoding, use D14/15 for HS/VS, invert VS. */
+	max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_INVVS |
+		      MAX9286_HVSRC_D14);
+}
+
 static void max9286_set_fsync_period(struct max9286_priv *priv)
 {
 	u32 fsync;
@@ -693,6 +758,15 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
 	int ret;
 
 	if (enable) {
+		const struct v4l2_mbus_framefmt *format;
+
+		/*
+		 * Get the format from the first used sink pad, as all sink
+		 * formats must be identical.
+		 */
+		format = &priv->fmt[__ffs(priv->bound_sources)];
+
+		max9286_set_video_format(priv, format);
 		max9286_set_fsync_period(priv);
 
 		/*
@@ -813,22 +887,20 @@ static int max9286_set_fmt(struct v4l2_subdev *sd,
 {
 	struct max9286_priv *priv = sd_to_max9286(sd);
 	struct v4l2_mbus_framefmt *cfg_fmt;
+	unsigned int i;
 
 	if (format->pad == MAX9286_SRC_PAD)
 		return -EINVAL;
 
-	/* Refuse non YUV422 formats as we hardcode DT to 8 bit YUV422 */
-	switch (format->format.code) {
-	case MEDIA_BUS_FMT_UYVY8_1X16:
-	case MEDIA_BUS_FMT_VYUY8_1X16:
-	case MEDIA_BUS_FMT_YUYV8_1X16:
-	case MEDIA_BUS_FMT_YVYU8_1X16:
-		break;
-	default:
-		format->format.code = MEDIA_BUS_FMT_UYVY8_1X16;
-		break;
+	/* Validate the format. */
+	for (i = 0; i < ARRAY_SIZE(max9286_formats); ++i) {
+		if (max9286_formats[i].code == format->format.code)
+			break;
 	}
 
+	if (i == ARRAY_SIZE(max9286_formats))
+		format->format.code = max9286_formats[i].code;
+
 	cfg_fmt = max9286_get_pad_format(priv, sd_state, format->pad,
 					 format->which);
 	if (!cfg_fmt)
@@ -886,16 +958,20 @@ static const struct v4l2_subdev_ops max9286_subdev_ops = {
 	.pad		= &max9286_pad_ops,
 };
 
+static const struct v4l2_mbus_framefmt max9286_default_format = {
+	.width		= 1280,
+	.height		= 800,
+	.code		= MEDIA_BUS_FMT_UYVY8_1X16,
+	.colorspace	= V4L2_COLORSPACE_SRGB,
+	.field		= V4L2_FIELD_NONE,
+	.ycbcr_enc	= V4L2_YCBCR_ENC_DEFAULT,
+	.quantization	= V4L2_QUANTIZATION_DEFAULT,
+	.xfer_func	= V4L2_XFER_FUNC_DEFAULT,
+};
+
 static void max9286_init_format(struct v4l2_mbus_framefmt *fmt)
 {
-	fmt->width		= 1280;
-	fmt->height		= 800;
-	fmt->code		= MEDIA_BUS_FMT_UYVY8_1X16;
-	fmt->colorspace		= V4L2_COLORSPACE_SRGB;
-	fmt->field		= V4L2_FIELD_NONE;
-	fmt->ycbcr_enc		= V4L2_YCBCR_ENC_DEFAULT;
-	fmt->quantization	= V4L2_QUANTIZATION_DEFAULT;
-	fmt->xfer_func		= V4L2_XFER_FUNC_DEFAULT;
+	*fmt = max9286_default_format;
 }
 
 static int max9286_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
@@ -1054,23 +1130,9 @@ static int max9286_setup(struct max9286_priv *priv)
 	max9286_write(priv, 0x0b, link_order[priv->route_mask]);
 	max9286_write(priv, 0x69, (0xf & ~priv->route_mask));
 
-	/*
-	 * Video format setup:
-	 * Disable CSI output, VC is set according to Link number.
-	 */
-	max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
-
-	/* Enable CSI-2 Lane D0-D3 only, DBL mode, YUV422 8-bit. */
-	max9286_write(priv, 0x12, MAX9286_CSIDBL | MAX9286_DBL |
-		      MAX9286_CSILANECNT(priv->csi2_data_lanes) |
-		      MAX9286_DATATYPE_YUV422_8BIT);
-
+	max9286_set_video_format(priv, &max9286_default_format);
 	max9286_set_fsync_period(priv);
 
-	/* Enable HS/VS encoding, use D14/15 for HS/VS, invert VS. */
-	max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_INVVS |
-		      MAX9286_HVSRC_D14);
-
 	/*
 	 * The overlap window seems to provide additional validation by tracking
 	 * the delay between vsync and frame sync, generating an error if the
-- 
Regards,

Laurent Pinchart


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

* [PATCH v2 08/11] media: i2c: max9286: Define macros for all bits of register 0x15
  2022-01-01 18:27 [PATCH v2 00/11] media: i2c: max9286: Small new features Laurent Pinchart
                   ` (6 preceding siblings ...)
  2022-01-01 18:28 ` [PATCH v2 07/11] media: i2c: max9286: Support 12-bit raw bayer formats Laurent Pinchart
@ 2022-01-01 18:28 ` Laurent Pinchart
  2022-01-09 10:37   ` Jacopo Mondi
  2022-01-01 18:28 ` [PATCH v2 09/11] media: i2c: max9286: Configure remote I2C speed from device tree Laurent Pinchart
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-01 18:28 UTC (permalink / raw)
  To: linux-media
  Cc: linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Macros are easier to read than numerical values.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/i2c/max9286.c | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index 24c2bf4fda53..4b69bd036ca6 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -80,10 +80,13 @@
 #define MAX9286_DATATYPE_RGB565		(1 << 0)
 #define MAX9286_DATATYPE_RGB888		(0 << 0)
 /* Register 0x15 */
+#define MAX9286_CSI_IMAGE_TYP		BIT(7)
 #define MAX9286_VC(n)			((n) << 5)
 #define MAX9286_VCTYPE			BIT(4)
 #define MAX9286_CSIOUTEN		BIT(3)
-#define MAX9286_0X15_RESV		(3 << 0)
+#define MAX9286_SWP_ENDIAN		BIT(2)
+#define MAX9286_EN_CCBSYB_CLK_STR	BIT(1)
+#define MAX9286_EN_GPI_CCBSYB		BIT(0)
 /* Register 0x1b */
 #define MAX9286_SWITCHIN(n)		(1 << ((n) + 4))
 #define MAX9286_ENEQ(n)			(1 << (n))
@@ -525,10 +528,12 @@ static void max9286_set_video_format(struct max9286_priv *priv,
 		return;
 
 	/*
-	 * Video format setup:
-	 * Disable CSI output, VC is set according to Link number.
+	 * Video format setup: disable CSI output, set VC according to Link
+	 * number, enable I2C clock stretching when CCBSY is low, enable CCBSY
+	 * in external GPI-to-GPO mode.
 	 */
-	max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
+	max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_EN_CCBSYB_CLK_STR |
+		      MAX9286_EN_GPI_CCBSYB);
 
 	/* Enable CSI-2 Lane D0-D3 only, DBL mode. */
 	max9286_write(priv, 0x12, MAX9286_CSIDBL | MAX9286_DBL |
@@ -810,13 +815,17 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
 		}
 
 		/*
-		 * Enable CSI output, VC set according to link number.
-		 * Bit 7 must be set (chip manual says it's 0 and reserved).
+		 * Configure the CSI-2 output to line interleaved mode (W x (N
+		 * x H), as opposed to the (N x W) x H mode that outputs the
+		 * images stitched side-by-side) and enable it.
 		 */
-		max9286_write(priv, 0x15, 0x80 | MAX9286_VCTYPE |
-			      MAX9286_CSIOUTEN | MAX9286_0X15_RESV);
+		max9286_write(priv, 0x15, MAX9286_CSI_IMAGE_TYP | MAX9286_VCTYPE |
+			      MAX9286_CSIOUTEN | MAX9286_EN_CCBSYB_CLK_STR |
+			      MAX9286_EN_GPI_CCBSYB);
 	} else {
-		max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
+		max9286_write(priv, 0x15, MAX9286_VCTYPE |
+			      MAX9286_EN_CCBSYB_CLK_STR |
+			      MAX9286_EN_GPI_CCBSYB);
 
 		/* Stop all cameras. */
 		for_each_source(priv, source)
-- 
Regards,

Laurent Pinchart


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

* [PATCH v2 09/11] media: i2c: max9286: Configure remote I2C speed from device tree
  2022-01-01 18:27 [PATCH v2 00/11] media: i2c: max9286: Small new features Laurent Pinchart
                   ` (7 preceding siblings ...)
  2022-01-01 18:28 ` [PATCH v2 08/11] media: i2c: max9286: Define macros for all bits of register 0x15 Laurent Pinchart
@ 2022-01-01 18:28 ` Laurent Pinchart
  2022-01-09 10:43   ` Jacopo Mondi
  2022-01-01 18:28 ` [PATCH v2 10/11] media: i2c: max9286: Configure bus width " Laurent Pinchart
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-01 18:28 UTC (permalink / raw)
  To: linux-media
  Cc: linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Read the maxim,i2c-clock-frequency DT property that specifies the speed
of the remote I2C bus, and configure the MAX9286 accordingly. The remote
serializers must all have a matching configuration.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/i2c/max9286.c | 56 +++++++++++++++++++++++++++++++------
 1 file changed, 47 insertions(+), 9 deletions(-)

diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index 4b69bd036ca6..d88a4d8e63ab 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -143,6 +143,11 @@ struct max9286_format_info {
 	u8 datatype;
 };
 
+struct max9286_i2c_speed {
+	u32 rate;
+	u8 mstbt;
+};
+
 struct max9286_source {
 	struct v4l2_subdev *sd;
 	struct fwnode_handle *fwnode;
@@ -176,6 +181,7 @@ struct max9286_priv {
 	/* The initial reverse control channel amplitude. */
 	u32 init_rev_chan_mv;
 	u32 rev_chan_mv;
+	u8 i2c_mstbt;
 
 	struct v4l2_ctrl_handler ctrls;
 	struct v4l2_ctrl *pixelrate_ctrl;
@@ -250,6 +256,17 @@ static const struct max9286_format_info max9286_formats[] = {
 	},
 };
 
+static const struct max9286_i2c_speed max9286_i2c_speeds[] = {
+	{ .rate =   8470, .mstbt = MAX9286_I2CMSTBT_8KBPS },
+	{ .rate =  28300, .mstbt = MAX9286_I2CMSTBT_28KBPS },
+	{ .rate =  84700, .mstbt = MAX9286_I2CMSTBT_84KBPS },
+	{ .rate = 105000, .mstbt = MAX9286_I2CMSTBT_105KBPS },
+	{ .rate = 173000, .mstbt = MAX9286_I2CMSTBT_173KBPS },
+	{ .rate = 339000, .mstbt = MAX9286_I2CMSTBT_339KBPS },
+	{ .rate = 533000, .mstbt = MAX9286_I2CMSTBT_533KBPS },
+	{ .rate = 837000, .mstbt = MAX9286_I2CMSTBT_837KBPS },
+};
+
 /* -----------------------------------------------------------------------------
  * I2C IO
  */
@@ -370,7 +387,7 @@ static int max9286_i2c_mux_init(struct max9286_priv *priv)
 static void max9286_configure_i2c(struct max9286_priv *priv, bool localack)
 {
 	u8 config = MAX9286_I2CSLVSH_469NS_234NS | MAX9286_I2CSLVTO_1024US |
-		    MAX9286_I2CMSTBT_105KBPS;
+		    priv->i2c_mstbt;
 
 	if (localack)
 		config |= MAX9286_I2CLOCACK;
@@ -1320,6 +1337,8 @@ static int max9286_parse_dt(struct max9286_priv *priv)
 	struct device_node *node = NULL;
 	unsigned int i2c_mux_mask = 0;
 	u32 reverse_channel_microvolt;
+	u32 i2c_clk_freq = 105000;
+	unsigned int i;
 
 	/* Balance the of_node_put() performed by of_find_node_by_name(). */
 	of_node_get(dev->of_node);
@@ -1410,6 +1429,23 @@ static int max9286_parse_dt(struct max9286_priv *priv)
 	}
 	of_node_put(node);
 
+	of_property_read_u32(dev->of_node, "maxim,i2c-clock-frequency",
+			     &i2c_clk_freq);
+	for (i = 0; i < ARRAY_SIZE(max9286_i2c_speeds); ++i) {
+		const struct max9286_i2c_speed *speed = &max9286_i2c_speeds[i];
+
+		if (speed->rate == i2c_clk_freq) {
+			priv->i2c_mstbt = speed->mstbt;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(max9286_i2c_speeds)) {
+		dev_err(dev, "Invalid %s value %u\n",
+			"maxim,i2c-clock-frequency", i2c_clk_freq);
+		return -EINVAL;
+	}
+
 	/*
 	 * Parse the initial value of the reverse channel amplitude from
 	 * the firmware interface and convert it to millivolts.
@@ -1484,10 +1520,16 @@ static int max9286_probe(struct i2c_client *client)
 	priv->client = client;
 	i2c_set_clientdata(client, priv);
 
+	ret = max9286_parse_dt(priv);
+	if (ret)
+		goto err_cleanup_dt;
+
 	priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable",
 						   GPIOD_OUT_HIGH);
-	if (IS_ERR(priv->gpiod_pwdn))
-		return PTR_ERR(priv->gpiod_pwdn);
+	if (IS_ERR(priv->gpiod_pwdn)) {
+		ret = PTR_ERR(priv->gpiod_pwdn);
+		goto err_cleanup_dt;
+	}
 
 	gpiod_set_consumer_name(priv->gpiod_pwdn, "max9286-pwdn");
 	gpiod_set_value_cansleep(priv->gpiod_pwdn, 1);
@@ -1514,10 +1556,6 @@ static int max9286_probe(struct i2c_client *client)
 	if (ret)
 		goto err_powerdown;
 
-	ret = max9286_parse_dt(priv);
-	if (ret)
-		goto err_cleanup_dt;
-
 	ret = max9286_get_poc_supplies(priv);
 	if (ret)
 		goto err_cleanup_dt;
@@ -1528,10 +1566,10 @@ static int max9286_probe(struct i2c_client *client)
 
 	return 0;
 
-err_cleanup_dt:
-	max9286_cleanup_dt(priv);
 err_powerdown:
 	gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
+err_cleanup_dt:
+	max9286_cleanup_dt(priv);
 
 	return ret;
 }
-- 
Regards,

Laurent Pinchart


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

* [PATCH v2 10/11] media: i2c: max9286: Configure bus width from device tree
  2022-01-01 18:27 [PATCH v2 00/11] media: i2c: max9286: Small new features Laurent Pinchart
                   ` (8 preceding siblings ...)
  2022-01-01 18:28 ` [PATCH v2 09/11] media: i2c: max9286: Configure remote I2C speed from device tree Laurent Pinchart
@ 2022-01-01 18:28 ` Laurent Pinchart
  2022-01-09 10:56   ` Jacopo Mondi
  2022-01-01 18:28 ` [PATCH v2 11/11] media: i2c: max9286: Select HS as data enable signal Laurent Pinchart
  2022-01-01 23:26 ` [PATCH v2 12/11] media: i2c: max9286: Print power-up GMSL link configuration Laurent Pinchart
  11 siblings, 1 reply; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-01 18:28 UTC (permalink / raw)
  To: linux-media
  Cc: linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

The GMSL serial data bus width is normally selected through the BWS pin.
On some systems, the pin may not be wired to the correct value. Support
overriding the bus width by software, using the value specified in the
device tree.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/i2c/max9286.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index d88a4d8e63ab..07ebb01640a1 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -90,6 +90,11 @@
 /* Register 0x1b */
 #define MAX9286_SWITCHIN(n)		(1 << ((n) + 4))
 #define MAX9286_ENEQ(n)			(1 << (n))
+/* Register 0x1c */
+#define MAX9286_HIGHIMM(n)		BIT((n) + 4)
+#define MAX9286_I2CSEL			BIT(2)
+#define MAX9286_HIBW			BIT(1)
+#define MAX9286_BWS			BIT(0)
 /* Register 0x27 */
 #define MAX9286_LOCKED			BIT(7)
 /* Register 0x31 */
@@ -182,6 +187,7 @@ struct max9286_priv {
 	u32 init_rev_chan_mv;
 	u32 rev_chan_mv;
 	u8 i2c_mstbt;
+	u32 bus_width;
 
 	struct v4l2_ctrl_handler ctrls;
 	struct v4l2_ctrl *pixelrate_ctrl;
@@ -1159,6 +1165,23 @@ static int max9286_setup(struct max9286_priv *priv)
 	max9286_set_video_format(priv, &max9286_default_format);
 	max9286_set_fsync_period(priv);
 
+	if (priv->bus_width) {
+		int val;
+
+		val = max9286_read(priv, 0x1c);
+		if (val < 0)
+			return val;
+
+		val &= ~(MAX9286_HIBW | MAX9286_BWS);
+
+		if (priv->bus_width == 27)
+			val |= MAX9286_HIBW;
+		else if (priv->bus_width == 32)
+			val |= MAX9286_BWS;
+
+		max9286_write(priv, 0x1c, val);
+	}
+
 	/*
 	 * The overlap window seems to provide additional validation by tracking
 	 * the delay between vsync and frame sync, generating an error if the
@@ -1429,6 +1452,19 @@ static int max9286_parse_dt(struct max9286_priv *priv)
 	}
 	of_node_put(node);
 
+	of_property_read_u32(dev->of_node, "maxim,bus-width", &priv->bus_width);
+	switch (priv->bus_width) {
+	case 0:
+	case 24:
+	case 27:
+	case 32:
+		break;
+	default:
+		dev_err(dev, "Invalid %s value %u\n", "maxim,bus-width",
+			priv->bus_width);
+		return -EINVAL;
+	}
+
 	of_property_read_u32(dev->of_node, "maxim,i2c-clock-frequency",
 			     &i2c_clk_freq);
 	for (i = 0; i < ARRAY_SIZE(max9286_i2c_speeds); ++i) {
-- 
Regards,

Laurent Pinchart


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

* [PATCH v2 11/11] media: i2c: max9286: Select HS as data enable signal
  2022-01-01 18:27 [PATCH v2 00/11] media: i2c: max9286: Small new features Laurent Pinchart
                   ` (9 preceding siblings ...)
  2022-01-01 18:28 ` [PATCH v2 10/11] media: i2c: max9286: Configure bus width " Laurent Pinchart
@ 2022-01-01 18:28 ` Laurent Pinchart
  2022-01-09 11:42   ` Jacopo Mondi
  2022-01-01 23:26 ` [PATCH v2 12/11] media: i2c: max9286: Print power-up GMSL link configuration Laurent Pinchart
  11 siblings, 1 reply; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-01 18:28 UTC (permalink / raw)
  To: linux-media
  Cc: linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

GMSL can transport three synchronization signals: VSync, HSync and Data
Enable. The MAX9286 can select either HS or DE as a line valid signal.

Not all serializers (and transmission formats) support the DE signal.
The MAX9271, used by the RDACM20 and RDACM21 cameras, doesn't document
DE support. Nonetheless, the max9286 driver selects the DE signal as
line valid in register 0x0c (by not setting the DESEL bit). It's not
clear why this works. As HS is a more common line valid qualifier, set
the DESEL bit by default. This is needed to support the onsemi MARS
cameras.

If a camera requires usage of the DE signal in the future, this will
need to be made configurable.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/i2c/max9286.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index 07ebb01640a1..446fc238d642 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -563,9 +563,12 @@ static void max9286_set_video_format(struct max9286_priv *priv,
 		      MAX9286_CSILANECNT(priv->csi2_data_lanes) |
 		      info->datatype);
 
-	/* Enable HS/VS encoding, use D14/15 for HS/VS, invert VS. */
-	max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_INVVS |
-		      MAX9286_HVSRC_D14);
+	/*
+	 * Enable HS/VS encoding, use HS as line valid source, use D14/15 for
+	 * HS/VS, invert VS.
+	 */
+	max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_DESEL |
+		      MAX9286_INVVS | MAX9286_HVSRC_D14);
 }
 
 static void max9286_set_fsync_period(struct max9286_priv *priv)
-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH v2 02/11] dt-bindings: media: i2c: max9286: Add property to select I2C speed
  2022-01-01 18:27 ` [PATCH v2 02/11] dt-bindings: media: i2c: max9286: Add property to select I2C speed Laurent Pinchart
@ 2022-01-01 22:01   ` Rob Herring
  2022-01-04 15:56   ` Rob Herring
  1 sibling, 0 replies; 37+ messages in thread
From: Rob Herring @ 2022-01-01 22:01 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: devicetree, Thomas Nizan, Kieran Bingham, linux-renesas-soc,
	Rob Herring, Niklas Söderlund, Jacopo Mondi, linux-media

On Sat, 01 Jan 2022 20:27:57 +0200, Laurent Pinchart wrote:
> The I2C speed on the remote side (the I2C master bus of the connected
> serializers) is configurable, and doesn't need to match the speed of the
> local bus (the slave bus of the MAX9286). All remote buses must use the
> same speed, and the MAX9286 needs to be programmed accordingly. Add a
> new DT property to select the speed to make it configurable.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  .../devicetree/bindings/media/i2c/maxim,max9286.yaml       | 7 +++++++
>  1 file changed, 7 insertions(+)
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml: properties:maxim,i2c-clock-frequency: 'oneOf' conditional failed, one must be fixed:
	'type' is a required property
		hint: A vendor boolean property can use "type: boolean"
	Additional properties are not allowed ('enum', 'default' were unexpected)
		hint: A vendor boolean property can use "type: boolean"
	Additional properties are not allowed ('default' was unexpected)
		hint: A vendor string property with exact values has an implicit type
	/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml: properties:maxim,i2c-clock-frequency: 'oneOf' conditional failed, one must be fixed:
		'$ref' is a required property
		'allOf' is a required property
		hint: A vendor property needs a $ref to types.yaml
		from schema $id: http://devicetree.org/meta-schemas/vendor-props.yaml#
	8470 is not of type 'string'
		hint: A vendor string property with exact values has an implicit type
	28300 is not of type 'string'
		hint: A vendor string property with exact values has an implicit type
	84700 is not of type 'string'
		hint: A vendor string property with exact values has an implicit type
	105000 is not of type 'string'
		hint: A vendor string property with exact values has an implicit type
	173000 is not of type 'string'
		hint: A vendor string property with exact values has an implicit type
	339000 is not of type 'string'
		hint: A vendor string property with exact values has an implicit type
	533000 is not of type 'string'
		hint: A vendor string property with exact values has an implicit type
	837000 is not of type 'string'
		hint: A vendor string property with exact values has an implicit type
	hint: Vendor specific properties must have a type and description unless they have a defined, common suffix.
	from schema $id: http://devicetree.org/meta-schemas/vendor-props.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml: ignoring, error in schema: properties: maxim,i2c-clock-frequency
Documentation/devicetree/bindings/media/i2c/maxim,max9286.example.dt.yaml:0:0: /example-0/i2c@e66d8000/gmsl-deserializer@2c: failed to match any schema with compatible: ['maxim,max9286']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1574505

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.


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

* [PATCH v2 12/11] media: i2c: max9286: Print power-up GMSL link configuration
  2022-01-01 18:27 [PATCH v2 00/11] media: i2c: max9286: Small new features Laurent Pinchart
                   ` (10 preceding siblings ...)
  2022-01-01 18:28 ` [PATCH v2 11/11] media: i2c: max9286: Select HS as data enable signal Laurent Pinchart
@ 2022-01-01 23:26 ` Laurent Pinchart
  2022-01-09 11:44   ` Jacopo Mondi
  11 siblings, 1 reply; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-01 23:26 UTC (permalink / raw)
  To: linux-media
  Cc: linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

The power-up GMSL link configuration is controlled by the HIM and BWS
pins, whose state is reflected in register 0x1c. Print the detected
power-up config in a debug message to help debugging.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 drivers/media/i2c/max9286.c | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index 446fc238d642..f7cbfdde436e 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -1147,6 +1147,7 @@ static int max9286_setup(struct max9286_priv *priv)
 		(2 << 6) | (1 << 4) | (0 << 2) | (3 << 0), /* 210x */
 		(3 << 6) | (2 << 4) | (1 << 2) | (0 << 0), /* 3210 */
 	};
+	int cfg;
 
 	/*
 	 * Set the I2C bus speed.
@@ -1168,21 +1169,23 @@ static int max9286_setup(struct max9286_priv *priv)
 	max9286_set_video_format(priv, &max9286_default_format);
 	max9286_set_fsync_period(priv);
 
+	cfg = max9286_read(priv, 0x1c);
+	if (cfg < 0)
+		return cfg;
+
+	dev_dbg(&priv->client->dev, "power-up config: %s immunity, %u-bit bus\n",
+		cfg & MAX9286_HIGHIMM(0) ? "high" : "legacy",
+		cfg & MAX9286_BWS ? 32 : cfg & MAX9286_HIBW ? 27 : 24);
+
 	if (priv->bus_width) {
-		int val;
-
-		val = max9286_read(priv, 0x1c);
-		if (val < 0)
-			return val;
-
-		val &= ~(MAX9286_HIBW | MAX9286_BWS);
+		cfg &= ~(MAX9286_HIBW | MAX9286_BWS);
 
 		if (priv->bus_width == 27)
-			val |= MAX9286_HIBW;
+			cfg |= MAX9286_HIBW;
 		else if (priv->bus_width == 32)
-			val |= MAX9286_BWS;
+			cfg |= MAX9286_BWS;
 
-		max9286_write(priv, 0x1c, val);
+		max9286_write(priv, 0x1c, cfg);
 	}
 
 	/*
-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH v2 02/11] dt-bindings: media: i2c: max9286: Add property to select I2C speed
  2022-01-01 18:27 ` [PATCH v2 02/11] dt-bindings: media: i2c: max9286: Add property to select I2C speed Laurent Pinchart
  2022-01-01 22:01   ` Rob Herring
@ 2022-01-04 15:56   ` Rob Herring
  1 sibling, 0 replies; 37+ messages in thread
From: Rob Herring @ 2022-01-04 15:56 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan, devicetree

On Sat, Jan 01, 2022 at 08:27:57PM +0200, Laurent Pinchart wrote:
> The I2C speed on the remote side (the I2C master bus of the connected
> serializers) is configurable, and doesn't need to match the speed of the
> local bus (the slave bus of the MAX9286). All remote buses must use the
> same speed, and the MAX9286 needs to be programmed accordingly. Add a
> new DT property to select the speed to make it configurable.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  .../devicetree/bindings/media/i2c/maxim,max9286.yaml       | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> index c20557b52e45..5d3e99027a79 100644
> --- a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> @@ -50,6 +50,13 @@ properties:
>    '#gpio-cells':
>      const: 2
>  
> +  maxim,i2c-clock-frequency:

Use '-hz'. I don't see much reason to align with 'clock-frequency'.

Actually, I'd make this 'maxim,i2c-remote-bus-hz' or similar to be a bit 
more self-describing.

> +    enum: [ 8470, 28300, 84700, 105000, 173000, 339000, 533000, 837000 ]
> +    default: 105000
> +    description: |
> +      The I2C clock frequency for the remote I2C buses. The value must match
> +      the configuration of the remote serializers.
> +
>    maxim,reverse-channel-microvolt:
>      minimum: 30000
>      maximum: 200000
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> 

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

* Re: [PATCH v2 04/11] media: i2c: max9286: Add support for port regulators
  2022-01-01 18:27 ` [PATCH v2 04/11] media: i2c: max9286: Add support for port regulators Laurent Pinchart
@ 2022-01-09 10:04   ` Jacopo Mondi
  2022-01-09 23:16     ` Laurent Pinchart
  0 siblings, 1 reply; 37+ messages in thread
From: Jacopo Mondi @ 2022-01-09 10:04 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan, Mark Brown, Liam Girdwood

Hi Laurent,

On Sat, Jan 01, 2022 at 08:27:59PM +0200, Laurent Pinchart wrote:
> From: Thomas Nizan <tnizan@witekio.com>
>
> Allow users to use one PoC regulator per port, instead of a global
> regulator.
>
> The properties '^port[0-3]-poc-supply$' in the DT node are used to
> indicate the regulators for individual ports.
>
> Signed-off-by: Thomas Nizan <tnizan@witekio.com>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

The patch looks almost good, but it will really conflict with gpio-poc work I
have on the list. Should we decide an ordering and send a single
series with both efforts in to ease collecting it ?

> ---
> Changes since v1:
>
> - Use to_index()
> - Use dev_err_probe()
> - Fix error path in probe()
> - Use devm_regulator_get_optional() instead of
>   devm_regulator_get_exclusive()
> ---
>  drivers/media/i2c/max9286.c | 107 +++++++++++++++++++++++++++++++-----
>  1 file changed, 94 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> index eb2b8e42335b..15c80034e3a4 100644
> --- a/drivers/media/i2c/max9286.c
> +++ b/drivers/media/i2c/max9286.c
> @@ -138,6 +138,7 @@
>  struct max9286_source {
>  	struct v4l2_subdev *sd;
>  	struct fwnode_handle *fwnode;
> +	struct regulator *regulator;
>  };
>
>  struct max9286_asd {
> @@ -1071,6 +1072,49 @@ static int max9286_register_gpio(struct max9286_priv *priv)
>  	return ret;
>  }
>
> +static int max9286_poc_power_on(struct max9286_priv *priv)
> +{
> +	struct max9286_source *source;
> +	unsigned int enabled = 0;
> +	int ret;
> +
> +	/* Enable the global regulator if available. */
> +	if (priv->regulator)
> +		return regulator_enable(priv->regulator);
> +
> +	/* Otherwise use the per-port regulators. */
> +	for_each_source(priv, source) {
> +		ret = regulator_enable(source->regulator);
> +		if (ret < 0)
> +			goto error;
> +
> +		enabled |= BIT(to_index(priv, source));
> +	}
> +
> +	return 0;
> +
> +error:
> +	for_each_source(priv, source) {
> +		if (enabled & BIT(to_index(priv, source)))
> +			regulator_disable(source->regulator);
> +	}
> +
> +	return ret;
> +}
> +
> +static void max9286_poc_power_off(struct max9286_priv *priv)
> +{
> +	struct max9286_source *source;
> +
> +	if (priv->regulator) {
> +		regulator_disable(priv->regulator);
> +		return;
> +	}
> +
> +	for_each_source(priv, source)
> +		regulator_disable(source->regulator);
> +}
> +
>  static int max9286_init(struct device *dev)
>  {
>  	struct max9286_priv *priv;
> @@ -1081,9 +1125,9 @@ static int max9286_init(struct device *dev)
>  	priv = i2c_get_clientdata(client);
>
>  	/* Enable the bus power. */
> -	ret = regulator_enable(priv->regulator);
> +	ret = max9286_poc_power_on(priv);
>  	if (ret < 0) {
> -		dev_err(&client->dev, "Unable to turn PoC on\n");
> +		dev_err(dev, "Unable to turn PoC on\n");
>  		return ret;
>  	}
>
> @@ -1117,7 +1161,7 @@ static int max9286_init(struct device *dev)
>  err_v4l2_register:
>  	max9286_v4l2_unregister(priv);
>  err_regulator:
> -	regulator_disable(priv->regulator);
> +	max9286_poc_power_off(priv);
>
>  	return ret;
>  }
> @@ -1248,6 +1292,47 @@ static int max9286_parse_dt(struct max9286_priv *priv)
>  	return 0;
>  }
>
> +static int max9286_get_poc_supplies(struct max9286_priv *priv)
> +{
> +	struct device *dev = &priv->client->dev;
> +	struct max9286_source *source;
> +	int ret;
> +
> +	/* Start by getting the global regulator. */
> +	priv->regulator = devm_regulator_get_optional(dev, "poc");
> +	if (!IS_ERR(priv->regulator))
> +		return 0;
> +
> +	if (PTR_ERR(priv->regulator) != -ENODEV) {
> +		if (PTR_ERR(priv->regulator) != -EPROBE_DEFER)
> +			dev_err(dev, "Unable to get PoC regulator: %ld\n",
> +				PTR_ERR(priv->regulator));
> +		return PTR_ERR(priv->regulator);
> +	}
> +
> +	/* If there's no global regulator, get per-port regulators. */
> +	dev_dbg(dev,
> +		"No global PoC regulator, looking for per-port regulators\n");
> +	priv->regulator = NULL;
> +
> +	for_each_source(priv, source) {
> +		unsigned int index = to_index(priv, source);
> +		char name[10];
> +
> +		snprintf(name, sizeof(name), "port%u-poc", index);
> +		source->regulator = devm_regulator_get(dev, name);

Are you ok with a dummy being returned ?

> +		if (IS_ERR(source->regulator)) {
> +			ret = PTR_ERR(source->regulator);
> +			dev_err_probe(dev, ret,
> +				      "Unable to get port %u PoC regulator\n",
> +				      index);
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  static int max9286_probe(struct i2c_client *client)
>  {
>  	struct max9286_priv *priv;
> @@ -1292,17 +1377,13 @@ static int max9286_probe(struct i2c_client *client)
>  	if (ret)
>  		goto err_powerdown;
>
> -	priv->regulator = devm_regulator_get(&client->dev, "poc");
> -	if (IS_ERR(priv->regulator)) {
> -		ret = PTR_ERR(priv->regulator);
> -		dev_err_probe(&client->dev, ret,
> -			      "Unable to get PoC regulator\n");
> -		goto err_powerdown;
> -	}
> -
>  	ret = max9286_parse_dt(priv);
>  	if (ret)
> -		goto err_powerdown;
> +		goto err_cleanup_dt;

Shouldn't this be still err_powerdown ?

> +
> +	ret = max9286_get_poc_supplies(priv);
> +	if (ret)
> +		goto err_cleanup_dt;
>
>  	ret = max9286_init(&client->dev);
>  	if (ret < 0)
> @@ -1326,7 +1407,7 @@ static int max9286_remove(struct i2c_client *client)
>
>  	max9286_v4l2_unregister(priv);
>
> -	regulator_disable(priv->regulator);
> +	max9286_poc_power_off(priv);
>
>  	gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
>
> --
> Regards,
>
> Laurent Pinchart
>

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

* Re: [PATCH v2 05/11] media: i2c: max9286: Support manual framesync operation
  2022-01-01 18:28 ` [PATCH v2 05/11] media: i2c: max9286: Support manual framesync operation Laurent Pinchart
@ 2022-01-09 10:26   ` Jacopo Mondi
  0 siblings, 0 replies; 37+ messages in thread
From: Jacopo Mondi @ 2022-01-09 10:26 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Hi Laurent,

On Sat, Jan 01, 2022 at 08:28:00PM +0200, Laurent Pinchart wrote:
> The MAX9286 can generate a framesync signal to synchronize the cameras,
> using an internal timer. Support this mode of operation and configure it
> through the .s_frameinterval() operation. If the frame interval is not
> 0, framesync is switched to manual mode with the specified interval,
> otherwise automatic mode is used.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
> Changes since v1:
>
> - Use pixel rate to calculate frame sync counter
> ---

Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Thanks
  j

>  drivers/media/i2c/max9286.c | 84 +++++++++++++++++++++++++++++++++----
>  1 file changed, 75 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> index 15c80034e3a4..75374034724f 100644
> --- a/drivers/media/i2c/max9286.c
> +++ b/drivers/media/i2c/max9286.c
> @@ -170,9 +170,11 @@ struct max9286_priv {
>  	u32 rev_chan_mv;
>
>  	struct v4l2_ctrl_handler ctrls;
> -	struct v4l2_ctrl *pixelrate;
> +	struct v4l2_ctrl *pixelrate_ctrl;
> +	unsigned int pixelrate;
>
>  	struct v4l2_mbus_framefmt fmt[MAX9286_N_SINKS];
> +	struct v4l2_fract interval;
>
>  	/* Protects controls and fmt structures */
>  	struct mutex mutex;
> @@ -473,6 +475,40 @@ static int max9286_check_config_link(struct max9286_priv *priv,
>  	return 0;
>  }
>
> +static void max9286_set_fsync_period(struct max9286_priv *priv)
> +{
> +	u32 fsync;
> +
> +	if (!priv->interval.numerator || !priv->interval.denominator) {
> +		/*
> +		 * Special case, a null interval enables automatic FRAMESYNC
> +		 * mode. FRAMESYNC is taken from the slowest link.
> +		 */
> +		max9286_write(priv, 0x01, MAX9286_FSYNCMODE_INT_HIZ |
> +			      MAX9286_FSYNCMETH_AUTO);
> +		return;
> +	}
> +
> +	/*
> +	 * Manual FRAMESYNC
> +	 *
> +	 * The FRAMESYNC generator is configured with a period expressed as a
> +	 * number of PCLK periods.
> +	 */
> +	fsync = div_u64((u64)priv->pixelrate * priv->interval.numerator,
> +			priv->interval.denominator);
> +
> +	dev_dbg(&priv->client->dev, "fsync period %u (pclk %u)\n", fsync,
> +		priv->pixelrate);
> +
> +	max9286_write(priv, 0x01, MAX9286_FSYNCMODE_INT_OUT |
> +		      MAX9286_FSYNCMETH_MANUAL);
> +
> +	max9286_write(priv, 0x06, (fsync >> 0) & 0xff);
> +	max9286_write(priv, 0x07, (fsync >> 8) & 0xff);
> +	max9286_write(priv, 0x08, (fsync >> 16) & 0xff);
> +}
> +
>  /* -----------------------------------------------------------------------------
>   * V4L2 Subdev
>   */
> @@ -511,11 +547,13 @@ static int max9286_set_pixelrate(struct max9286_priv *priv)
>  		return -EINVAL;
>  	}
>
> +	priv->pixelrate = pixelrate;
> +
>  	/*
>  	 * The CSI-2 transmitter pixel rate is the single source rate multiplied
>  	 * by the number of available sources.
>  	 */
> -	return v4l2_ctrl_s_ctrl_int64(priv->pixelrate,
> +	return v4l2_ctrl_s_ctrl_int64(priv->pixelrate_ctrl,
>  				      pixelrate * priv->nsources);
>  }
>
> @@ -655,6 +693,8 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
>  	int ret;
>
>  	if (enable) {
> +		max9286_set_fsync_period(priv);
> +
>  		/*
>  		 * The frame sync between cameras is transmitted across the
>  		 * reverse channel as GPIO. We must open all channels while
> @@ -714,6 +754,32 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
>  	return 0;
>  }
>
> +static int max9286_g_frame_interval(struct v4l2_subdev *sd,
> +				    struct v4l2_subdev_frame_interval *interval)
> +{
> +	struct max9286_priv *priv = sd_to_max9286(sd);
> +
> +	if (interval->pad != MAX9286_SRC_PAD)
> +		return -EINVAL;
> +
> +	interval->interval = priv->interval;
> +
> +	return 0;
> +}
> +
> +static int max9286_s_frame_interval(struct v4l2_subdev *sd,
> +				    struct v4l2_subdev_frame_interval *interval)
> +{
> +	struct max9286_priv *priv = sd_to_max9286(sd);
> +
> +	if (interval->pad != MAX9286_SRC_PAD)
> +		return -EINVAL;
> +
> +	priv->interval = interval->interval;
> +
> +	return 0;
> +}
> +
>  static int max9286_enum_mbus_code(struct v4l2_subdev *sd,
>  				  struct v4l2_subdev_state *sd_state,
>  				  struct v4l2_subdev_mbus_code_enum *code)
> @@ -805,6 +871,8 @@ static int max9286_get_fmt(struct v4l2_subdev *sd,
>
>  static const struct v4l2_subdev_video_ops max9286_video_ops = {
>  	.s_stream	= max9286_s_stream,
> +	.g_frame_interval = max9286_g_frame_interval,
> +	.s_frame_interval = max9286_s_frame_interval,
>  };
>
>  static const struct v4l2_subdev_pad_ops max9286_pad_ops = {
> @@ -885,10 +953,10 @@ static int max9286_v4l2_register(struct max9286_priv *priv)
>  	priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
>
>  	v4l2_ctrl_handler_init(&priv->ctrls, 1);
> -	priv->pixelrate = v4l2_ctrl_new_std(&priv->ctrls,
> -					    &max9286_ctrl_ops,
> -					    V4L2_CID_PIXEL_RATE,
> -					    1, INT_MAX, 1, 50000000);
> +	priv->pixelrate_ctrl = v4l2_ctrl_new_std(&priv->ctrls,
> +						 &max9286_ctrl_ops,
> +						 V4L2_CID_PIXEL_RATE,
> +						 1, INT_MAX, 1, 50000000);
>
>  	priv->sd.ctrl_handler = &priv->ctrls;
>  	ret = priv->ctrls.error;
> @@ -997,9 +1065,7 @@ static int max9286_setup(struct max9286_priv *priv)
>  		      MAX9286_CSILANECNT(priv->csi2_data_lanes) |
>  		      MAX9286_DATATYPE_YUV422_8BIT);
>
> -	/* Automatic: FRAMESYNC taken from the slowest Link. */
> -	max9286_write(priv, 0x01, MAX9286_FSYNCMODE_INT_HIZ |
> -		      MAX9286_FSYNCMETH_AUTO);
> +	max9286_set_fsync_period(priv);
>
>  	/* Enable HS/VS encoding, use D14/15 for HS/VS, invert VS. */
>  	max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_INVVS |
> --
> Regards,
>
> Laurent Pinchart
>

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

* Re: [PATCH v2 06/11] media: i2c: max9286: Rename MAX9286_DATATYPE_RAW11 to RAW12
  2022-01-01 18:28 ` [PATCH v2 06/11] media: i2c: max9286: Rename MAX9286_DATATYPE_RAW11 to RAW12 Laurent Pinchart
@ 2022-01-09 10:26   ` Jacopo Mondi
  0 siblings, 0 replies; 37+ messages in thread
From: Jacopo Mondi @ 2022-01-09 10:26 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Hi Laurent,

On Sat, Jan 01, 2022 at 08:28:01PM +0200, Laurent Pinchart wrote:
> The MAX9286_DATATYPE_RAW11 value is used to configure the MAX9286 for
> 11-bit or 12-bit input data. While 11-bit data is supported on the GMSL
> side, CSI-2 doesn't have a RAW11 format. 11-bit data is transferred over
> CSI-2 as RAW12. Rename the macro accordingly to avoid confusion.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Makes sense
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Thanks
  j

> ---
>  drivers/media/i2c/max9286.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> index 75374034724f..576d9c6fac14 100644
> --- a/drivers/media/i2c/max9286.c
> +++ b/drivers/media/i2c/max9286.c
> @@ -71,7 +71,7 @@
>  #define MAX9286_DATATYPE_USER_YUV_12BIT	(10 << 0)
>  #define MAX9286_DATATYPE_USER_24BIT	(9 << 0)
>  #define MAX9286_DATATYPE_RAW14		(8 << 0)
> -#define MAX9286_DATATYPE_RAW11		(7 << 0)
> +#define MAX9286_DATATYPE_RAW12		(7 << 0)
>  #define MAX9286_DATATYPE_RAW10		(6 << 0)
>  #define MAX9286_DATATYPE_RAW8		(5 << 0)
>  #define MAX9286_DATATYPE_YUV422_10BIT	(4 << 0)
> --
> Regards,
>
> Laurent Pinchart
>

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

* Re: [PATCH v2 07/11] media: i2c: max9286: Support 12-bit raw bayer formats
  2022-01-01 18:28 ` [PATCH v2 07/11] media: i2c: max9286: Support 12-bit raw bayer formats Laurent Pinchart
@ 2022-01-09 10:34   ` Jacopo Mondi
  2022-01-09 23:19     ` Laurent Pinchart
  0 siblings, 1 reply; 37+ messages in thread
From: Jacopo Mondi @ 2022-01-09 10:34 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Hi Laurent,

On Sat, Jan 01, 2022 at 08:28:02PM +0200, Laurent Pinchart wrote:
> Add support for 12-bit raw bayer formats to the driver, configuring the
> GMSL format accordingly.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/media/i2c/max9286.c | 128 ++++++++++++++++++++++++++----------
>  1 file changed, 95 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> index 576d9c6fac14..24c2bf4fda53 100644
> --- a/drivers/media/i2c/max9286.c
> +++ b/drivers/media/i2c/max9286.c
> @@ -135,6 +135,11 @@
>  #define MAX9286_N_PADS			5
>  #define MAX9286_SRC_PAD			4
>
> +struct max9286_format_info {
> +	u32 code;
> +	u8 datatype;
> +};
> +
>  struct max9286_source {
>  	struct v4l2_subdev *sd;
>  	struct fwnode_handle *fwnode;
> @@ -214,6 +219,34 @@ static inline struct max9286_priv *sd_to_max9286(struct v4l2_subdev *sd)
>  	return container_of(sd, struct max9286_priv, sd);
>  }
>
> +static const struct max9286_format_info max9286_formats[] = {
> +	{
> +		.code = MEDIA_BUS_FMT_UYVY8_1X16,
> +		.datatype = MAX9286_DATATYPE_YUV422_8BIT,
> +	}, {
> +		.code = MEDIA_BUS_FMT_VYUY8_1X16,
> +		.datatype = MAX9286_DATATYPE_YUV422_8BIT,
> +	}, {
> +		.code = MEDIA_BUS_FMT_YUYV8_1X16,
> +		.datatype = MAX9286_DATATYPE_YUV422_8BIT,
> +	}, {
> +		.code = MEDIA_BUS_FMT_YVYU8_1X16,
> +		.datatype = MAX9286_DATATYPE_YUV422_8BIT,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
> +		.datatype = MAX9286_DATATYPE_RAW12,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
> +		.datatype = MAX9286_DATATYPE_RAW12,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
> +		.datatype = MAX9286_DATATYPE_RAW12,
> +	}, {
> +		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
> +		.datatype = MAX9286_DATATYPE_RAW12,
> +	},
> +};
> +
>  /* -----------------------------------------------------------------------------
>   * I2C IO
>   */
> @@ -475,6 +508,38 @@ static int max9286_check_config_link(struct max9286_priv *priv,
>  	return 0;
>  }
>
> +static void max9286_set_video_format(struct max9286_priv *priv,
> +				     const struct v4l2_mbus_framefmt *format)
> +{
> +	const struct max9286_format_info *info = NULL;
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(max9286_formats); ++i) {
> +		if (max9286_formats[i].code == format->code) {
> +			info = &max9286_formats[i];
> +			break;
> +		}
> +	}
> +
> +	if (WARN_ON(!info))
> +		return;
> +
> +	/*
> +	 * Video format setup:
> +	 * Disable CSI output, VC is set according to Link number.
> +	 */
> +	max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);

I'm a bit scared about the fact settnig the video format disables the
CSI-2 output. But for the current usage pattern, it seems ok

> +
> +	/* Enable CSI-2 Lane D0-D3 only, DBL mode. */
> +	max9286_write(priv, 0x12, MAX9286_CSIDBL | MAX9286_DBL |
> +		      MAX9286_CSILANECNT(priv->csi2_data_lanes) |
> +		      info->datatype);
> +
> +	/* Enable HS/VS encoding, use D14/15 for HS/VS, invert VS. */
> +	max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_INVVS |
> +		      MAX9286_HVSRC_D14);
> +}
> +
>  static void max9286_set_fsync_period(struct max9286_priv *priv)
>  {
>  	u32 fsync;
> @@ -693,6 +758,15 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
>  	int ret;
>
>  	if (enable) {
> +		const struct v4l2_mbus_framefmt *format;
> +
> +		/*
> +		 * Get the format from the first used sink pad, as all sink
> +		 * formats must be identical.
> +		 */
> +		format = &priv->fmt[__ffs(priv->bound_sources)];
> +
> +		max9286_set_video_format(priv, format);
>  		max9286_set_fsync_period(priv);
>
>  		/*
> @@ -813,22 +887,20 @@ static int max9286_set_fmt(struct v4l2_subdev *sd,
>  {
>  	struct max9286_priv *priv = sd_to_max9286(sd);
>  	struct v4l2_mbus_framefmt *cfg_fmt;
> +	unsigned int i;
>
>  	if (format->pad == MAX9286_SRC_PAD)
>  		return -EINVAL;
>
> -	/* Refuse non YUV422 formats as we hardcode DT to 8 bit YUV422 */
> -	switch (format->format.code) {
> -	case MEDIA_BUS_FMT_UYVY8_1X16:
> -	case MEDIA_BUS_FMT_VYUY8_1X16:
> -	case MEDIA_BUS_FMT_YUYV8_1X16:
> -	case MEDIA_BUS_FMT_YVYU8_1X16:
> -		break;
> -	default:
> -		format->format.code = MEDIA_BUS_FMT_UYVY8_1X16;
> -		break;
> +	/* Validate the format. */
> +	for (i = 0; i < ARRAY_SIZE(max9286_formats); ++i) {
> +		if (max9286_formats[i].code == format->format.code)
> +			break;
>  	}
>
> +	if (i == ARRAY_SIZE(max9286_formats))
> +		format->format.code = max9286_formats[i].code;

Isn't i past the end of the array now ?

> +
>  	cfg_fmt = max9286_get_pad_format(priv, sd_state, format->pad,
>  					 format->which);
>  	if (!cfg_fmt)
> @@ -886,16 +958,20 @@ static const struct v4l2_subdev_ops max9286_subdev_ops = {
>  	.pad		= &max9286_pad_ops,
>  };
>
> +static const struct v4l2_mbus_framefmt max9286_default_format = {
> +	.width		= 1280,
> +	.height		= 800,
> +	.code		= MEDIA_BUS_FMT_UYVY8_1X16,
> +	.colorspace	= V4L2_COLORSPACE_SRGB,
> +	.field		= V4L2_FIELD_NONE,
> +	.ycbcr_enc	= V4L2_YCBCR_ENC_DEFAULT,
> +	.quantization	= V4L2_QUANTIZATION_DEFAULT,
> +	.xfer_func	= V4L2_XFER_FUNC_DEFAULT,
> +};
> +
>  static void max9286_init_format(struct v4l2_mbus_framefmt *fmt)
>  {
> -	fmt->width		= 1280;
> -	fmt->height		= 800;
> -	fmt->code		= MEDIA_BUS_FMT_UYVY8_1X16;
> -	fmt->colorspace		= V4L2_COLORSPACE_SRGB;
> -	fmt->field		= V4L2_FIELD_NONE;
> -	fmt->ycbcr_enc		= V4L2_YCBCR_ENC_DEFAULT;
> -	fmt->quantization	= V4L2_QUANTIZATION_DEFAULT;
> -	fmt->xfer_func		= V4L2_XFER_FUNC_DEFAULT;
> +	*fmt = max9286_default_format;
>  }
>
>  static int max9286_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
> @@ -1054,23 +1130,9 @@ static int max9286_setup(struct max9286_priv *priv)
>  	max9286_write(priv, 0x0b, link_order[priv->route_mask]);
>  	max9286_write(priv, 0x69, (0xf & ~priv->route_mask));
>
> -	/*
> -	 * Video format setup:
> -	 * Disable CSI output, VC is set according to Link number.
> -	 */
> -	max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
> -
> -	/* Enable CSI-2 Lane D0-D3 only, DBL mode, YUV422 8-bit. */
> -	max9286_write(priv, 0x12, MAX9286_CSIDBL | MAX9286_DBL |
> -		      MAX9286_CSILANECNT(priv->csi2_data_lanes) |
> -		      MAX9286_DATATYPE_YUV422_8BIT);
> -
> +	max9286_set_video_format(priv, &max9286_default_format);
>  	max9286_set_fsync_period(priv);
>
> -	/* Enable HS/VS encoding, use D14/15 for HS/VS, invert VS. */
> -	max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_INVVS |
> -		      MAX9286_HVSRC_D14);
> -
>  	/*
>  	 * The overlap window seems to provide additional validation by tracking
>  	 * the delay between vsync and frame sync, generating an error if the
> --
> Regards,
>
> Laurent Pinchart
>

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

* Re: [PATCH v2 08/11] media: i2c: max9286: Define macros for all bits of register 0x15
  2022-01-01 18:28 ` [PATCH v2 08/11] media: i2c: max9286: Define macros for all bits of register 0x15 Laurent Pinchart
@ 2022-01-09 10:37   ` Jacopo Mondi
  2022-01-09 23:21     ` Laurent Pinchart
  0 siblings, 1 reply; 37+ messages in thread
From: Jacopo Mondi @ 2022-01-09 10:37 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

On Sat, Jan 01, 2022 at 08:28:03PM +0200, Laurent Pinchart wrote:
> Macros are easier to read than numerical values.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/media/i2c/max9286.c | 27 ++++++++++++++++++---------
>  1 file changed, 18 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> index 24c2bf4fda53..4b69bd036ca6 100644
> --- a/drivers/media/i2c/max9286.c
> +++ b/drivers/media/i2c/max9286.c
> @@ -80,10 +80,13 @@
>  #define MAX9286_DATATYPE_RGB565		(1 << 0)
>  #define MAX9286_DATATYPE_RGB888		(0 << 0)
>  /* Register 0x15 */
> +#define MAX9286_CSI_IMAGE_TYP		BIT(7)
>  #define MAX9286_VC(n)			((n) << 5)
>  #define MAX9286_VCTYPE			BIT(4)
>  #define MAX9286_CSIOUTEN		BIT(3)
> -#define MAX9286_0X15_RESV		(3 << 0)
> +#define MAX9286_SWP_ENDIAN		BIT(2)
> +#define MAX9286_EN_CCBSYB_CLK_STR	BIT(1)
> +#define MAX9286_EN_GPI_CCBSYB		BIT(0)
>  /* Register 0x1b */
>  #define MAX9286_SWITCHIN(n)		(1 << ((n) + 4))
>  #define MAX9286_ENEQ(n)			(1 << (n))
> @@ -525,10 +528,12 @@ static void max9286_set_video_format(struct max9286_priv *priv,
>  		return;
>
>  	/*
> -	 * Video format setup:
> -	 * Disable CSI output, VC is set according to Link number.
> +	 * Video format setup: disable CSI output, set VC according to Link
> +	 * number, enable I2C clock stretching when CCBSY is low, enable CCBSY
> +	 * in external GPI-to-GPO mode.
>  	 */
> -	max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
> +	max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_EN_CCBSYB_CLK_STR |
> +		      MAX9286_EN_GPI_CCBSYB);
>
>  	/* Enable CSI-2 Lane D0-D3 only, DBL mode. */
>  	max9286_write(priv, 0x12, MAX9286_CSIDBL | MAX9286_DBL |
> @@ -810,13 +815,17 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
>  		}
>
>  		/*
> -		 * Enable CSI output, VC set according to link number.
> -		 * Bit 7 must be set (chip manual says it's 0 and reserved).
> +		 * Configure the CSI-2 output to line interleaved mode (W x (N
> +		 * x H), as opposed to the (N x W) x H mode that outputs the
> +		 * images stitched side-by-side) and enable it.
>  		 */
> -		max9286_write(priv, 0x15, 0x80 | MAX9286_VCTYPE |
> -			      MAX9286_CSIOUTEN | MAX9286_0X15_RESV);
> +		max9286_write(priv, 0x15, MAX9286_CSI_IMAGE_TYP | MAX9286_VCTYPE |
> +			      MAX9286_CSIOUTEN | MAX9286_EN_CCBSYB_CLK_STR |
> +			      MAX9286_EN_GPI_CCBSYB);
>  	} else {
> -		max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
> +		max9286_write(priv, 0x15, MAX9286_VCTYPE |
> +			      MAX9286_EN_CCBSYB_CLK_STR |
> +			      MAX9286_EN_GPI_CCBSYB);

Probably fits better on two lines only.

Trusting the bits definitions:
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Thanks
   j

>
>  		/* Stop all cameras. */
>  		for_each_source(priv, source)
> --
> Regards,
>
> Laurent Pinchart
>

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

* Re: [PATCH v2 09/11] media: i2c: max9286: Configure remote I2C speed from device tree
  2022-01-01 18:28 ` [PATCH v2 09/11] media: i2c: max9286: Configure remote I2C speed from device tree Laurent Pinchart
@ 2022-01-09 10:43   ` Jacopo Mondi
  2022-01-09 23:29     ` Laurent Pinchart
  0 siblings, 1 reply; 37+ messages in thread
From: Jacopo Mondi @ 2022-01-09 10:43 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Hi Laurent

On Sat, Jan 01, 2022 at 08:28:04PM +0200, Laurent Pinchart wrote:
> Read the maxim,i2c-clock-frequency DT property that specifies the speed
> of the remote I2C bus, and configure the MAX9286 accordingly. The remote
> serializers must all have a matching configuration.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/media/i2c/max9286.c | 56 +++++++++++++++++++++++++++++++------
>  1 file changed, 47 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> index 4b69bd036ca6..d88a4d8e63ab 100644
> --- a/drivers/media/i2c/max9286.c
> +++ b/drivers/media/i2c/max9286.c
> @@ -143,6 +143,11 @@ struct max9286_format_info {
>  	u8 datatype;
>  };
>
> +struct max9286_i2c_speed {
> +	u32 rate;
> +	u8 mstbt;
> +};
> +
>  struct max9286_source {
>  	struct v4l2_subdev *sd;
>  	struct fwnode_handle *fwnode;
> @@ -176,6 +181,7 @@ struct max9286_priv {
>  	/* The initial reverse control channel amplitude. */
>  	u32 init_rev_chan_mv;
>  	u32 rev_chan_mv;
> +	u8 i2c_mstbt;
>
>  	struct v4l2_ctrl_handler ctrls;
>  	struct v4l2_ctrl *pixelrate_ctrl;
> @@ -250,6 +256,17 @@ static const struct max9286_format_info max9286_formats[] = {
>  	},
>  };
>
> +static const struct max9286_i2c_speed max9286_i2c_speeds[] = {
> +	{ .rate =   8470, .mstbt = MAX9286_I2CMSTBT_8KBPS },
> +	{ .rate =  28300, .mstbt = MAX9286_I2CMSTBT_28KBPS },
> +	{ .rate =  84700, .mstbt = MAX9286_I2CMSTBT_84KBPS },
> +	{ .rate = 105000, .mstbt = MAX9286_I2CMSTBT_105KBPS },
> +	{ .rate = 173000, .mstbt = MAX9286_I2CMSTBT_173KBPS },
> +	{ .rate = 339000, .mstbt = MAX9286_I2CMSTBT_339KBPS },
> +	{ .rate = 533000, .mstbt = MAX9286_I2CMSTBT_533KBPS },
> +	{ .rate = 837000, .mstbt = MAX9286_I2CMSTBT_837KBPS },
> +};
> +
>  /* -----------------------------------------------------------------------------
>   * I2C IO
>   */
> @@ -370,7 +387,7 @@ static int max9286_i2c_mux_init(struct max9286_priv *priv)
>  static void max9286_configure_i2c(struct max9286_priv *priv, bool localack)
>  {
>  	u8 config = MAX9286_I2CSLVSH_469NS_234NS | MAX9286_I2CSLVTO_1024US |

Does the 'slave remote timeout' need to be changed according to speed
as well ?

> -		    MAX9286_I2CMSTBT_105KBPS;
> +		    priv->i2c_mstbt;
>
>  	if (localack)
>  		config |= MAX9286_I2CLOCACK;
> @@ -1320,6 +1337,8 @@ static int max9286_parse_dt(struct max9286_priv *priv)
>  	struct device_node *node = NULL;
>  	unsigned int i2c_mux_mask = 0;
>  	u32 reverse_channel_microvolt;
> +	u32 i2c_clk_freq = 105000;
> +	unsigned int i;
>
>  	/* Balance the of_node_put() performed by of_find_node_by_name(). */
>  	of_node_get(dev->of_node);
> @@ -1410,6 +1429,23 @@ static int max9286_parse_dt(struct max9286_priv *priv)
>  	}
>  	of_node_put(node);
>
> +	of_property_read_u32(dev->of_node, "maxim,i2c-clock-frequency",
> +			     &i2c_clk_freq);
> +	for (i = 0; i < ARRAY_SIZE(max9286_i2c_speeds); ++i) {
> +		const struct max9286_i2c_speed *speed = &max9286_i2c_speeds[i];
> +
> +		if (speed->rate == i2c_clk_freq) {
> +			priv->i2c_mstbt = speed->mstbt;
> +			break;
> +		}
> +	}
> +
> +	if (i == ARRAY_SIZE(max9286_i2c_speeds)) {
> +		dev_err(dev, "Invalid %s value %u\n",
> +			"maxim,i2c-clock-frequency", i2c_clk_freq);
> +		return -EINVAL;
> +	}
> +

I never got a real answer to this question in years: should we assume
dts are correct or should we validate them ?

>  	/*
>  	 * Parse the initial value of the reverse channel amplitude from
>  	 * the firmware interface and convert it to millivolts.
> @@ -1484,10 +1520,16 @@ static int max9286_probe(struct i2c_client *client)
>  	priv->client = client;
>  	i2c_set_clientdata(client, priv);
>
> +	ret = max9286_parse_dt(priv);

Any reason why moving this so up ? Doing so just before i2c_config()
would be enough ?

> +	if (ret)
> +		goto err_cleanup_dt;
> +
>  	priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable",
>  						   GPIOD_OUT_HIGH);
> -	if (IS_ERR(priv->gpiod_pwdn))
> -		return PTR_ERR(priv->gpiod_pwdn);
> +	if (IS_ERR(priv->gpiod_pwdn)) {
> +		ret = PTR_ERR(priv->gpiod_pwdn);
> +		goto err_cleanup_dt;
> +	}
>
>  	gpiod_set_consumer_name(priv->gpiod_pwdn, "max9286-pwdn");
>  	gpiod_set_value_cansleep(priv->gpiod_pwdn, 1);
> @@ -1514,10 +1556,6 @@ static int max9286_probe(struct i2c_client *client)
>  	if (ret)
>  		goto err_powerdown;
>
> -	ret = max9286_parse_dt(priv);
> -	if (ret)
> -		goto err_cleanup_dt;
> -
>  	ret = max9286_get_poc_supplies(priv);
>  	if (ret)
>  		goto err_cleanup_dt;
> @@ -1528,10 +1566,10 @@ static int max9286_probe(struct i2c_client *client)
>
>  	return 0;
>
> -err_cleanup_dt:
> -	max9286_cleanup_dt(priv);
>  err_powerdown:
>  	gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
> +err_cleanup_dt:
> +	max9286_cleanup_dt(priv);
>
>  	return ret;
>  }
> --
> Regards,
>
> Laurent Pinchart
>

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

* Re: [PATCH v2 10/11] media: i2c: max9286: Configure bus width from device tree
  2022-01-01 18:28 ` [PATCH v2 10/11] media: i2c: max9286: Configure bus width " Laurent Pinchart
@ 2022-01-09 10:56   ` Jacopo Mondi
  2022-01-09 23:32     ` Laurent Pinchart
  0 siblings, 1 reply; 37+ messages in thread
From: Jacopo Mondi @ 2022-01-09 10:56 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Hi Laurent

On Sat, Jan 01, 2022 at 08:28:05PM +0200, Laurent Pinchart wrote:
> The GMSL serial data bus width is normally selected through the BWS pin.
> On some systems, the pin may not be wired to the correct value. Support
> overriding the bus width by software, using the value specified in the
> device tree.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/media/i2c/max9286.c | 36 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
>
> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> index d88a4d8e63ab..07ebb01640a1 100644
> --- a/drivers/media/i2c/max9286.c
> +++ b/drivers/media/i2c/max9286.c
> @@ -90,6 +90,11 @@
>  /* Register 0x1b */
>  #define MAX9286_SWITCHIN(n)		(1 << ((n) + 4))
>  #define MAX9286_ENEQ(n)			(1 << (n))
> +/* Register 0x1c */
> +#define MAX9286_HIGHIMM(n)		BIT((n) + 4)
> +#define MAX9286_I2CSEL			BIT(2)
> +#define MAX9286_HIBW			BIT(1)
> +#define MAX9286_BWS			BIT(0)
>  /* Register 0x27 */
>  #define MAX9286_LOCKED			BIT(7)
>  /* Register 0x31 */
> @@ -182,6 +187,7 @@ struct max9286_priv {
>  	u32 init_rev_chan_mv;
>  	u32 rev_chan_mv;
>  	u8 i2c_mstbt;
> +	u32 bus_width;
>
>  	struct v4l2_ctrl_handler ctrls;
>  	struct v4l2_ctrl *pixelrate_ctrl;
> @@ -1159,6 +1165,23 @@ static int max9286_setup(struct max9286_priv *priv)
>  	max9286_set_video_format(priv, &max9286_default_format);
>  	max9286_set_fsync_period(priv);
>
> +	if (priv->bus_width) {
> +		int val;
> +
> +		val = max9286_read(priv, 0x1c);
> +		if (val < 0)
> +			return val;
> +
> +		val &= ~(MAX9286_HIBW | MAX9286_BWS);
> +
> +		if (priv->bus_width == 27)
> +			val |= MAX9286_HIBW;
> +		else if (priv->bus_width == 32)
> +			val |= MAX9286_BWS;
> +
> +		max9286_write(priv, 0x1c, val);
> +	}
> +
>  	/*
>  	 * The overlap window seems to provide additional validation by tracking
>  	 * the delay between vsync and frame sync, generating an error if the
> @@ -1429,6 +1452,19 @@ static int max9286_parse_dt(struct max9286_priv *priv)
>  	}
>  	of_node_put(node);
>
> +	of_property_read_u32(dev->of_node, "maxim,bus-width", &priv->bus_width);
> +	switch (priv->bus_width) {
> +	case 0:

Can you add a comment that in this case we rely on HW configuration ?
Looking at this with the above function in the same patch makes it
clear, but it might get lost when merged.

Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Thanks
  j


> +	case 24:
> +	case 27:
> +	case 32:
> +		break;
> +	default:
> +		dev_err(dev, "Invalid %s value %u\n", "maxim,bus-width",
> +			priv->bus_width);
> +		return -EINVAL;
> +	}
> +
>  	of_property_read_u32(dev->of_node, "maxim,i2c-clock-frequency",
>  			     &i2c_clk_freq);
>  	for (i = 0; i < ARRAY_SIZE(max9286_i2c_speeds); ++i) {
> --
> Regards,
>
> Laurent Pinchart
>

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

* Re: [PATCH v2 11/11] media: i2c: max9286: Select HS as data enable signal
  2022-01-01 18:28 ` [PATCH v2 11/11] media: i2c: max9286: Select HS as data enable signal Laurent Pinchart
@ 2022-01-09 11:42   ` Jacopo Mondi
  0 siblings, 0 replies; 37+ messages in thread
From: Jacopo Mondi @ 2022-01-09 11:42 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Hi Laurent,

On Sat, Jan 01, 2022 at 08:28:06PM +0200, Laurent Pinchart wrote:
> GMSL can transport three synchronization signals: VSync, HSync and Data
> Enable. The MAX9286 can select either HS or DE as a line valid signal.
>
> Not all serializers (and transmission formats) support the DE signal.
> The MAX9271, used by the RDACM20 and RDACM21 cameras, doesn't document
> DE support. Nonetheless, the max9286 driver selects the DE signal as
> line valid in register 0x0c (by not setting the DESEL bit). It's not
> clear why this works. As HS is a more common line valid qualifier, set
> the DESEL bit by default. This is needed to support the onsemi MARS
> cameras.
>
> If a camera requires usage of the DE signal in the future, this will
> need to be made configurable.

Tested-by: Jacopo Mondi <jacopo@jmondi.org>
On Eagle V3M with RDACM20

Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Thanks
   j
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/media/i2c/max9286.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> index 07ebb01640a1..446fc238d642 100644
> --- a/drivers/media/i2c/max9286.c
> +++ b/drivers/media/i2c/max9286.c
> @@ -563,9 +563,12 @@ static void max9286_set_video_format(struct max9286_priv *priv,
>  		      MAX9286_CSILANECNT(priv->csi2_data_lanes) |
>  		      info->datatype);
>
> -	/* Enable HS/VS encoding, use D14/15 for HS/VS, invert VS. */
> -	max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_INVVS |
> -		      MAX9286_HVSRC_D14);
> +	/*
> +	 * Enable HS/VS encoding, use HS as line valid source, use D14/15 for
> +	 * HS/VS, invert VS.
> +	 */
> +	max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_DESEL |
> +		      MAX9286_INVVS | MAX9286_HVSRC_D14);
>  }
>
>  static void max9286_set_fsync_period(struct max9286_priv *priv)
> --
> Regards,
>
> Laurent Pinchart
>

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

* Re: [PATCH v2 12/11] media: i2c: max9286: Print power-up GMSL link configuration
  2022-01-01 23:26 ` [PATCH v2 12/11] media: i2c: max9286: Print power-up GMSL link configuration Laurent Pinchart
@ 2022-01-09 11:44   ` Jacopo Mondi
  0 siblings, 0 replies; 37+ messages in thread
From: Jacopo Mondi @ 2022-01-09 11:44 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Hi Laurent

On Sun, Jan 02, 2022 at 01:26:37AM +0200, Laurent Pinchart wrote:
> The power-up GMSL link configuration is controlled by the HIM and BWS
> pins, whose state is reflected in register 0x1c. Print the detected
> power-up config in a debug message to help debugging.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Thanks
  j

> ---
>  drivers/media/i2c/max9286.c | 23 +++++++++++++----------
>  1 file changed, 13 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> index 446fc238d642..f7cbfdde436e 100644
> --- a/drivers/media/i2c/max9286.c
> +++ b/drivers/media/i2c/max9286.c
> @@ -1147,6 +1147,7 @@ static int max9286_setup(struct max9286_priv *priv)
>  		(2 << 6) | (1 << 4) | (0 << 2) | (3 << 0), /* 210x */
>  		(3 << 6) | (2 << 4) | (1 << 2) | (0 << 0), /* 3210 */
>  	};
> +	int cfg;
>
>  	/*
>  	 * Set the I2C bus speed.
> @@ -1168,21 +1169,23 @@ static int max9286_setup(struct max9286_priv *priv)
>  	max9286_set_video_format(priv, &max9286_default_format);
>  	max9286_set_fsync_period(priv);
>
> +	cfg = max9286_read(priv, 0x1c);
> +	if (cfg < 0)
> +		return cfg;
> +
> +	dev_dbg(&priv->client->dev, "power-up config: %s immunity, %u-bit bus\n",
> +		cfg & MAX9286_HIGHIMM(0) ? "high" : "legacy",
> +		cfg & MAX9286_BWS ? 32 : cfg & MAX9286_HIBW ? 27 : 24);
> +
>  	if (priv->bus_width) {
> -		int val;
> -
> -		val = max9286_read(priv, 0x1c);
> -		if (val < 0)
> -			return val;
> -
> -		val &= ~(MAX9286_HIBW | MAX9286_BWS);
> +		cfg &= ~(MAX9286_HIBW | MAX9286_BWS);
>
>  		if (priv->bus_width == 27)
> -			val |= MAX9286_HIBW;
> +			cfg |= MAX9286_HIBW;
>  		else if (priv->bus_width == 32)
> -			val |= MAX9286_BWS;
> +			cfg |= MAX9286_BWS;
>
> -		max9286_write(priv, 0x1c, val);
> +		max9286_write(priv, 0x1c, cfg);
>  	}
>
>  	/*
> --
> Regards,
>
> Laurent Pinchart
>

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

* Re: [PATCH v2 03/11] dt-bindings: media: i2c: max9286: Add property to select bus width
  2022-01-01 18:27 ` [PATCH v2 03/11] dt-bindings: media: i2c: max9286: Add property to select bus width Laurent Pinchart
@ 2022-01-09 11:47   ` Jacopo Mondi
  2022-01-10 20:53   ` Rob Herring
  2022-01-10 21:24   ` [PATCH v2.1 " Laurent Pinchart
  2 siblings, 0 replies; 37+ messages in thread
From: Jacopo Mondi @ 2022-01-09 11:47 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan, Rob Herring, devicetree

Hi Laurent,

On Sat, Jan 01, 2022 at 08:27:58PM +0200, Laurent Pinchart wrote:
> The GMSL serial data bus width is normally selected by the BWS pin, but
> it can also be configured by software. Add a DT property that allows
> overriding the value of the BWS-selected bus width to support systems
> whose BWS pin doesn't result in the correct value.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Thanks
  j

> ---
>  .../devicetree/bindings/media/i2c/maxim,max9286.yaml       | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> index 5d3e99027a79..123e98cdb7b6 100644
> --- a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> @@ -50,6 +50,13 @@ properties:
>    '#gpio-cells':
>      const: 2
>
> +  maxim,bus-width:
> +    enum: [ 24, 27, 32 ]
> +    description: |
> +      The GMSL serial data bus width. This setting is normally controlled by
> +      the BWS pin, but may be overridden with this property. The value must
> +      match the configuration of the remote serializers.
> +
>    maxim,i2c-clock-frequency:
>      enum: [ 8470, 28300, 84700, 105000, 173000, 339000, 533000, 837000 ]
>      default: 105000
> --
> Regards,
>
> Laurent Pinchart
>

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

* Re: [PATCH v2 01/11] dt-bindings: media: i2c: max9286: Add support for per-port supplies
  2022-01-01 18:27 ` [PATCH v2 01/11] dt-bindings: media: i2c: max9286: Add support for per-port supplies Laurent Pinchart
@ 2022-01-09 11:48   ` Jacopo Mondi
  2022-01-10 20:47   ` Rob Herring
  1 sibling, 0 replies; 37+ messages in thread
From: Jacopo Mondi @ 2022-01-09 11:48 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan, Rob Herring, devicetree,
	Mark Brown, Liam Girdwood

Hi Laurent,

On Sat, Jan 01, 2022 at 08:27:56PM +0200, Laurent Pinchart wrote:
> Power supplies for the ports can be controlled per port depending on the
> hardware design. Support per-port supplies in the DT bindings, mutually
> exclusive with the global supply.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>

Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>

Thanks
  j

> ---
> Changes since v1:
>
> - Simplify mutual exclusion condition
> ---
>  .../bindings/media/i2c/maxim,max9286.yaml          | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> index 02f656e78700..c20557b52e45 100644
> --- a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> @@ -39,7 +39,7 @@ properties:
>      maxItems: 1
>
>    poc-supply:
> -    description: Regulator providing Power over Coax to the cameras
> +    description: Regulator providing Power over Coax to all the ports
>
>    enable-gpios:
>      description: GPIO connected to the \#PWDN pin with inverted polarity
> @@ -160,6 +160,10 @@ properties:
>
>              additionalProperties: false
>
> +patternProperties:
> +  "^port[0-3]-poc-supply$":
> +    description: Regulator providing Power over Coax for a particular port
> +
>  required:
>    - compatible
>    - reg
> @@ -167,6 +171,14 @@ required:
>    - i2c-mux
>    - gpio-controller
>
> +allOf:
> +  - if:
> +      required:
> +        - poc-supply
> +    then:
> +      patternProperties:
> +        "^port[0-3]-poc-supply$": false
> +
>  additionalProperties: false
>
>  examples:
> --
> Regards,
>
> Laurent Pinchart
>

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

* Re: [PATCH v2 04/11] media: i2c: max9286: Add support for port regulators
  2022-01-09 10:04   ` Jacopo Mondi
@ 2022-01-09 23:16     ` Laurent Pinchart
  0 siblings, 0 replies; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-09 23:16 UTC (permalink / raw)
  To: Jacopo Mondi
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan, Mark Brown, Liam Girdwood

Hi Jacopo,

On Sun, Jan 09, 2022 at 11:04:12AM +0100, Jacopo Mondi wrote:
> On Sat, Jan 01, 2022 at 08:27:59PM +0200, Laurent Pinchart wrote:
> > From: Thomas Nizan <tnizan@witekio.com>
> >
> > Allow users to use one PoC regulator per port, instead of a global
> > regulator.
> >
> > The properties '^port[0-3]-poc-supply$' in the DT node are used to
> > indicate the regulators for individual ports.
> >
> > Signed-off-by: Thomas Nizan <tnizan@witekio.com>
> > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> 
> The patch looks almost good, but it will really conflict with gpio-poc work I
> have on the list. Should we decide an ordering and send a single
> series with both efforts in to ease collecting it ?

I'm fine with any order, and I'm also fine merging the two series. I
don't mind rebasing on top of your gpio-poc series at all, would that
help ?

> > ---
> > Changes since v1:
> >
> > - Use to_index()
> > - Use dev_err_probe()
> > - Fix error path in probe()
> > - Use devm_regulator_get_optional() instead of
> >   devm_regulator_get_exclusive()
> > ---
> >  drivers/media/i2c/max9286.c | 107 +++++++++++++++++++++++++++++++-----
> >  1 file changed, 94 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> > index eb2b8e42335b..15c80034e3a4 100644
> > --- a/drivers/media/i2c/max9286.c
> > +++ b/drivers/media/i2c/max9286.c
> > @@ -138,6 +138,7 @@
> >  struct max9286_source {
> >  	struct v4l2_subdev *sd;
> >  	struct fwnode_handle *fwnode;
> > +	struct regulator *regulator;
> >  };
> >
> >  struct max9286_asd {
> > @@ -1071,6 +1072,49 @@ static int max9286_register_gpio(struct max9286_priv *priv)
> >  	return ret;
> >  }
> >
> > +static int max9286_poc_power_on(struct max9286_priv *priv)
> > +{
> > +	struct max9286_source *source;
> > +	unsigned int enabled = 0;
> > +	int ret;
> > +
> > +	/* Enable the global regulator if available. */
> > +	if (priv->regulator)
> > +		return regulator_enable(priv->regulator);
> > +
> > +	/* Otherwise use the per-port regulators. */
> > +	for_each_source(priv, source) {
> > +		ret = regulator_enable(source->regulator);
> > +		if (ret < 0)
> > +			goto error;
> > +
> > +		enabled |= BIT(to_index(priv, source));
> > +	}
> > +
> > +	return 0;
> > +
> > +error:
> > +	for_each_source(priv, source) {
> > +		if (enabled & BIT(to_index(priv, source)))
> > +			regulator_disable(source->regulator);
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +static void max9286_poc_power_off(struct max9286_priv *priv)
> > +{
> > +	struct max9286_source *source;
> > +
> > +	if (priv->regulator) {
> > +		regulator_disable(priv->regulator);
> > +		return;
> > +	}
> > +
> > +	for_each_source(priv, source)
> > +		regulator_disable(source->regulator);
> > +}
> > +
> >  static int max9286_init(struct device *dev)
> >  {
> >  	struct max9286_priv *priv;
> > @@ -1081,9 +1125,9 @@ static int max9286_init(struct device *dev)
> >  	priv = i2c_get_clientdata(client);
> >
> >  	/* Enable the bus power. */
> > -	ret = regulator_enable(priv->regulator);
> > +	ret = max9286_poc_power_on(priv);
> >  	if (ret < 0) {
> > -		dev_err(&client->dev, "Unable to turn PoC on\n");
> > +		dev_err(dev, "Unable to turn PoC on\n");
> >  		return ret;
> >  	}
> >
> > @@ -1117,7 +1161,7 @@ static int max9286_init(struct device *dev)
> >  err_v4l2_register:
> >  	max9286_v4l2_unregister(priv);
> >  err_regulator:
> > -	regulator_disable(priv->regulator);
> > +	max9286_poc_power_off(priv);
> >
> >  	return ret;
> >  }
> > @@ -1248,6 +1292,47 @@ static int max9286_parse_dt(struct max9286_priv *priv)
> >  	return 0;
> >  }
> >
> > +static int max9286_get_poc_supplies(struct max9286_priv *priv)
> > +{
> > +	struct device *dev = &priv->client->dev;
> > +	struct max9286_source *source;
> > +	int ret;
> > +
> > +	/* Start by getting the global regulator. */
> > +	priv->regulator = devm_regulator_get_optional(dev, "poc");
> > +	if (!IS_ERR(priv->regulator))
> > +		return 0;
> > +
> > +	if (PTR_ERR(priv->regulator) != -ENODEV) {
> > +		if (PTR_ERR(priv->regulator) != -EPROBE_DEFER)
> > +			dev_err(dev, "Unable to get PoC regulator: %ld\n",
> > +				PTR_ERR(priv->regulator));
> > +		return PTR_ERR(priv->regulator);
> > +	}
> > +
> > +	/* If there's no global regulator, get per-port regulators. */
> > +	dev_dbg(dev,
> > +		"No global PoC regulator, looking for per-port regulators\n");
> > +	priv->regulator = NULL;
> > +
> > +	for_each_source(priv, source) {
> > +		unsigned int index = to_index(priv, source);
> > +		char name[10];
> > +
> > +		snprintf(name, sizeof(name), "port%u-poc", index);
> > +		source->regulator = devm_regulator_get(dev, name);
> 
> Are you ok with a dummy being returned ?

I think that's fine. It would mean that there's no global regulator nor
per-port regulator specified in DT, which shouldn't happen even if the
supply is alwaus on. From a driver point of view it won't hurt I think.

> > +		if (IS_ERR(source->regulator)) {
> > +			ret = PTR_ERR(source->regulator);
> > +			dev_err_probe(dev, ret,
> > +				      "Unable to get port %u PoC regulator\n",
> > +				      index);
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  static int max9286_probe(struct i2c_client *client)
> >  {
> >  	struct max9286_priv *priv;
> > @@ -1292,17 +1377,13 @@ static int max9286_probe(struct i2c_client *client)
> >  	if (ret)
> >  		goto err_powerdown;
> >
> > -	priv->regulator = devm_regulator_get(&client->dev, "poc");
> > -	if (IS_ERR(priv->regulator)) {
> > -		ret = PTR_ERR(priv->regulator);
> > -		dev_err_probe(&client->dev, ret,
> > -			      "Unable to get PoC regulator\n");
> > -		goto err_powerdown;
> > -	}
> > -
> >  	ret = max9286_parse_dt(priv);
> >  	if (ret)
> > -		goto err_powerdown;
> > +		goto err_cleanup_dt;
> 
> Shouldn't this be still err_powerdown ?

I don't think so, max9286_parse_dt() may have populated the fwnode of
part of the sources before failing.

> > +
> > +	ret = max9286_get_poc_supplies(priv);
> > +	if (ret)
> > +		goto err_cleanup_dt;
> >
> >  	ret = max9286_init(&client->dev);
> >  	if (ret < 0)
> > @@ -1326,7 +1407,7 @@ static int max9286_remove(struct i2c_client *client)
> >
> >  	max9286_v4l2_unregister(priv);
> >
> > -	regulator_disable(priv->regulator);
> > +	max9286_poc_power_off(priv);
> >
> >  	gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
> >

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 07/11] media: i2c: max9286: Support 12-bit raw bayer formats
  2022-01-09 10:34   ` Jacopo Mondi
@ 2022-01-09 23:19     ` Laurent Pinchart
  0 siblings, 0 replies; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-09 23:19 UTC (permalink / raw)
  To: Jacopo Mondi
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Hi Jacopo,

On Sun, Jan 09, 2022 at 11:34:09AM +0100, Jacopo Mondi wrote:
> On Sat, Jan 01, 2022 at 08:28:02PM +0200, Laurent Pinchart wrote:
> > Add support for 12-bit raw bayer formats to the driver, configuring the
> > GMSL format accordingly.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> >  drivers/media/i2c/max9286.c | 128 ++++++++++++++++++++++++++----------
> >  1 file changed, 95 insertions(+), 33 deletions(-)
> >
> > diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> > index 576d9c6fac14..24c2bf4fda53 100644
> > --- a/drivers/media/i2c/max9286.c
> > +++ b/drivers/media/i2c/max9286.c
> > @@ -135,6 +135,11 @@
> >  #define MAX9286_N_PADS			5
> >  #define MAX9286_SRC_PAD			4
> >
> > +struct max9286_format_info {
> > +	u32 code;
> > +	u8 datatype;
> > +};
> > +
> >  struct max9286_source {
> >  	struct v4l2_subdev *sd;
> >  	struct fwnode_handle *fwnode;
> > @@ -214,6 +219,34 @@ static inline struct max9286_priv *sd_to_max9286(struct v4l2_subdev *sd)
> >  	return container_of(sd, struct max9286_priv, sd);
> >  }
> >
> > +static const struct max9286_format_info max9286_formats[] = {
> > +	{
> > +		.code = MEDIA_BUS_FMT_UYVY8_1X16,
> > +		.datatype = MAX9286_DATATYPE_YUV422_8BIT,
> > +	}, {
> > +		.code = MEDIA_BUS_FMT_VYUY8_1X16,
> > +		.datatype = MAX9286_DATATYPE_YUV422_8BIT,
> > +	}, {
> > +		.code = MEDIA_BUS_FMT_YUYV8_1X16,
> > +		.datatype = MAX9286_DATATYPE_YUV422_8BIT,
> > +	}, {
> > +		.code = MEDIA_BUS_FMT_YVYU8_1X16,
> > +		.datatype = MAX9286_DATATYPE_YUV422_8BIT,
> > +	}, {
> > +		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
> > +		.datatype = MAX9286_DATATYPE_RAW12,
> > +	}, {
> > +		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
> > +		.datatype = MAX9286_DATATYPE_RAW12,
> > +	}, {
> > +		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
> > +		.datatype = MAX9286_DATATYPE_RAW12,
> > +	}, {
> > +		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
> > +		.datatype = MAX9286_DATATYPE_RAW12,
> > +	},
> > +};
> > +
> >  /* -----------------------------------------------------------------------------
> >   * I2C IO
> >   */
> > @@ -475,6 +508,38 @@ static int max9286_check_config_link(struct max9286_priv *priv,
> >  	return 0;
> >  }
> >
> > +static void max9286_set_video_format(struct max9286_priv *priv,
> > +				     const struct v4l2_mbus_framefmt *format)
> > +{
> > +	const struct max9286_format_info *info = NULL;
> > +	unsigned int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(max9286_formats); ++i) {
> > +		if (max9286_formats[i].code == format->code) {
> > +			info = &max9286_formats[i];
> > +			break;
> > +		}
> > +	}
> > +
> > +	if (WARN_ON(!info))
> > +		return;
> > +
> > +	/*
> > +	 * Video format setup:
> > +	 * Disable CSI output, VC is set according to Link number.
> > +	 */
> > +	max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
> 
> I'm a bit scared about the fact settnig the video format disables the
> CSI-2 output. But for the current usage pattern, it seems ok

I'd like to further reorganize this (on top of this series) by avoiding
the max9286_set_video_format() call from max9286_setup(), as that
shouldn't be needed at probe time.

> > +
> > +	/* Enable CSI-2 Lane D0-D3 only, DBL mode. */
> > +	max9286_write(priv, 0x12, MAX9286_CSIDBL | MAX9286_DBL |
> > +		      MAX9286_CSILANECNT(priv->csi2_data_lanes) |
> > +		      info->datatype);
> > +
> > +	/* Enable HS/VS encoding, use D14/15 for HS/VS, invert VS. */
> > +	max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_INVVS |
> > +		      MAX9286_HVSRC_D14);
> > +}
> > +
> >  static void max9286_set_fsync_period(struct max9286_priv *priv)
> >  {
> >  	u32 fsync;
> > @@ -693,6 +758,15 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
> >  	int ret;
> >
> >  	if (enable) {
> > +		const struct v4l2_mbus_framefmt *format;
> > +
> > +		/*
> > +		 * Get the format from the first used sink pad, as all sink
> > +		 * formats must be identical.
> > +		 */
> > +		format = &priv->fmt[__ffs(priv->bound_sources)];
> > +
> > +		max9286_set_video_format(priv, format);
> >  		max9286_set_fsync_period(priv);
> >
> >  		/*
> > @@ -813,22 +887,20 @@ static int max9286_set_fmt(struct v4l2_subdev *sd,
> >  {
> >  	struct max9286_priv *priv = sd_to_max9286(sd);
> >  	struct v4l2_mbus_framefmt *cfg_fmt;
> > +	unsigned int i;
> >
> >  	if (format->pad == MAX9286_SRC_PAD)
> >  		return -EINVAL;
> >
> > -	/* Refuse non YUV422 formats as we hardcode DT to 8 bit YUV422 */
> > -	switch (format->format.code) {
> > -	case MEDIA_BUS_FMT_UYVY8_1X16:
> > -	case MEDIA_BUS_FMT_VYUY8_1X16:
> > -	case MEDIA_BUS_FMT_YUYV8_1X16:
> > -	case MEDIA_BUS_FMT_YVYU8_1X16:
> > -		break;
> > -	default:
> > -		format->format.code = MEDIA_BUS_FMT_UYVY8_1X16;
> > -		break;
> > +	/* Validate the format. */
> > +	for (i = 0; i < ARRAY_SIZE(max9286_formats); ++i) {
> > +		if (max9286_formats[i].code == format->format.code)
> > +			break;
> >  	}
> >
> > +	if (i == ARRAY_SIZE(max9286_formats))
> > +		format->format.code = max9286_formats[i].code;
> 
> Isn't i past the end of the array now ?

Oops, it should be [0]. I'll fix it.

> > +
> >  	cfg_fmt = max9286_get_pad_format(priv, sd_state, format->pad,
> >  					 format->which);
> >  	if (!cfg_fmt)
> > @@ -886,16 +958,20 @@ static const struct v4l2_subdev_ops max9286_subdev_ops = {
> >  	.pad		= &max9286_pad_ops,
> >  };
> >
> > +static const struct v4l2_mbus_framefmt max9286_default_format = {
> > +	.width		= 1280,
> > +	.height		= 800,
> > +	.code		= MEDIA_BUS_FMT_UYVY8_1X16,
> > +	.colorspace	= V4L2_COLORSPACE_SRGB,
> > +	.field		= V4L2_FIELD_NONE,
> > +	.ycbcr_enc	= V4L2_YCBCR_ENC_DEFAULT,
> > +	.quantization	= V4L2_QUANTIZATION_DEFAULT,
> > +	.xfer_func	= V4L2_XFER_FUNC_DEFAULT,
> > +};
> > +
> >  static void max9286_init_format(struct v4l2_mbus_framefmt *fmt)
> >  {
> > -	fmt->width		= 1280;
> > -	fmt->height		= 800;
> > -	fmt->code		= MEDIA_BUS_FMT_UYVY8_1X16;
> > -	fmt->colorspace		= V4L2_COLORSPACE_SRGB;
> > -	fmt->field		= V4L2_FIELD_NONE;
> > -	fmt->ycbcr_enc		= V4L2_YCBCR_ENC_DEFAULT;
> > -	fmt->quantization	= V4L2_QUANTIZATION_DEFAULT;
> > -	fmt->xfer_func		= V4L2_XFER_FUNC_DEFAULT;
> > +	*fmt = max9286_default_format;
> >  }
> >
> >  static int max9286_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
> > @@ -1054,23 +1130,9 @@ static int max9286_setup(struct max9286_priv *priv)
> >  	max9286_write(priv, 0x0b, link_order[priv->route_mask]);
> >  	max9286_write(priv, 0x69, (0xf & ~priv->route_mask));
> >
> > -	/*
> > -	 * Video format setup:
> > -	 * Disable CSI output, VC is set according to Link number.
> > -	 */
> > -	max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
> > -
> > -	/* Enable CSI-2 Lane D0-D3 only, DBL mode, YUV422 8-bit. */
> > -	max9286_write(priv, 0x12, MAX9286_CSIDBL | MAX9286_DBL |
> > -		      MAX9286_CSILANECNT(priv->csi2_data_lanes) |
> > -		      MAX9286_DATATYPE_YUV422_8BIT);
> > -
> > +	max9286_set_video_format(priv, &max9286_default_format);
> >  	max9286_set_fsync_period(priv);
> >
> > -	/* Enable HS/VS encoding, use D14/15 for HS/VS, invert VS. */
> > -	max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_INVVS |
> > -		      MAX9286_HVSRC_D14);
> > -
> >  	/*
> >  	 * The overlap window seems to provide additional validation by tracking
> >  	 * the delay between vsync and frame sync, generating an error if the

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 08/11] media: i2c: max9286: Define macros for all bits of register 0x15
  2022-01-09 10:37   ` Jacopo Mondi
@ 2022-01-09 23:21     ` Laurent Pinchart
  2022-01-10 10:37       ` Sergey Shtylyov
  0 siblings, 1 reply; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-09 23:21 UTC (permalink / raw)
  To: Jacopo Mondi
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Hi Jacopo,

On Sun, Jan 09, 2022 at 11:37:38AM +0100, Jacopo Mondi wrote:
> On Sat, Jan 01, 2022 at 08:28:03PM +0200, Laurent Pinchart wrote:
> > Macros are easier to read than numerical values.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> >  drivers/media/i2c/max9286.c | 27 ++++++++++++++++++---------
> >  1 file changed, 18 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> > index 24c2bf4fda53..4b69bd036ca6 100644
> > --- a/drivers/media/i2c/max9286.c
> > +++ b/drivers/media/i2c/max9286.c
> > @@ -80,10 +80,13 @@
> >  #define MAX9286_DATATYPE_RGB565		(1 << 0)
> >  #define MAX9286_DATATYPE_RGB888		(0 << 0)
> >  /* Register 0x15 */
> > +#define MAX9286_CSI_IMAGE_TYP		BIT(7)
> >  #define MAX9286_VC(n)			((n) << 5)
> >  #define MAX9286_VCTYPE			BIT(4)
> >  #define MAX9286_CSIOUTEN		BIT(3)
> > -#define MAX9286_0X15_RESV		(3 << 0)
> > +#define MAX9286_SWP_ENDIAN		BIT(2)
> > +#define MAX9286_EN_CCBSYB_CLK_STR	BIT(1)
> > +#define MAX9286_EN_GPI_CCBSYB		BIT(0)
> >  /* Register 0x1b */
> >  #define MAX9286_SWITCHIN(n)		(1 << ((n) + 4))
> >  #define MAX9286_ENEQ(n)			(1 << (n))
> > @@ -525,10 +528,12 @@ static void max9286_set_video_format(struct max9286_priv *priv,
> >  		return;
> >
> >  	/*
> > -	 * Video format setup:
> > -	 * Disable CSI output, VC is set according to Link number.
> > +	 * Video format setup: disable CSI output, set VC according to Link
> > +	 * number, enable I2C clock stretching when CCBSY is low, enable CCBSY
> > +	 * in external GPI-to-GPO mode.
> >  	 */
> > -	max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
> > +	max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_EN_CCBSYB_CLK_STR |
> > +		      MAX9286_EN_GPI_CCBSYB);
> >
> >  	/* Enable CSI-2 Lane D0-D3 only, DBL mode. */
> >  	max9286_write(priv, 0x12, MAX9286_CSIDBL | MAX9286_DBL |
> > @@ -810,13 +815,17 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
> >  		}
> >
> >  		/*
> > -		 * Enable CSI output, VC set according to link number.
> > -		 * Bit 7 must be set (chip manual says it's 0 and reserved).
> > +		 * Configure the CSI-2 output to line interleaved mode (W x (N
> > +		 * x H), as opposed to the (N x W) x H mode that outputs the
> > +		 * images stitched side-by-side) and enable it.
> >  		 */
> > -		max9286_write(priv, 0x15, 0x80 | MAX9286_VCTYPE |
> > -			      MAX9286_CSIOUTEN | MAX9286_0X15_RESV);
> > +		max9286_write(priv, 0x15, MAX9286_CSI_IMAGE_TYP | MAX9286_VCTYPE |
> > +			      MAX9286_CSIOUTEN | MAX9286_EN_CCBSYB_CLK_STR |
> > +			      MAX9286_EN_GPI_CCBSYB);
> >  	} else {
> > -		max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
> > +		max9286_write(priv, 0x15, MAX9286_VCTYPE |
> > +			      MAX9286_EN_CCBSYB_CLK_STR |
> > +			      MAX9286_EN_GPI_CCBSYB);
> 
> Probably fits better on two lines only.

That would be over the 80 columns limit, which is a soft limit now, but
still often requested by reviewers (including myself in quite a few
cases :-)).

> Trusting the bits definitions:
> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> 
> >
> >  		/* Stop all cameras. */
> >  		for_each_source(priv, source)

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 09/11] media: i2c: max9286: Configure remote I2C speed from device tree
  2022-01-09 10:43   ` Jacopo Mondi
@ 2022-01-09 23:29     ` Laurent Pinchart
  0 siblings, 0 replies; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-09 23:29 UTC (permalink / raw)
  To: Jacopo Mondi
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Hi Jacopo,

On Sun, Jan 09, 2022 at 11:43:32AM +0100, Jacopo Mondi wrote:
> On Sat, Jan 01, 2022 at 08:28:04PM +0200, Laurent Pinchart wrote:
> > Read the maxim,i2c-clock-frequency DT property that specifies the speed
> > of the remote I2C bus, and configure the MAX9286 accordingly. The remote
> > serializers must all have a matching configuration.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> >  drivers/media/i2c/max9286.c | 56 +++++++++++++++++++++++++++++++------
> >  1 file changed, 47 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> > index 4b69bd036ca6..d88a4d8e63ab 100644
> > --- a/drivers/media/i2c/max9286.c
> > +++ b/drivers/media/i2c/max9286.c
> > @@ -143,6 +143,11 @@ struct max9286_format_info {
> >  	u8 datatype;
> >  };
> >
> > +struct max9286_i2c_speed {
> > +	u32 rate;
> > +	u8 mstbt;
> > +};
> > +
> >  struct max9286_source {
> >  	struct v4l2_subdev *sd;
> >  	struct fwnode_handle *fwnode;
> > @@ -176,6 +181,7 @@ struct max9286_priv {
> >  	/* The initial reverse control channel amplitude. */
> >  	u32 init_rev_chan_mv;
> >  	u32 rev_chan_mv;
> > +	u8 i2c_mstbt;
> >
> >  	struct v4l2_ctrl_handler ctrls;
> >  	struct v4l2_ctrl *pixelrate_ctrl;
> > @@ -250,6 +256,17 @@ static const struct max9286_format_info max9286_formats[] = {
> >  	},
> >  };
> >
> > +static const struct max9286_i2c_speed max9286_i2c_speeds[] = {
> > +	{ .rate =   8470, .mstbt = MAX9286_I2CMSTBT_8KBPS },
> > +	{ .rate =  28300, .mstbt = MAX9286_I2CMSTBT_28KBPS },
> > +	{ .rate =  84700, .mstbt = MAX9286_I2CMSTBT_84KBPS },
> > +	{ .rate = 105000, .mstbt = MAX9286_I2CMSTBT_105KBPS },
> > +	{ .rate = 173000, .mstbt = MAX9286_I2CMSTBT_173KBPS },
> > +	{ .rate = 339000, .mstbt = MAX9286_I2CMSTBT_339KBPS },
> > +	{ .rate = 533000, .mstbt = MAX9286_I2CMSTBT_533KBPS },
> > +	{ .rate = 837000, .mstbt = MAX9286_I2CMSTBT_837KBPS },
> > +};
> > +
> >  /* -----------------------------------------------------------------------------
> >   * I2C IO
> >   */
> > @@ -370,7 +387,7 @@ static int max9286_i2c_mux_init(struct max9286_priv *priv)
> >  static void max9286_configure_i2c(struct max9286_priv *priv, bool localack)
> >  {
> >  	u8 config = MAX9286_I2CSLVSH_469NS_234NS | MAX9286_I2CSLVTO_1024US |
> 
> Does the 'slave remote timeout' need to be changed according to speed
> as well ?

Possibly, but the documentation doesn't tell how, and the current values
for the setup/hold times and the timeout work fine in my setup, so I
haven't changed them.

> > -		    MAX9286_I2CMSTBT_105KBPS;
> > +		    priv->i2c_mstbt;
> >
> >  	if (localack)
> >  		config |= MAX9286_I2CLOCACK;
> > @@ -1320,6 +1337,8 @@ static int max9286_parse_dt(struct max9286_priv *priv)
> >  	struct device_node *node = NULL;
> >  	unsigned int i2c_mux_mask = 0;
> >  	u32 reverse_channel_microvolt;
> > +	u32 i2c_clk_freq = 105000;
> > +	unsigned int i;
> >
> >  	/* Balance the of_node_put() performed by of_find_node_by_name(). */
> >  	of_node_get(dev->of_node);
> > @@ -1410,6 +1429,23 @@ static int max9286_parse_dt(struct max9286_priv *priv)
> >  	}
> >  	of_node_put(node);
> >
> > +	of_property_read_u32(dev->of_node, "maxim,i2c-clock-frequency",
> > +			     &i2c_clk_freq);
> > +	for (i = 0; i < ARRAY_SIZE(max9286_i2c_speeds); ++i) {
> > +		const struct max9286_i2c_speed *speed = &max9286_i2c_speeds[i];
> > +
> > +		if (speed->rate == i2c_clk_freq) {
> > +			priv->i2c_mstbt = speed->mstbt;
> > +			break;
> > +		}
> > +	}
> > +
> > +	if (i == ARRAY_SIZE(max9286_i2c_speeds)) {
> > +		dev_err(dev, "Invalid %s value %u\n",
> > +			"maxim,i2c-clock-frequency", i2c_clk_freq);
> > +		return -EINVAL;
> > +	}
> > +
> 
> I never got a real answer to this question in years: should we assume
> dts are correct or should we validate them ?

That's a very good question :-) Given the DT-is-an-ABI dogma, I tend to
do validation in drivers, to avoid accepting incorrect device trees that
would work by chance and find myself unable to fix the driver later.

> >  	/*
> >  	 * Parse the initial value of the reverse channel amplitude from
> >  	 * the firmware interface and convert it to millivolts.
> > @@ -1484,10 +1520,16 @@ static int max9286_probe(struct i2c_client *client)
> >  	priv->client = client;
> >  	i2c_set_clientdata(client, priv);
> >
> > +	ret = max9286_parse_dt(priv);
> 
> Any reason why moving this so up ? Doing so just before i2c_config()
> would be enough ?

Just to avoid having to move it up again in the future if we add more
parameters to the device tree that would be needed before
max9286_configure_i2c().

> > +	if (ret)
> > +		goto err_cleanup_dt;
> > +
> >  	priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable",
> >  						   GPIOD_OUT_HIGH);
> > -	if (IS_ERR(priv->gpiod_pwdn))
> > -		return PTR_ERR(priv->gpiod_pwdn);
> > +	if (IS_ERR(priv->gpiod_pwdn)) {
> > +		ret = PTR_ERR(priv->gpiod_pwdn);
> > +		goto err_cleanup_dt;
> > +	}
> >
> >  	gpiod_set_consumer_name(priv->gpiod_pwdn, "max9286-pwdn");
> >  	gpiod_set_value_cansleep(priv->gpiod_pwdn, 1);
> > @@ -1514,10 +1556,6 @@ static int max9286_probe(struct i2c_client *client)
> >  	if (ret)
> >  		goto err_powerdown;
> >
> > -	ret = max9286_parse_dt(priv);
> > -	if (ret)
> > -		goto err_cleanup_dt;
> > -
> >  	ret = max9286_get_poc_supplies(priv);
> >  	if (ret)
> >  		goto err_cleanup_dt;
> > @@ -1528,10 +1566,10 @@ static int max9286_probe(struct i2c_client *client)
> >
> >  	return 0;
> >
> > -err_cleanup_dt:
> > -	max9286_cleanup_dt(priv);
> >  err_powerdown:
> >  	gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
> > +err_cleanup_dt:
> > +	max9286_cleanup_dt(priv);
> >
> >  	return ret;
> >  }

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 10/11] media: i2c: max9286: Configure bus width from device tree
  2022-01-09 10:56   ` Jacopo Mondi
@ 2022-01-09 23:32     ` Laurent Pinchart
  0 siblings, 0 replies; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-09 23:32 UTC (permalink / raw)
  To: Jacopo Mondi
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Hi Jacopo,

On Sun, Jan 09, 2022 at 11:56:34AM +0100, Jacopo Mondi wrote:
> On Sat, Jan 01, 2022 at 08:28:05PM +0200, Laurent Pinchart wrote:
> > The GMSL serial data bus width is normally selected through the BWS pin.
> > On some systems, the pin may not be wired to the correct value. Support
> > overriding the bus width by software, using the value specified in the
> > device tree.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> > ---
> >  drivers/media/i2c/max9286.c | 36 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 36 insertions(+)
> >
> > diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> > index d88a4d8e63ab..07ebb01640a1 100644
> > --- a/drivers/media/i2c/max9286.c
> > +++ b/drivers/media/i2c/max9286.c
> > @@ -90,6 +90,11 @@
> >  /* Register 0x1b */
> >  #define MAX9286_SWITCHIN(n)		(1 << ((n) + 4))
> >  #define MAX9286_ENEQ(n)			(1 << (n))
> > +/* Register 0x1c */
> > +#define MAX9286_HIGHIMM(n)		BIT((n) + 4)
> > +#define MAX9286_I2CSEL			BIT(2)
> > +#define MAX9286_HIBW			BIT(1)
> > +#define MAX9286_BWS			BIT(0)
> >  /* Register 0x27 */
> >  #define MAX9286_LOCKED			BIT(7)
> >  /* Register 0x31 */
> > @@ -182,6 +187,7 @@ struct max9286_priv {
> >  	u32 init_rev_chan_mv;
> >  	u32 rev_chan_mv;
> >  	u8 i2c_mstbt;
> > +	u32 bus_width;
> >
> >  	struct v4l2_ctrl_handler ctrls;
> >  	struct v4l2_ctrl *pixelrate_ctrl;
> > @@ -1159,6 +1165,23 @@ static int max9286_setup(struct max9286_priv *priv)
> >  	max9286_set_video_format(priv, &max9286_default_format);
> >  	max9286_set_fsync_period(priv);
> >
> > +	if (priv->bus_width) {
> > +		int val;
> > +
> > +		val = max9286_read(priv, 0x1c);
> > +		if (val < 0)
> > +			return val;
> > +
> > +		val &= ~(MAX9286_HIBW | MAX9286_BWS);
> > +
> > +		if (priv->bus_width == 27)
> > +			val |= MAX9286_HIBW;
> > +		else if (priv->bus_width == 32)
> > +			val |= MAX9286_BWS;
> > +
> > +		max9286_write(priv, 0x1c, val);
> > +	}
> > +
> >  	/*
> >  	 * The overlap window seems to provide additional validation by tracking
> >  	 * the delay between vsync and frame sync, generating an error if the
> > @@ -1429,6 +1452,19 @@ static int max9286_parse_dt(struct max9286_priv *priv)
> >  	}
> >  	of_node_put(node);
> >
> > +	of_property_read_u32(dev->of_node, "maxim,bus-width", &priv->bus_width);
> > +	switch (priv->bus_width) {
> > +	case 0:
> 
> Can you add a comment that in this case we rely on HW configuration ?
> Looking at this with the above function in the same patch makes it
> clear, but it might get lost when merged.

I'll add

		/*
		 * The property isn't specified in the device tree, the driver
		 * will keep the default value selected by the BWS pin.
		 */

> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> 
> > +	case 24:
> > +	case 27:
> > +	case 32:
> > +		break;
> > +	default:
> > +		dev_err(dev, "Invalid %s value %u\n", "maxim,bus-width",
> > +			priv->bus_width);
> > +		return -EINVAL;
> > +	}
> > +
> >  	of_property_read_u32(dev->of_node, "maxim,i2c-clock-frequency",
> >  			     &i2c_clk_freq);
> >  	for (i = 0; i < ARRAY_SIZE(max9286_i2c_speeds); ++i) {

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 08/11] media: i2c: max9286: Define macros for all bits of register 0x15
  2022-01-09 23:21     ` Laurent Pinchart
@ 2022-01-10 10:37       ` Sergey Shtylyov
  2022-01-10 11:32         ` Laurent Pinchart
  0 siblings, 1 reply; 37+ messages in thread
From: Sergey Shtylyov @ 2022-01-10 10:37 UTC (permalink / raw)
  To: Laurent Pinchart, Jacopo Mondi
  Cc: linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Hello!

On 1/10/22 2:21 AM, Laurent Pinchart wrote:

>>> Macros are easier to read than numerical values.
>>>
>>> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
>>> ---
>>>  drivers/media/i2c/max9286.c | 27 ++++++++++++++++++---------
>>>  1 file changed, 18 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
>>> index 24c2bf4fda53..4b69bd036ca6 100644
>>> --- a/drivers/media/i2c/max9286.c
>>> +++ b/drivers/media/i2c/max9286.c
[...]
>>> @@ -810,13 +815,17 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
>>>  		}
>>>
>>>  		/*
>>> -		 * Enable CSI output, VC set according to link number.
>>> -		 * Bit 7 must be set (chip manual says it's 0 and reserved).
>>> +		 * Configure the CSI-2 output to line interleaved mode (W x (N
>>> +		 * x H), as opposed to the (N x W) x H mode that outputs the
>>> +		 * images stitched side-by-side) and enable it.
>>>  		 */
>>> -		max9286_write(priv, 0x15, 0x80 | MAX9286_VCTYPE |
>>> -			      MAX9286_CSIOUTEN | MAX9286_0X15_RESV);
>>> +		max9286_write(priv, 0x15, MAX9286_CSI_IMAGE_TYP | MAX9286_VCTYPE |
>>> +			      MAX9286_CSIOUTEN | MAX9286_EN_CCBSYB_CLK_STR |
>>> +			      MAX9286_EN_GPI_CCBSYB);
>>>  	} else {
>>> -		max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
>>> +		max9286_write(priv, 0x15, MAX9286_VCTYPE |
>>> +			      MAX9286_EN_CCBSYB_CLK_STR |
>>> +			      MAX9286_EN_GPI_CCBSYB);
>>
>> Probably fits better on two lines only.
> 
> That would be over the 80 columns limit, which is a soft limit now, but
> still often requested by reviewers (including myself in quite a few
> cases :-)).

    The new limit is 100 columns, not 80. :-)

[...]

MBR, Sergey

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

* Re: [PATCH v2 08/11] media: i2c: max9286: Define macros for all bits of register 0x15
  2022-01-10 10:37       ` Sergey Shtylyov
@ 2022-01-10 11:32         ` Laurent Pinchart
  0 siblings, 0 replies; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-10 11:32 UTC (permalink / raw)
  To: Sergey Shtylyov
  Cc: Jacopo Mondi, linux-media, linux-renesas-soc, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan

Hi Sergey,

On Mon, Jan 10, 2022 at 01:37:51PM +0300, Sergey Shtylyov wrote:
> Hello!
> 
> On 1/10/22 2:21 AM, Laurent Pinchart wrote:
> 
> >>> Macros are easier to read than numerical values.
> >>>
> >>> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> >>> ---
> >>>  drivers/media/i2c/max9286.c | 27 ++++++++++++++++++---------
> >>>  1 file changed, 18 insertions(+), 9 deletions(-)
> >>>
> >>> diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
> >>> index 24c2bf4fda53..4b69bd036ca6 100644
> >>> --- a/drivers/media/i2c/max9286.c
> >>> +++ b/drivers/media/i2c/max9286.c
> [...]
> >>> @@ -810,13 +815,17 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
> >>>  		}
> >>>
> >>>  		/*
> >>> -		 * Enable CSI output, VC set according to link number.
> >>> -		 * Bit 7 must be set (chip manual says it's 0 and reserved).
> >>> +		 * Configure the CSI-2 output to line interleaved mode (W x (N
> >>> +		 * x H), as opposed to the (N x W) x H mode that outputs the
> >>> +		 * images stitched side-by-side) and enable it.
> >>>  		 */
> >>> -		max9286_write(priv, 0x15, 0x80 | MAX9286_VCTYPE |
> >>> -			      MAX9286_CSIOUTEN | MAX9286_0X15_RESV);
> >>> +		max9286_write(priv, 0x15, MAX9286_CSI_IMAGE_TYP | MAX9286_VCTYPE |
> >>> +			      MAX9286_CSIOUTEN | MAX9286_EN_CCBSYB_CLK_STR |
> >>> +			      MAX9286_EN_GPI_CCBSYB);
> >>>  	} else {
> >>> -		max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
> >>> +		max9286_write(priv, 0x15, MAX9286_VCTYPE |
> >>> +			      MAX9286_EN_CCBSYB_CLK_STR |
> >>> +			      MAX9286_EN_GPI_CCBSYB);
> >>
> >> Probably fits better on two lines only.
> > 
> > That would be over the 80 columns limit, which is a soft limit now, but
> > still often requested by reviewers (including myself in quite a few
> > cases :-)).
> 
>     The new limit is 100 columns, not 80. :-)

That's the new hard limit, yes :-) I do occasionally write lines wider
than 80 columns and am often asked to change that. In this specific case
it doesn't matter much to me, I'll happily pick whatever option
reviewers will want to give me a Reviewed-by as both are equally
readable for me.

> [...]

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH v2 01/11] dt-bindings: media: i2c: max9286: Add support for per-port supplies
  2022-01-01 18:27 ` [PATCH v2 01/11] dt-bindings: media: i2c: max9286: Add support for per-port supplies Laurent Pinchart
  2022-01-09 11:48   ` Jacopo Mondi
@ 2022-01-10 20:47   ` Rob Herring
  1 sibling, 0 replies; 37+ messages in thread
From: Rob Herring @ 2022-01-10 20:47 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mark Brown, devicetree, Thomas Nizan, Liam Girdwood,
	Jacopo Mondi, Kieran Bingham, linux-media, Niklas Söderlund,
	Rob Herring, linux-renesas-soc

On Sat, 01 Jan 2022 20:27:56 +0200, Laurent Pinchart wrote:
> Power supplies for the ports can be controlled per port depending on the
> hardware design. Support per-port supplies in the DT bindings, mutually
> exclusive with the global supply.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
> Changes since v1:
> 
> - Simplify mutual exclusion condition
> ---
>  .../bindings/media/i2c/maxim,max9286.yaml          | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
> 

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

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

* Re: [PATCH v2 03/11] dt-bindings: media: i2c: max9286: Add property to select bus width
  2022-01-01 18:27 ` [PATCH v2 03/11] dt-bindings: media: i2c: max9286: Add property to select bus width Laurent Pinchart
  2022-01-09 11:47   ` Jacopo Mondi
@ 2022-01-10 20:53   ` Rob Herring
  2022-01-10 21:24   ` [PATCH v2.1 " Laurent Pinchart
  2 siblings, 0 replies; 37+ messages in thread
From: Rob Herring @ 2022-01-10 20:53 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-media, linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Thomas Nizan, devicetree

On Sat, Jan 01, 2022 at 08:27:58PM +0200, Laurent Pinchart wrote:
> The GMSL serial data bus width is normally selected by the BWS pin, but
> it can also be configured by software. Add a DT property that allows
> overriding the value of the BWS-selected bus width to support systems
> whose BWS pin doesn't result in the correct value.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  .../devicetree/bindings/media/i2c/maxim,max9286.yaml       | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> index 5d3e99027a79..123e98cdb7b6 100644
> --- a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
> @@ -50,6 +50,13 @@ properties:
>    '#gpio-cells':
>      const: 2
>  
> +  maxim,bus-width:

Needs a $ref to a type.

> +    enum: [ 24, 27, 32 ]
> +    description: |
> +      The GMSL serial data bus width. This setting is normally controlled by
> +      the BWS pin, but may be overridden with this property. The value must
> +      match the configuration of the remote serializers.
> +
>    maxim,i2c-clock-frequency:
>      enum: [ 8470, 28300, 84700, 105000, 173000, 339000, 533000, 837000 ]
>      default: 105000
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> 

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

* [PATCH v2.1 03/11] dt-bindings: media: i2c: max9286: Add property to select bus width
  2022-01-01 18:27 ` [PATCH v2 03/11] dt-bindings: media: i2c: max9286: Add property to select bus width Laurent Pinchart
  2022-01-09 11:47   ` Jacopo Mondi
  2022-01-10 20:53   ` Rob Herring
@ 2022-01-10 21:24   ` Laurent Pinchart
  2022-01-22  0:28     ` Rob Herring
  2 siblings, 1 reply; 37+ messages in thread
From: Laurent Pinchart @ 2022-01-10 21:24 UTC (permalink / raw)
  To: linux-media
  Cc: linux-renesas-soc, Jacopo Mondi, Kieran Bingham,
	Niklas Söderlund, Rob Herring, Thomas Nizan, devicetree

The GMSL serial data bus width is normally selected by the BWS pin, but
it can also be configured by software. Add a DT property that allows
overriding the value of the BWS-selected bus width to support systems
whose BWS pin doesn't result in the correct value.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
Changes since v2:

- Specify the property type
---
 .../devicetree/bindings/media/i2c/maxim,max9286.yaml      | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
index 438381eb3cde..c6d92f51aa5a 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
@@ -50,6 +50,14 @@ properties:
   '#gpio-cells':
     const: 2
 
+  maxim,bus-width:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [ 24, 27, 32 ]
+    description: |
+      The GMSL serial data bus width. This setting is normally controlled by
+      the BWS pin, but may be overridden with this property. The value must
+      match the configuration of the remote serializers.
+
   maxim,i2c-remote-bus-hz:
     $ref: /schemas/types.yaml#/definitions/uint32
     enum: [ 8470, 28300, 84700, 105000, 173000, 339000, 533000, 837000 ]
-- 
Regards,

Laurent Pinchart


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

* Re: [PATCH v2.1 03/11] dt-bindings: media: i2c: max9286: Add property to select bus width
  2022-01-10 21:24   ` [PATCH v2.1 " Laurent Pinchart
@ 2022-01-22  0:28     ` Rob Herring
  0 siblings, 0 replies; 37+ messages in thread
From: Rob Herring @ 2022-01-22  0:28 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: devicetree, Rob Herring, Thomas Nizan, Niklas Söderlund,
	linux-media, Jacopo Mondi, linux-renesas-soc, Kieran Bingham

On Mon, 10 Jan 2022 23:24:46 +0200, Laurent Pinchart wrote:
> The GMSL serial data bus width is normally selected by the BWS pin, but
> it can also be configured by software. Add a DT property that allows
> overriding the value of the BWS-selected bus width to support systems
> whose BWS pin doesn't result in the correct value.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
> Changes since v2:
> 
> - Specify the property type
> ---
>  .../devicetree/bindings/media/i2c/maxim,max9286.yaml      | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 

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

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

end of thread, other threads:[~2022-01-22  0:28 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-01 18:27 [PATCH v2 00/11] media: i2c: max9286: Small new features Laurent Pinchart
2022-01-01 18:27 ` [PATCH v2 01/11] dt-bindings: media: i2c: max9286: Add support for per-port supplies Laurent Pinchart
2022-01-09 11:48   ` Jacopo Mondi
2022-01-10 20:47   ` Rob Herring
2022-01-01 18:27 ` [PATCH v2 02/11] dt-bindings: media: i2c: max9286: Add property to select I2C speed Laurent Pinchart
2022-01-01 22:01   ` Rob Herring
2022-01-04 15:56   ` Rob Herring
2022-01-01 18:27 ` [PATCH v2 03/11] dt-bindings: media: i2c: max9286: Add property to select bus width Laurent Pinchart
2022-01-09 11:47   ` Jacopo Mondi
2022-01-10 20:53   ` Rob Herring
2022-01-10 21:24   ` [PATCH v2.1 " Laurent Pinchart
2022-01-22  0:28     ` Rob Herring
2022-01-01 18:27 ` [PATCH v2 04/11] media: i2c: max9286: Add support for port regulators Laurent Pinchart
2022-01-09 10:04   ` Jacopo Mondi
2022-01-09 23:16     ` Laurent Pinchart
2022-01-01 18:28 ` [PATCH v2 05/11] media: i2c: max9286: Support manual framesync operation Laurent Pinchart
2022-01-09 10:26   ` Jacopo Mondi
2022-01-01 18:28 ` [PATCH v2 06/11] media: i2c: max9286: Rename MAX9286_DATATYPE_RAW11 to RAW12 Laurent Pinchart
2022-01-09 10:26   ` Jacopo Mondi
2022-01-01 18:28 ` [PATCH v2 07/11] media: i2c: max9286: Support 12-bit raw bayer formats Laurent Pinchart
2022-01-09 10:34   ` Jacopo Mondi
2022-01-09 23:19     ` Laurent Pinchart
2022-01-01 18:28 ` [PATCH v2 08/11] media: i2c: max9286: Define macros for all bits of register 0x15 Laurent Pinchart
2022-01-09 10:37   ` Jacopo Mondi
2022-01-09 23:21     ` Laurent Pinchart
2022-01-10 10:37       ` Sergey Shtylyov
2022-01-10 11:32         ` Laurent Pinchart
2022-01-01 18:28 ` [PATCH v2 09/11] media: i2c: max9286: Configure remote I2C speed from device tree Laurent Pinchart
2022-01-09 10:43   ` Jacopo Mondi
2022-01-09 23:29     ` Laurent Pinchart
2022-01-01 18:28 ` [PATCH v2 10/11] media: i2c: max9286: Configure bus width " Laurent Pinchart
2022-01-09 10:56   ` Jacopo Mondi
2022-01-09 23:32     ` Laurent Pinchart
2022-01-01 18:28 ` [PATCH v2 11/11] media: i2c: max9286: Select HS as data enable signal Laurent Pinchart
2022-01-09 11:42   ` Jacopo Mondi
2022-01-01 23:26 ` [PATCH v2 12/11] media: i2c: max9286: Print power-up GMSL link configuration Laurent Pinchart
2022-01-09 11:44   ` 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.