summaryrefslogtreecommitdiffstats
path: root/drivers/usb/imx/imx-usb-phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/imx/imx-usb-phy.c')
-rw-r--r--drivers/usb/imx/imx-usb-phy.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/drivers/usb/imx/imx-usb-phy.c b/drivers/usb/imx/imx-usb-phy.c
index d4562285c0..70bf292f80 100644
--- a/drivers/usb/imx/imx-usb-phy.c
+++ b/drivers/usb/imx/imx-usb-phy.c
@@ -1,15 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2013 Sascha Hauer <s.hauer@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
*/
#include <common.h>
@@ -19,7 +10,7 @@
#include <errno.h>
#include <driver.h>
#include <malloc.h>
-#include <usb/phy.h>
+#include <linux/usb/phy.h>
#include <linux/phy/phy.h>
#include <linux/clk.h>
#include <linux/err.h>
@@ -37,9 +28,12 @@
#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1)
#define ANADIG_USB1_CHRG_DETECT_SET 0x1b4
-#define ANADIG_USB2_CHRG_DETECT_SET 0x214
#define ANADIG_USB1_CHRG_DETECT_EN_B BIT(20)
#define ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B BIT(19)
+#define ANADIG_USB1_VBUS_DETECT_STAT 0x1c0
+#define ANADIG_USB1_VBUS_DETECT_STAT_VBUS_VALID BIT(3)
+#define ANADIG_USB2_CHRG_DETECT_SET 0x214
+#define ANADIG_USB2_VBUS_DETECT_STAT 0x220
struct imx_usbphy {
struct usb_phy usb_phy;
@@ -49,6 +43,8 @@ struct imx_usbphy {
struct clk *clk;
struct phy_provider *provider;
int port_id;
+
+ unsigned int vbus_valid;
};
static int imx_usbphy_phy_init(struct phy *phy)
@@ -57,6 +53,7 @@ static int imx_usbphy_phy_init(struct phy *phy)
int ret;
clk_enable(imxphy->clk);
+ mdelay(1);
ret = stmp_reset_block(imxphy->base + HW_USBPHY_CTRL, false);
if (ret)
@@ -111,7 +108,7 @@ static int imx_usbphy_notify_disconnect(struct usb_phy *phy,
return 0;
}
-static struct phy *imx_usbphy_xlate(struct device_d *dev,
+static struct phy *imx_usbphy_xlate(struct device *dev,
struct of_phandle_args *args)
{
struct imx_usbphy *imxphy = dev->priv;
@@ -131,10 +128,25 @@ static const struct phy_ops imx_phy_ops = {
.to_usbphy = imx_usbphy_to_usbphy,
};
-static int imx_usbphy_probe(struct device_d *dev)
+static int imx_usbphy_get_vbus_state(struct param_d *p, void *priv)
+{
+ struct imx_usbphy *imxphy = priv;
+ unsigned int reg, val;
+
+ reg = imxphy->port_id ?
+ ANADIG_USB1_VBUS_DETECT_STAT :
+ ANADIG_USB2_VBUS_DETECT_STAT;
+ val = readl(imxphy->anatop + reg);
+
+ imxphy->vbus_valid = !!(val & ANADIG_USB1_VBUS_DETECT_STAT_VBUS_VALID);
+
+ return 0;
+}
+
+static int imx_usbphy_probe(struct device *dev)
{
struct resource *iores;
- struct device_node *np = dev->device_node;
+ struct device_node *np = dev->of_node;
int ret;
struct imx_usbphy *imxphy;
@@ -153,6 +165,15 @@ static int imx_usbphy_probe(struct device_d *dev)
ret = PTR_ERR_OR_ZERO(imxphy->anatop);
if (ret)
goto err_free;
+
+ /*
+ * This is useful in case of usb-otg = device. In host case
+ * it isn't that useful since we are the supplier of the vbus
+ * signal.
+ */
+ dev_add_param_bool(dev, "vbus_valid", param_set_readonly,
+ imx_usbphy_get_vbus_state,
+ &imxphy->vbus_valid, imxphy);
}
iores = dev_request_mem_resource(dev, 0);
@@ -164,7 +185,7 @@ static int imx_usbphy_probe(struct device_d *dev)
imxphy->clk = clk_get(dev, NULL);
if (IS_ERR(imxphy->clk)) {
- dev_err(dev, "could not get clk: %s\n", strerrorp(imxphy->clk));
+ dev_err(dev, "could not get clk: %pe\n", imxphy->clk);
ret = PTR_ERR(imxphy->clk);
goto err_clk;
}
@@ -174,7 +195,7 @@ static int imx_usbphy_probe(struct device_d *dev)
imxphy->usb_phy.dev = dev;
imxphy->usb_phy.notify_connect = imx_usbphy_notify_connect;
imxphy->usb_phy.notify_disconnect = imx_usbphy_notify_disconnect;
- imxphy->phy = phy_create(dev, NULL, &imx_phy_ops, NULL);
+ imxphy->phy = phy_create(dev, NULL, &imx_phy_ops);
if (IS_ERR(imxphy->phy)) {
ret = PTR_ERR(imxphy->phy);
goto err_clk;
@@ -208,15 +229,12 @@ static __maybe_unused struct of_device_id imx_usbphy_dt_ids[] = {
/* sentinel */
},
};
+MODULE_DEVICE_TABLE(of, imx_usbphy_dt_ids);
-static struct driver_d imx_usbphy_driver = {
+static struct driver imx_usbphy_driver = {
.name = "imx-usb-phy",
.probe = imx_usbphy_probe,
.of_compatible = DRV_OF_COMPAT(imx_usbphy_dt_ids),
};
-static int imx_usbphy_init(void)
-{
- return platform_driver_register(&imx_usbphy_driver);
-}
-fs_initcall(imx_usbphy_init);
+fs_platform_driver(imx_usbphy_driver);