2021-07-22 09:15:33

by Jacopo Mondi

[permalink] [raw]
Subject: [PATCH v6 0/8] arm64: dts: renesas: Enable GMSL on Eagle and Condor

Hello,
here we go again with the attempt to try enable GMSL for Eagle and this time
also Condor board.

v5 highlighted an issue with the integration of RDACM20 which shown failures at
start streaming time due to conflicts with i2c writes performed by the embedded
microcontroller. A new patch
- media: i2c: rdacm20: Re-program chip address earlier
is aimed to fix the issue by reducing the collision window by re-programming the
chip address earlier. All capture session I've run seems stable now.

Compared to v5 integration for the Condor board is now included.

Condor has 2 GMSL channels, something the current version of the MAX9286 driver
does not support. However the DTS integration can be upstreamed but a single
channel can be used at a time.

Support for Condor required a reword of what was called eagle-gmsl.dtsi in v5
and is now called gmsl-cameras.dtsi to expand support for the secondary GMSL
channel.

Integration of the new "maxim,gpio-poc" property required for Eagle/Condor is
fully reviewed and can be eventually fast-tracked.

The series is based on:
https://patchwork.linuxtv.org/project/linux-media/list/?series=5847
and has been tested on Eagle V3H board, while only compile tested for Condor.

Thanks
j

Jacopo Mondi (5):
dt-bindings: media: max9286: Re-indent example
dt-bindings: media: max9286: Define 'maxim,gpio-poc'
media: i2c: max9286: Use "maxim,gpio-poc" property
media: i2c: rdacm20: Re-program chip address earlier
arm64: dts: renesas: condor: Enable MAX9286

Kieran Bingham (3):
arm64: dts: renesas: eagle: Enable MAX9286
arm64: dts: renesas: Add GMSL cameras .dtsi
DNI: arm64: dts: renesas: eagle: Include eagle-gmsl

.../bindings/media/i2c/maxim,max9286.yaml | 275 +++++++++------
arch/arm64/boot/dts/renesas/gmsl-cameras.dtsi | 332 ++++++++++++++++++
.../arm64/boot/dts/renesas/r8a77970-eagle.dts | 112 ++++++
.../boot/dts/renesas/r8a77980-condor.dts | 193 ++++++++++
drivers/media/i2c/max9286.c | 125 +++++--
drivers/media/i2c/rdacm20.c | 10 +-
6 files changed, 906 insertions(+), 141 deletions(-)
create mode 100644 arch/arm64/boot/dts/renesas/gmsl-cameras.dtsi

--
2.32.0


2021-07-22 09:16:18

by Jacopo Mondi

[permalink] [raw]
Subject: [PATCH v6 3/8] media: i2c: max9286: Use "maxim,gpio-poc" property

The 'maxim,gpio-poc' property is used when the remote camera
power-over-coax is controlled by one of the MAX9286 gpio lines,
to instruct the driver about which line to use and what the line
polarity is.

Add to the max9286 driver support for parsing the newly introduced
property and use it if available in place of the usual supply, as it is
not possible to establish one as consumer of the max9286 gpio
controller.

If the new property is present, no gpio controller is registered and
'poc-supply' is ignored.

In order to maximize code re-use, break out the max9286 gpio handling
function so that they can be used by the gpio controller through the
gpio-consumer API, or directly by the driver code.

Wrap the power up and power down routines to their own function to
be able to use either the gpio line directly or the supply. This will
make it easier to control the remote camera power at run time.

Signed-off-by: Jacopo Mondi <[email protected]>
Reviewed-by: Laurent Pinchart <[email protected]>
---
drivers/media/i2c/max9286.c | 125 +++++++++++++++++++++++++++---------
1 file changed, 94 insertions(+), 31 deletions(-)

diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index 18d38db9864c..1b92d18a1f94 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -15,6 +15,7 @@
#include <linux/fwnode.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
+#include <linux/gpio/machine.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/module.h>
@@ -168,6 +169,9 @@ struct max9286_priv {
u32 init_rev_chan_mv;
u32 rev_chan_mv;

+ u32 gpio_poc;
+ u32 gpio_poc_flags;
+
struct v4l2_ctrl_handler ctrls;
struct v4l2_ctrl *pixelrate;

@@ -1041,20 +1045,27 @@ static int max9286_setup(struct max9286_priv *priv)
return 0;
}

-static void max9286_gpio_set(struct gpio_chip *chip,
- unsigned int offset, int value)
+static int max9286_gpio_set(struct max9286_priv *priv, unsigned int offset,
+ int value)
{
- struct max9286_priv *priv = gpiochip_get_data(chip);
-
if (value)
priv->gpio_state |= BIT(offset);
else
priv->gpio_state &= ~BIT(offset);

- max9286_write(priv, 0x0f, MAX9286_0X0F_RESERVED | priv->gpio_state);
+ return max9286_write(priv, 0x0f,
+ MAX9286_0X0F_RESERVED | priv->gpio_state);
+}
+
+static void max9286_gpiochip_set(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ struct max9286_priv *priv = gpiochip_get_data(chip);
+
+ max9286_gpio_set(priv, offset, value);
}

-static int max9286_gpio_get(struct gpio_chip *chip, unsigned int offset)
+static int max9286_gpiochip_get(struct gpio_chip *chip, unsigned int offset)
{
struct max9286_priv *priv = gpiochip_get_data(chip);

@@ -1074,16 +1085,81 @@ static int max9286_register_gpio(struct max9286_priv *priv)
gpio->of_node = dev->of_node;
gpio->ngpio = 2;
gpio->base = -1;
- gpio->set = max9286_gpio_set;
- gpio->get = max9286_gpio_get;
+ gpio->set = max9286_gpiochip_set;
+ gpio->get = max9286_gpiochip_get;
gpio->can_sleep = true;

+ ret = devm_gpiochip_add_data(dev, gpio, priv);
+ if (ret)
+ dev_err(dev, "Unable to create gpio_chip\n");
+
+ return ret;
+}
+
+static int max9286_parse_gpios(struct max9286_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ u32 gpio_poc[2];
+ int ret;
+
/* GPIO values default to high */
priv->gpio_state = BIT(0) | BIT(1);

- ret = devm_gpiochip_add_data(dev, gpio, priv);
+ /*
+ * Parse the "gpio-poc" vendor property. If the camera power is
+ * controlled by one of the MAX9286 gpio lines, do not register
+ * the gpio controller and ignore 'poc-supply'.
+ */
+ ret = of_property_read_u32_array(dev->of_node,
+ "maxim,gpio-poc", gpio_poc, 2);
+ if (!ret) {
+ priv->gpio_poc = gpio_poc[0];
+ priv->gpio_poc_flags = gpio_poc[1];
+ if (priv->gpio_poc > 1 ||
+ (priv->gpio_poc_flags != GPIO_ACTIVE_HIGH &&
+ priv->gpio_poc_flags != GPIO_ACTIVE_LOW)) {
+ dev_err(dev, "Invalid 'gpio-poc': (%u %u)\n",
+ priv->gpio_poc, priv->gpio_poc_flags);
+ return -EINVAL;
+ }
+
+ return 0;
+ }
+
+ ret = max9286_register_gpio(priv);
if (ret)
- dev_err(dev, "Unable to create gpio_chip\n");
+ return ret;
+
+ priv->regulator = devm_regulator_get(dev, "poc");
+ if (IS_ERR(priv->regulator)) {
+ 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);
+ }
+
+ return 0;
+}
+
+static int max9286_poc_enable(struct max9286_priv *priv, bool enable)
+{
+ int ret;
+
+ /* If "poc-gpio" is used, toggle the line and do not use regulator. */
+ if (enable)
+ ret = priv->regulator
+ ? regulator_enable(priv->regulator)
+ : max9286_gpio_set(priv, priv->gpio_poc,
+ enable ^ priv->gpio_poc_flags);
+ else
+ ret = priv->regulator
+ ? regulator_disable(priv->regulator)
+ : max9286_gpio_set(priv, priv->gpio_poc,
+ enable ^ priv->gpio_poc_flags);
+
+ if (ret < 0)
+ dev_err(&priv->client->dev, "Unable to turn PoC %s\n",
+ enable ? "on" : "off");

return ret;
}
@@ -1097,17 +1173,14 @@ static int max9286_init(struct device *dev)
client = to_i2c_client(dev);
priv = i2c_get_clientdata(client);

- /* Enable the bus power. */
- ret = regulator_enable(priv->regulator);
- if (ret < 0) {
- dev_err(&client->dev, "Unable to turn PoC on\n");
+ ret = max9286_poc_enable(priv, true);
+ if (ret)
return ret;
- }

ret = max9286_setup(priv);
if (ret) {
dev_err(dev, "Unable to setup max9286\n");
- goto err_regulator;
+ goto err_poc_disable;
}

/*
@@ -1117,7 +1190,7 @@ static int max9286_init(struct device *dev)
ret = max9286_v4l2_register(priv);
if (ret) {
dev_err(dev, "Failed to register with V4L2\n");
- goto err_regulator;
+ goto err_poc_disable;
}

ret = max9286_i2c_mux_init(priv);
@@ -1133,8 +1206,8 @@ static int max9286_init(struct device *dev)

err_v4l2_register:
max9286_v4l2_unregister(priv);
-err_regulator:
- regulator_disable(priv->regulator);
+err_poc_disable:
+ max9286_poc_enable(priv, false);

return ret;
}
@@ -1305,20 +1378,10 @@ static int max9286_probe(struct i2c_client *client)
*/
max9286_configure_i2c(priv, false);

- ret = max9286_register_gpio(priv);
+ ret = max9286_parse_gpios(priv);
if (ret)
goto err_powerdown;

- priv->regulator = devm_regulator_get(&client->dev, "poc");
- if (IS_ERR(priv->regulator)) {
- if (PTR_ERR(priv->regulator) != -EPROBE_DEFER)
- dev_err(&client->dev,
- "Unable to get PoC regulator (%ld)\n",
- PTR_ERR(priv->regulator));
- ret = PTR_ERR(priv->regulator);
- goto err_powerdown;
- }
-
ret = max9286_parse_dt(priv);
if (ret)
goto err_powerdown;
@@ -1345,7 +1408,7 @@ static int max9286_remove(struct i2c_client *client)

max9286_v4l2_unregister(priv);

- regulator_disable(priv->regulator);
+ max9286_poc_enable(priv, false);

gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);

--
2.32.0

2021-07-22 09:16:38

by Jacopo Mondi

[permalink] [raw]
Subject: [PATCH v6 6/8] arm64: dts: renesas: eagle: Enable MAX9286

From: Kieran Bingham <[email protected]>

Enable the MAX9286 GMSL deserializer on the Eagle-V3M board.

Connected cameras should be defined in a device-tree overlay or included
after these definitions.

Reviewed-by: Laurent Pinchart <[email protected]>
Signed-off-by: Kieran Bingham <[email protected]>
Signed-off-by: Jacopo Mondi <[email protected]>
---
.../arm64/boot/dts/renesas/r8a77970-eagle.dts | 104 ++++++++++++++++++
1 file changed, 104 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
index 874a7fc2730b..05e66467bc0a 100644
--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
@@ -6,6 +6,8 @@
* Copyright (C) 2017 Cogent Embedded, Inc.
*/

+#include <dt-bindings/gpio/gpio.h>
+
/dts-v1/;
#include "r8a77970.dtsi"

@@ -188,6 +190,11 @@ i2c0_pins: i2c0 {
function = "i2c0";
};

+ i2c3_pins: i2c3 {
+ groups = "i2c3_a";
+ function = "i2c3";
+ };
+
qspi0_pins: qspi0 {
groups = "qspi0_ctrl", "qspi0_data4";
function = "qspi0";
@@ -266,6 +273,103 @@ &rwdt {
status = "okay";
};

+&csi40 {
+ status = "okay";
+
+ ports {
+ port@0 {
+ csi40_in: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&max9286_out0>;
+ };
+ };
+ };
+};
+
+&i2c3 {
+ pinctrl-0 = <&i2c3_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ gmsl0: gmsl-deserializer@48 {
+ compatible = "maxim,max9286";
+ reg = <0x48>;
+
+ maxim,gpio-poc = <0 GPIO_ACTIVE_LOW>;
+ enable-gpios = <&io_expander 0 GPIO_ACTIVE_HIGH>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+
+ port@2 {
+ reg = <2>;
+ };
+
+ port@3 {
+ reg = <3>;
+ };
+
+ port@4 {
+ reg = <4>;
+ max9286_out0: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csi40_in>;
+ };
+ };
+ };
+
+ i2c-mux {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ status = "disabled";
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ status = "disabled";
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+
+ status = "disabled";
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+
+ status = "disabled";
+ };
+ };
+ };
+};
+
&scif0 {
pinctrl-0 = <&scif0_pins>;
pinctrl-names = "default";
--
2.32.0

2021-07-22 09:17:17

by Jacopo Mondi

[permalink] [raw]
Subject: [PATCH v6 8/8] DNI: arm64: dts: renesas: eagle: Include eagle-gmsl

From: Kieran Bingham <[email protected]>

Include the eagle-gmsl.dtsi to enable GMSL camera support on the
Eagle-V3M platform.

Signed-off-by: Kieran Bingham <[email protected]>
Signed-off-by: Jacopo Mondi <[email protected]>
---
arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
index 05e66467bc0a..542797288e9d 100644
--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
@@ -376,3 +376,11 @@ &scif0 {

status = "okay";
};
+
+/* FAKRA Overlay */
+#define GMSL_CAMERA_RDACM20
+#define GMSL_CAMERA_0
+#define GMSL_CAMERA_1
+#define GMSL_CAMERA_2
+#define GMSL_CAMERA_3
+#include "gmsl-cameras.dtsi"
--
2.32.0