usb的phy 分为内置phy和外置phy,其中内置phy在控制器里面,内置phy 不需要驱动
而外置phy 需要驱动,phy的目录在driver/phy 这个命令下。我们看看phy的主要功能
我们以drivers/phy/marvell/phy-pxa-usb.c中的描述的phy为例
usb是通过phy_ops 来控制phy的
struct phy_ops {
int (*init)(struct phy *phy);
int (*exit)(struct phy *phy);
int (*power_on)(struct phy *phy);
int (*power_off)(struct phy *phy);
int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
int (*configure)(struct phy *phy, union phy_configure_opts *opts);
int (*validate)(struct phy *phy, enum phy_mode mode, int submode,
union phy_configure_opts *opts);
int (*reset)(struct phy *phy);
int (*calibrate)(struct phy *phy);
void (*release)(struct phy *phy);
struct module *owner;
};
可以看到phy 主要是和电源管理相关的,实际上本来中的仅仅实现了init和exit两个接口
static const struct phy_ops pxa_usb_phy_ops = {
.init = pxa_usb_phy_init,
.exit = pxa_usb_phy_exit,
.owner = THIS_MODULE,
};
这个可以猜测到相对于外置phy 需要phy_ops来控制phy,内置phy 直接就控制phy了。
举例如下:
drivers/usb/usb3/dwc3-pci.c
static int dwc3_pci_quirks(struct dwc3_pci *dwc)
{
struct pci_dev *pdev = dwc->pci;
#控制器中直接控制phy
/*
* These GPIOs will turn on the USB2 PHY. Note that we have to
* put the gpio descriptors again here because the phy driver
* might want to grab them, too.
*/
gpio = gpiod_get_optional(&pdev->dev, "cs", GPIOD_OUT_LOW);
if (IS_ERR(gpio))
return PTR_ERR(gpio);
}