Support optional feature: bypass GPIO.

Get GPIO status in irq handler. If GPIO is active, mode_fixup would be
bypassed.

Signed-off-by: Hsin-Yi Wang <hsi...@chromium.org>
---
 drivers/gpu/drm/bridge/analogix-anx7688.c | 57 +++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix-anx7688.c 
b/drivers/gpu/drm/bridge/analogix-anx7688.c
index 5a3a2251c1c5..1d09db2cf8e9 100644
--- a/drivers/gpu/drm/bridge/analogix-anx7688.c
+++ b/drivers/gpu/drm/bridge/analogix-anx7688.c
@@ -5,11 +5,16 @@
  * Copyright 2016 Google LLC
  */
 
+#include <linux/gpio.h>
 #include <linux/i2c.h>
+#include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/of_gpio.h>
 #include <linux/regmap.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_probe_helper.h>
 
 /* Register addresses */
 #define VENDOR_ID_REG 0x00
@@ -31,6 +36,9 @@ struct anx7688 {
        struct i2c_client *client;
        struct regmap *regmap;
 
+       struct gpio_desc *gpiod_bypass;
+       int bypass;
+
        bool filter;
 };
 
@@ -49,6 +57,10 @@ static bool anx7688_bridge_mode_fixup(struct drm_bridge 
*bridge,
        int totalbw, requiredbw;
        int ret;
 
+       /* bypass anx mode fixup */
+       if (anx7688->bypass)
+               return true;
+
        if (!anx7688->filter)
                return true;
 
@@ -93,6 +105,19 @@ static const struct drm_bridge_funcs anx7688_bridge_funcs = 
{
        .mode_fixup     = anx7688_bridge_mode_fixup,
 };
 
+static irqreturn_t gpio_display_mux_det_threaded_handler(int unused, void 
*data)
+{
+       struct anx7688 *anx7688 = data;
+
+       anx7688->bypass = gpiod_get_value(anx7688->gpiod_bypass);
+       dev_dbg(&anx7688->client->dev, "Interrupt %d!\n", anx7688->bypass);
+
+       if (anx7688->bridge.dev)
+               drm_kms_helper_hotplug_event(anx7688->bridge.dev);
+
+       return IRQ_HANDLED;
+}
+
 static const struct regmap_config anx7688_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
@@ -156,6 +181,38 @@ static int anx7688_i2c_probe(struct i2c_client *client,
                         buffer[0], buffer[1]);
        }
 
+       /* Optional bypass-gpios */
+       anx7688->gpiod_bypass = devm_gpiod_get_optional(dev, "bypass",
+                                                       GPIOD_IN);
+       if (IS_ERR(anx7688->gpiod_bypass)) {
+               ret = PTR_ERR(anx7688->gpiod_bypass);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(dev, "bypass-gpios assigned failed\n");
+               return ret;
+       }
+       if (anx7688->gpiod_bypass) {
+               int irq;
+
+               irq = gpiod_to_irq(anx7688->gpiod_bypass);
+               if (irq < 0) {
+                       dev_err(dev, "Failed to get output irq %d\n", irq);
+                       return -ENODEV;
+               }
+
+               anx7688->bypass = gpiod_get_value(anx7688->gpiod_bypass);
+
+               ret = devm_request_threaded_irq(dev, irq, NULL,
+                               gpio_display_mux_det_threaded_handler,
+                               IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
+                               IRQF_ONESHOT,
+                               "gpio-display-mux-det", anx7688);
+               if (ret) {
+                       dev_err(dev,
+                               "Failed to request MUX_DET threaded irq\n");
+                       return ret;
+               }
+       }
+
        anx7688->bridge.funcs = &anx7688_bridge_funcs;
        drm_bridge_add(&anx7688->bridge);
 
-- 
2.24.0.393.g34dc348eaf-goog

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to