usb: otg: support for multiple transceivers by a single controller

Add a linked list for keeping multiple PHY instances with different
types so that we can have separate USB2 and USB3 PHYs on one single
board. _get_phy_ has been changed so that the controller gets
the transceiver by type. _remove_phy_ has been added to let the phy
be removed from the phy list.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
Kishon Vijay Abraham I 2012-06-22 17:02:46 +05:30 committed by Felipe Balbi
parent 721002ec1d
commit 662dca54ca
35 changed files with 152 additions and 57 deletions

View file

@ -43,6 +43,13 @@ enum usb_phy_events {
USB_EVENT_ENUMERATED, /* gadget driver enumerated */
};
/* associate a type with PHY */
enum usb_phy_type {
USB_PHY_TYPE_UNDEFINED,
USB_PHY_TYPE_USB2,
USB_PHY_TYPE_USB3,
};
struct usb_phy;
/* for transceivers connected thru an ULPI interface, the user must
@ -89,6 +96,7 @@ struct usb_phy {
const char *label;
unsigned int flags;
enum usb_phy_type type;
enum usb_otg_state state;
enum usb_phy_events last_event;
@ -105,6 +113,9 @@ struct usb_phy {
u16 port_status;
u16 port_change;
/* to support controllers that have multiple transceivers */
struct list_head head;
/* initialize/shutdown the OTG controller */
int (*init)(struct usb_phy *x);
void (*shutdown)(struct usb_phy *x);
@ -121,7 +132,8 @@ struct usb_phy {
/* for board-specific init logic */
extern int usb_add_phy(struct usb_phy *);
extern int usb_add_phy(struct usb_phy *, enum usb_phy_type type);
extern void usb_remove_phy(struct usb_phy *);
#if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE))
/* sometimes transceivers are accessed only through e.g. ULPI */
@ -172,11 +184,11 @@ usb_phy_shutdown(struct usb_phy *x)
/* for usb host and peripheral controller drivers */
#ifdef CONFIG_USB_OTG_UTILS
extern struct usb_phy *usb_get_phy(void);
extern struct usb_phy *usb_get_phy(enum usb_phy_type type);
extern void usb_put_phy(struct usb_phy *);
extern const char *otg_state_string(enum usb_otg_state state);
#else
static inline struct usb_phy *usb_get_phy(void)
static inline struct usb_phy *usb_get_phy(enum usb_phy_type type)
{
return NULL;
}
@ -276,4 +288,15 @@ usb_unregister_notifier(struct usb_phy *x, struct notifier_block *nb)
/* for OTG controller drivers (and maybe other stuff) */
extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num);
static inline const char *usb_phy_type_string(enum usb_phy_type type)
{
switch (type) {
case USB_PHY_TYPE_USB2:
return "USB2 PHY";
case USB_PHY_TYPE_USB3:
return "USB3 PHY";
default:
return "UNKNOWN PHY TYPE";
}
}
#endif /* __LINUX_USB_OTG_H */