#include <dt-bindings/phy/phy.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/mux/consumer.h>
 #define WIZ_SERDES_CTRL                0x404
 #define WIZ_SERDES_TOP_CTRL    0x408
 #define WIZ_SERDES_RST         0x40c
+#define WIZ_SERDES_TYPEC       0x410
 #define WIZ_LANECTL(n)         (0x480 + (0x40 * (n)))
 
 #define WIZ_MAX_LANES          4
 #define WIZ_DIV_NUM_CLOCKS_16G 2
 #define WIZ_DIV_NUM_CLOCKS_10G 1
 
+#define WIZ_SERDES_TYPEC_LN10_SWAP     BIT(30)
+
 enum wiz_lane_standard_mode {
        LANE_MODE_GEN1,
        LANE_MODE_GEN2,
        REG_FIELD(WIZ_LANECTL(3), 24, 25),
 };
 
+static const struct reg_field typec_ln10_swap =
+                                       REG_FIELD(WIZ_SERDES_TYPEC, 30, 30);
+
 struct wiz_clk_mux {
        struct clk_hw           hw;
        struct regmap_field     *field;
        J721E_WIZ_10G,
 };
 
+#define WIZ_TYPEC_DIR_DEBOUNCE_MIN     100     /* ms */
+#define WIZ_TYPEC_DIR_DEBOUNCE_MAX     1000
+
 struct wiz {
        struct regmap           *regmap;
        enum wiz_type           type;
        struct regmap_field     *pma_cmn_refclk_mode;
        struct regmap_field     *pma_cmn_refclk_dig_div;
        struct regmap_field     *pma_cmn_refclk1_dig_div;
+       struct regmap_field     *typec_ln10_swap;
 
        struct device           *dev;
        u32                     num_lanes;
        struct platform_device  *serdes_pdev;
        struct reset_controller_dev wiz_phy_reset_dev;
+       struct gpio_desc        *gpio_typec_dir;
+       int                     typec_dir_delay;
 };
 
 static int wiz_reset(struct wiz *wiz)
                }
        }
 
+       wiz->typec_ln10_swap = devm_regmap_field_alloc(dev, regmap,
+                                                      typec_ln10_swap);
+       if (IS_ERR(wiz->typec_ln10_swap)) {
+               dev_err(dev, "LN10_SWAP reg field init failed\n");
+               return PTR_ERR(wiz->typec_ln10_swap);
+       }
+
        return 0;
 }
 
        struct wiz *wiz = dev_get_drvdata(dev);
        int ret;
 
+       /* if typec-dir gpio was specified, set LN10 SWAP bit based on that */
+       if (id == 0 && wiz->gpio_typec_dir) {
+               if (wiz->typec_dir_delay)
+                       msleep_interruptible(wiz->typec_dir_delay);
+
+               if (gpiod_get_value_cansleep(wiz->gpio_typec_dir))
+                       regmap_field_write(wiz->typec_ln10_swap, 1);
+               else
+                       regmap_field_write(wiz->typec_ln10_swap, 0);
+       }
+
        if (id == 0) {
                ret = regmap_field_write(wiz->phy_reset_n, true);
                return ret;
                goto err_addr_to_resource;
        }
 
+       wiz->gpio_typec_dir = devm_gpiod_get_optional(dev, "typec-dir",
+                                                     GPIOD_IN);
+       if (IS_ERR(wiz->gpio_typec_dir)) {
+               ret = PTR_ERR(wiz->gpio_typec_dir);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to request typec-dir gpio: %d\n",
+                               ret);
+               goto err_addr_to_resource;
+       }
+
+       if (wiz->gpio_typec_dir) {
+               ret = of_property_read_u32(node, "typec-dir-debounce-ms",
+                                          &wiz->typec_dir_delay);
+               if (ret && ret != -EINVAL) {
+                       dev_err(dev, "Invalid typec-dir-debounce property\n");
+                       goto err_addr_to_resource;
+               }
+
+               /* use min. debounce from Type-C spec if not provided in DT  */
+               if (ret == -EINVAL)
+                       wiz->typec_dir_delay = WIZ_TYPEC_DIR_DEBOUNCE_MIN;
+
+               if (wiz->typec_dir_delay < WIZ_TYPEC_DIR_DEBOUNCE_MIN ||
+                   wiz->typec_dir_delay > WIZ_TYPEC_DIR_DEBOUNCE_MAX) {
+                       dev_err(dev, "Invalid typec-dir-debounce property\n");
+                       goto err_addr_to_resource;
+               }
+       }
+
        wiz->dev = dev;
        wiz->regmap = regmap;
        wiz->num_lanes = num_lanes;