diff options
Diffstat (limited to 'drivers/usb/imx/imx-usb-phy.c')
-rw-r--r-- | drivers/usb/imx/imx-usb-phy.c | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/drivers/usb/imx/imx-usb-phy.c b/drivers/usb/imx/imx-usb-phy.c index 069dddcacb..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; } @@ -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); |