9
0
Fork 0

usb: imx-us-phy: Convert driver to generic phy support

The generic phy layer now supports USB phys, so convert
the driver over to use it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Sascha Hauer 2016-09-29 12:53:35 +02:00
parent 068bc903c1
commit a44f222e09
5 changed files with 70 additions and 4 deletions

View File

@ -107,6 +107,8 @@ CONFIG_EEPROM_AT24=y
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_IMX=y
CONFIG_IMX_WEIM=y
CONFIG_GENERIC_PHY=y
CONFIG_USB_NOP_XCEIV=y
CONFIG_FS_EXT4=y
CONFIG_FS_TFTP=y
CONFIG_FS_NFS=y

View File

@ -177,6 +177,8 @@ CONFIG_MXS_APBH_DMA=y
CONFIG_GPIO_STMPE=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED=y
CONFIG_GENERIC_PHY=y
CONFIG_USB_NOP_XCEIV=y
CONFIG_FS_EXT4=y
CONFIG_FS_TFTP=y
CONFIG_FS_NFS=y

View File

@ -16,5 +16,4 @@ config USB_IMX_CHIPIDEA
config USB_IMX_PHY
bool
depends on ARCH_IMX
default y if ARCH_IMX6
default y if ARCH_IMX6 && GENERIC_PHY

View File

@ -26,6 +26,7 @@
#include <usb/ulpi.h>
#include <usb/fsl_usb2.h>
#include <linux/err.h>
#include <linux/phy/phy.h>
#define MXC_EHCI_PORTSC_MASK ((0xf << 28) | (1 << 25))
@ -40,6 +41,8 @@ struct imx_chipidea {
struct param_d *param_mode;
int role_registered;
struct regulator *vbus;
struct phy *phy;
struct usb_phy *usbphy;
};
static int imx_chipidea_port_init(void *drvdata)
@ -260,6 +263,23 @@ static int imx_chipidea_probe(struct device_d *dev)
if (IS_ERR(ci->vbus))
ci->vbus = NULL;
if (of_property_read_bool(dev->device_node, "fsl,usbphy")) {
ci->phy = of_phy_get_by_phandle(dev, "fsl,usbphy", 0);
if (IS_ERR(ci->phy)) {
ret = PTR_ERR(ci->phy);
dev_err(dev, "Cannot get phy: %s\n", strerror(-ret));
return ret;
} else {
ci->usbphy = phy_to_usbphy(ci->phy);
if (IS_ERR(ci->usbphy))
return PTR_ERR(ci->usbphy);
ret = phy_init(ci->phy);
if (ret)
return ret;
}
}
iores = dev_request_mem_resource(dev, 0);
if (IS_ERR(iores))
return PTR_ERR(iores);
@ -270,6 +290,7 @@ static int imx_chipidea_probe(struct device_d *dev)
ci->data.init = imx_chipidea_port_init;
ci->data.post_init = imx_chipidea_port_post_init;
ci->data.drvdata = ci;
ci->data.usbphy = ci->usbphy;
if ((ci->flags & MXC_EHCI_PORTSC_MASK) == MXC_EHCI_MODE_HSIC)
imx_chipidea_port_init(ci);

View File

@ -19,6 +19,8 @@
#include <errno.h>
#include <driver.h>
#include <malloc.h>
#include <usb/phy.h>
#include <linux/phy/phy.h>
#include <linux/clk.h>
#include <linux/err.h>
@ -33,12 +35,17 @@
#define USBPHY_CTRL_ENUTMILEVEL2 (1 << 14)
struct imx_usbphy {
struct usb_phy usb_phy;
struct phy *phy;
void __iomem *base;
struct clk *clk;
struct phy_provider *provider;
};
static int imx_usbphy_enable(struct imx_usbphy *imxphy)
static int imx_usbphy_phy_init(struct phy *phy)
{
struct imx_usbphy *imxphy = phy_get_drvdata(phy);
clk_enable(imxphy->clk);
/* reset usbphy */
@ -60,6 +67,26 @@ static int imx_usbphy_enable(struct imx_usbphy *imxphy)
return 0;
}
static struct phy *imx_usbphy_xlate(struct device_d *dev,
struct of_phandle_args *args)
{
struct imx_usbphy *imxphy = dev->priv;
return imxphy->phy;
}
static struct usb_phy *imx_usbphy_to_usbphy(struct phy *phy)
{
struct imx_usbphy *imxphy = phy_get_drvdata(phy);
return &imxphy->usb_phy;
}
static const struct phy_ops imx_phy_ops = {
.init = imx_usbphy_phy_init,
.to_usbphy = imx_usbphy_to_usbphy,
};
static int imx_usbphy_probe(struct device_d *dev)
{
struct resource *iores;
@ -82,7 +109,22 @@ static int imx_usbphy_probe(struct device_d *dev)
goto err_clk;
}
imx_usbphy_enable(imxphy);
dev->priv = imxphy;
imxphy->usb_phy.dev = dev;
imxphy->phy = phy_create(dev, NULL, &imx_phy_ops, NULL);
if (IS_ERR(imxphy->phy)) {
ret = PTR_ERR(imxphy->phy);
goto err_clk;
}
phy_set_drvdata(imxphy->phy, imxphy);
imxphy->provider = of_phy_provider_register(dev, imx_usbphy_xlate);
if (IS_ERR(imxphy->provider)) {
ret = PTR_ERR(imxphy->provider);
goto err_clk;
}
dev_dbg(dev, "phy enabled\n");