The bridge chip has an enable gpio which of course can enable/disable
the bridge. Most the time this gpio is connected directly to the host
but sometimes it is connected to a reset controller chip and the host
controlls the reset controller chip instead. This commit adds the
support to handle that.

Therefore we need either the reset controller or a gpio to be present
and valid. The behaviour is changed in that way that a gpio or a reset
controller have to be successfully requested else the driver probe
fails, like the current behaviour.

Signed-off-by: Marco Felsch <m.fel...@pengutronix.de>
---
 drivers/gpu/drm/bridge/ti-sn65dsi83.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c 
b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
index 3c1dc16985b5..7b232a4f8bcb 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -35,6 +35,7 @@
 #include <linux/property.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/reset.h>
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_bridge.h>
@@ -146,6 +147,7 @@ struct sn65dsi83 {
        struct drm_bridge               *panel_bridge;
        struct gpio_desc                *enable_gpio;
        struct regulator                *vcc;
+       struct reset_control            *reset;
        int                             dsi_lanes;
        bool                            lvds_dual_link;
        bool                            lvds_dual_link_even_odd_swap;
@@ -350,6 +352,7 @@ static void sn65dsi83_atomic_enable(struct drm_bridge 
*bridge,
 
        /* Deassert reset */
        gpiod_set_value(ctx->enable_gpio, 1);
+       reset_control_deassert(ctx->reset);
        usleep_range(1000, 1100);
 
        /* Get the LVDS format from the bridge state. */
@@ -511,6 +514,7 @@ static void sn65dsi83_atomic_disable(struct drm_bridge 
*bridge,
 
        /* Put the chip in reset, pull EN line low, and assure 10ms reset low 
timing. */
        gpiod_set_value(ctx->enable_gpio, 0);
+       reset_control_assert(ctx->reset);
        usleep_range(10000, 11000);
 
        ret = regulator_disable(ctx->vcc);
@@ -760,6 +764,13 @@ static int sn65dsi83_probe(struct i2c_client *client,
                return dev_err_probe(ctx->dev, PTR_ERR(ctx->enable_gpio),
                                     "Failed to get GPIO\n");
 
+       /* Or use a external reset chip to do so */
+       ctx->reset = devm_reset_control_get_optional(ctx->dev, NULL);
+       if (IS_ERR(ctx->reset))
+               return dev_err_probe(ctx->dev, PTR_ERR(ctx->reset),
+                                    "Failed to get reset\n");
+       reset_control_assert(ctx->reset);
+
        usleep_range(10000, 11000);
 
        ret = sn65dsi83_parse_dt(ctx, model);
-- 
2.30.2

Reply via email to