--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2019 BayLibre SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+#ifndef _ARCH_MESON_USB_GX_H_
+#define _ARCH_MESON_USB_GX_H_
+
+#include <generic-phy.h>
+#include <linux/usb/otg.h>
+
+/* TOFIX add set_mode to struct phy_ops */
+void phy_meson_gxl_usb2_set_mode(struct phy *phy, enum usb_dr_mode mode);
+void phy_meson_gxl_usb3_set_mode(struct phy *phy, enum usb_dr_mode mode);
+
+#endif
#include <regmap.h>
#include <power/regulator.h>
#include <clk.h>
+#include <linux/usb/otg.h>
+
+#include <asm/arch/usb-gx.h>
#include <linux/bitops.h>
#include <linux/compat.h>
udelay(RESET_COMPLETE_TIME);
}
-static void
-phy_meson_gxl_usb2_set_host_mode(struct phy_meson_gxl_usb2_priv *priv)
+void phy_meson_gxl_usb2_set_mode(struct phy *phy, enum usb_dr_mode mode)
{
+ struct udevice *dev = phy->dev;
+ struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
uint val;
regmap_read(priv->regmap, U2P_R0, &val);
- val |= U2P_R0_DM_PULLDOWN;
- val |= U2P_R0_DP_PULLDOWN;
- val &= ~U2P_R0_ID_PULLUP;
+
+ switch (mode) {
+ case USB_DR_MODE_UNKNOWN:
+ case USB_DR_MODE_HOST:
+ case USB_DR_MODE_OTG:
+ val |= U2P_R0_DM_PULLDOWN;
+ val |= U2P_R0_DP_PULLDOWN;
+ val &= ~U2P_R0_ID_PULLUP;
+ break;
+
+ case USB_DR_MODE_PERIPHERAL:
+ val &= ~U2P_R0_DM_PULLDOWN;
+ val &= ~U2P_R0_DP_PULLDOWN;
+ val |= U2P_R0_ID_PULLUP;
+ break;
+ }
+
regmap_write(priv->regmap, U2P_R0, val);
phy_meson_gxl_usb2_reset(priv);
val &= ~U2P_R0_POWER_ON_RESET;
regmap_write(priv->regmap, U2P_R0, val);
- phy_meson_gxl_usb2_set_host_mode(priv);
+ phy_meson_gxl_usb2_set_mode(phy, USB_DR_MODE_HOST);
#if CONFIG_IS_ENABLED(DM_REGULATOR)
if (priv->phy_supply) {
#include <generic-phy.h>
#include <regmap.h>
#include <clk.h>
+#include <linux/usb/otg.h>
+
+#include <asm/arch/usb-gx.h>
#include <linux/bitops.h>
#include <linux/compat.h>
#endif
};
-static int
-phy_meson_gxl_usb3_set_host_mode(struct phy_meson_gxl_usb3_priv *priv)
+void phy_meson_gxl_usb3_set_mode(struct phy *phy, enum usb_dr_mode mode)
{
+ struct udevice *dev = phy->dev;
+ struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
uint val;
- regmap_read(priv->regmap, USB_R0, &val);
- val &= ~USB_R0_U2D_ACT;
- regmap_write(priv->regmap, USB_R0, val);
-
- regmap_read(priv->regmap, USB_R4, &val);
- val &= ~USB_R4_P21_SLEEP_M0;
- regmap_write(priv->regmap, USB_R4, val);
-
- return 0;
+ switch (mode) {
+ case USB_DR_MODE_UNKNOWN:
+ case USB_DR_MODE_HOST:
+ case USB_DR_MODE_OTG:
+ regmap_read(priv->regmap, USB_R0, &val);
+ val &= ~USB_R0_U2D_ACT;
+ regmap_write(priv->regmap, USB_R0, val);
+
+ regmap_read(priv->regmap, USB_R4, &val);
+ val &= ~USB_R4_P21_SLEEP_M0;
+ regmap_write(priv->regmap, USB_R4, val);
+ break;
+
+ case USB_DR_MODE_PERIPHERAL:
+ regmap_read(priv->regmap, USB_R0, &val);
+ val |= USB_R0_U2D_ACT;
+ regmap_write(priv->regmap, USB_R0, val);
+
+ regmap_read(priv->regmap, USB_R4, &val);
+ val |= USB_R4_P21_SLEEP_M0;
+ regmap_write(priv->regmap, USB_R4, val);
+ break;
+ }
}
static int phy_meson_gxl_usb3_power_on(struct phy *phy)
val |= FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff);
regmap_write(priv->regmap, USB_R5, val);
- return phy_meson_gxl_usb3_set_host_mode(priv);
+ phy_meson_gxl_usb3_set_mode(phy, USB_DR_MODE_HOST);
+
+ return 0;
}
static int phy_meson_gxl_usb3_power_off(struct phy *phy)