at v3.7 5.2 kB view raw
1/* USB OTG (On The Go) defines */ 2/* 3 * 4 * These APIs may be used between USB controllers. USB device drivers 5 * (for either host or peripheral roles) don't use these calls; they 6 * continue to use just usb_device and usb_gadget. 7 */ 8 9#ifndef __LINUX_USB_PHY_H 10#define __LINUX_USB_PHY_H 11 12#include <linux/notifier.h> 13 14enum usb_phy_events { 15 USB_EVENT_NONE, /* no events or cable disconnected */ 16 USB_EVENT_VBUS, /* vbus valid event */ 17 USB_EVENT_ID, /* id was grounded */ 18 USB_EVENT_CHARGER, /* usb dedicated charger */ 19 USB_EVENT_ENUMERATED, /* gadget driver enumerated */ 20}; 21 22/* associate a type with PHY */ 23enum usb_phy_type { 24 USB_PHY_TYPE_UNDEFINED, 25 USB_PHY_TYPE_USB2, 26 USB_PHY_TYPE_USB3, 27}; 28 29/* OTG defines lots of enumeration states before device reset */ 30enum usb_otg_state { 31 OTG_STATE_UNDEFINED = 0, 32 33 /* single-role peripheral, and dual-role default-b */ 34 OTG_STATE_B_IDLE, 35 OTG_STATE_B_SRP_INIT, 36 OTG_STATE_B_PERIPHERAL, 37 38 /* extra dual-role default-b states */ 39 OTG_STATE_B_WAIT_ACON, 40 OTG_STATE_B_HOST, 41 42 /* dual-role default-a */ 43 OTG_STATE_A_IDLE, 44 OTG_STATE_A_WAIT_VRISE, 45 OTG_STATE_A_WAIT_BCON, 46 OTG_STATE_A_HOST, 47 OTG_STATE_A_SUSPEND, 48 OTG_STATE_A_PERIPHERAL, 49 OTG_STATE_A_WAIT_VFALL, 50 OTG_STATE_A_VBUS_ERR, 51}; 52 53struct usb_phy; 54struct usb_otg; 55 56/* for transceivers connected thru an ULPI interface, the user must 57 * provide access ops 58 */ 59struct usb_phy_io_ops { 60 int (*read)(struct usb_phy *x, u32 reg); 61 int (*write)(struct usb_phy *x, u32 val, u32 reg); 62}; 63 64struct usb_phy { 65 struct device *dev; 66 const char *label; 67 unsigned int flags; 68 69 enum usb_phy_type type; 70 enum usb_otg_state state; 71 enum usb_phy_events last_event; 72 73 struct usb_otg *otg; 74 75 struct device *io_dev; 76 struct usb_phy_io_ops *io_ops; 77 void __iomem *io_priv; 78 79 /* for notification of usb_phy_events */ 80 struct atomic_notifier_head notifier; 81 82 /* to pass extra port status to the root hub */ 83 u16 port_status; 84 u16 port_change; 85 86 /* to support controllers that have multiple transceivers */ 87 struct list_head head; 88 89 /* initialize/shutdown the OTG controller */ 90 int (*init)(struct usb_phy *x); 91 void (*shutdown)(struct usb_phy *x); 92 93 /* effective for B devices, ignored for A-peripheral */ 94 int (*set_power)(struct usb_phy *x, 95 unsigned mA); 96 97 /* for non-OTG B devices: set transceiver into suspend mode */ 98 int (*set_suspend)(struct usb_phy *x, 99 int suspend); 100 101 /* notify phy connect status change */ 102 int (*notify_connect)(struct usb_phy *x, int port); 103 int (*notify_disconnect)(struct usb_phy *x, int port); 104}; 105 106 107/* for board-specific init logic */ 108extern int usb_add_phy(struct usb_phy *, enum usb_phy_type type); 109extern void usb_remove_phy(struct usb_phy *); 110 111/* helpers for direct access thru low-level io interface */ 112static inline int usb_phy_io_read(struct usb_phy *x, u32 reg) 113{ 114 if (x->io_ops && x->io_ops->read) 115 return x->io_ops->read(x, reg); 116 117 return -EINVAL; 118} 119 120static inline int usb_phy_io_write(struct usb_phy *x, u32 val, u32 reg) 121{ 122 if (x->io_ops && x->io_ops->write) 123 return x->io_ops->write(x, val, reg); 124 125 return -EINVAL; 126} 127 128static inline int 129usb_phy_init(struct usb_phy *x) 130{ 131 if (x->init) 132 return x->init(x); 133 134 return 0; 135} 136 137static inline void 138usb_phy_shutdown(struct usb_phy *x) 139{ 140 if (x->shutdown) 141 x->shutdown(x); 142} 143 144/* for usb host and peripheral controller drivers */ 145#ifdef CONFIG_USB_OTG_UTILS 146extern struct usb_phy *usb_get_phy(enum usb_phy_type type); 147extern struct usb_phy *devm_usb_get_phy(struct device *dev, 148 enum usb_phy_type type); 149extern void usb_put_phy(struct usb_phy *); 150extern void devm_usb_put_phy(struct device *dev, struct usb_phy *x); 151#else 152static inline struct usb_phy *usb_get_phy(enum usb_phy_type type) 153{ 154 return NULL; 155} 156 157static inline struct usb_phy *devm_usb_get_phy(struct device *dev, 158 enum usb_phy_type type) 159{ 160 return NULL; 161} 162 163static inline void usb_put_phy(struct usb_phy *x) 164{ 165} 166 167static inline void devm_usb_put_phy(struct device *dev, struct usb_phy *x) 168{ 169} 170 171#endif 172 173static inline int 174usb_phy_set_power(struct usb_phy *x, unsigned mA) 175{ 176 if (x && x->set_power) 177 return x->set_power(x, mA); 178 return 0; 179} 180 181/* Context: can sleep */ 182static inline int 183usb_phy_set_suspend(struct usb_phy *x, int suspend) 184{ 185 if (x->set_suspend != NULL) 186 return x->set_suspend(x, suspend); 187 else 188 return 0; 189} 190 191static inline int 192usb_phy_notify_connect(struct usb_phy *x, int port) 193{ 194 if (x->notify_connect) 195 return x->notify_connect(x, port); 196 else 197 return 0; 198} 199 200static inline int 201usb_phy_notify_disconnect(struct usb_phy *x, int port) 202{ 203 if (x->notify_disconnect) 204 return x->notify_disconnect(x, port); 205 else 206 return 0; 207} 208 209/* notifiers */ 210static inline int 211usb_register_notifier(struct usb_phy *x, struct notifier_block *nb) 212{ 213 return atomic_notifier_chain_register(&x->notifier, nb); 214} 215 216static inline void 217usb_unregister_notifier(struct usb_phy *x, struct notifier_block *nb) 218{ 219 atomic_notifier_chain_unregister(&x->notifier, nb); 220} 221 222static inline const char *usb_phy_type_string(enum usb_phy_type type) 223{ 224 switch (type) { 225 case USB_PHY_TYPE_USB2: 226 return "USB2 PHY"; 227 case USB_PHY_TYPE_USB3: 228 return "USB3 PHY"; 229 default: 230 return "UNKNOWN PHY TYPE"; 231 } 232} 233#endif /* __LINUX_USB_PHY_H */