Index: sys/dev/extres/phy/phy.h =================================================================== --- sys/dev/extres/phy/phy.h +++ sys/dev/extres/phy/phy.h @@ -37,6 +37,10 @@ #define PHY_STATUS_ENABLED 0x00000001 +#define PHY_MODE_USB_HOST 1 +#define PHY_MODE_USB_OTG 2 +#define PHY_MODE_USB_DEVICE 3 + typedef struct phy *phy_t; /* Initialization parameters. */ @@ -68,6 +72,7 @@ int phynode_enable(struct phynode *phynode); int phynode_disable(struct phynode *phynode); int phynode_status(struct phynode *phynode, int *status); +int phynode_set_mode(struct phynode *phynode, int mode); #ifdef FDT phandle_t phynode_get_ofw_node(struct phynode *phynode); #endif @@ -81,6 +86,7 @@ int phy_enable(phy_t phy); int phy_disable(phy_t phy); int phy_status(phy_t phy, int *value); +int phy_set_mode(phy_t phy, int mode); #ifdef FDT int phy_get_by_ofw_name(device_t consumer, phandle_t node, char *name, Index: sys/dev/extres/phy/phy.c =================================================================== --- sys/dev/extres/phy/phy.c +++ sys/dev/extres/phy/phy.c @@ -59,6 +59,7 @@ static int phynode_method_init(struct phynode *phynode); static int phynode_method_enable(struct phynode *phynode, bool disable); static int phynode_method_status(struct phynode *phynode, int *status); +static int phynode_method_set_mode(struct phynode *phynode, int mode); /* @@ -68,6 +69,7 @@ PHYNODEMETHOD(phynode_init, phynode_method_init), PHYNODEMETHOD(phynode_enable, phynode_method_enable), PHYNODEMETHOD(phynode_status, phynode_method_status), + PHYNODEMETHOD(phynode_set_mode, phynode_method_set_mode), PHYNODEMETHOD_END }; @@ -150,6 +152,13 @@ return (0); } +static int +phynode_method_set_mode(struct phynode *phynode, int mode) +{ + + return (EOPNOTSUPP); +} + /* ---------------------------------------------------------------------------- * * Internal functions. @@ -335,6 +344,22 @@ return (rv); } +/* + * Set phy mode. + */ +int +phynode_set_mode(struct phynode *phynode, int mode) +{ + int rv; + + PHY_TOPO_ASSERT(); + + PHYNODE_XLOCK(phynode); + rv = PHYNODE_SET_MODE(phynode, mode); + PHYNODE_UNLOCK(phynode); + return (0); +} + /* -------------------------------------------------------------------------- * * Phy consumers interface. @@ -458,6 +483,22 @@ free(phy, M_PHY); } +int +phy_set_mode(phy_t phy, int mode) +{ + int rv; + struct phynode *phynode; + + phynode = phy->phynode; + KASSERT(phynode->ref_cnt > 0, + ("Attempt to access unreferenced phy.\n")); + + PHY_TOPO_SLOCK(); + rv = phynode_set_mode(phynode, mode); + PHY_TOPO_UNLOCK(); + return (rv); +} + #ifdef FDT int phydev_default_ofw_map(device_t provider, phandle_t xref, int ncells, pcell_t *cells, intptr_t *id) Index: sys/dev/extres/phy/phynode_if.m =================================================================== --- sys/dev/extres/phy/phynode_if.m +++ sys/dev/extres/phy/phynode_if.m @@ -58,4 +58,11 @@ int *status; /* PHY_STATUS_* */ }; - +# +# Set phy mode +# Returns 0 on success or a standard errno value. +# +METHOD int set_mode { + struct phynode *phynode; + int mode; +};