Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */ 2 : : /* 3 : : * USB PHY defines 4 : : * 5 : : * These APIs may be used between USB controllers. USB device drivers 6 : : * (for either host or peripheral roles) don't use these calls; they 7 : : * continue to use just usb_device and usb_gadget. 8 : : */ 9 : : 10 : : #ifndef __LINUX_USB_PHY_H 11 : : #define __LINUX_USB_PHY_H 12 : : 13 : : #include <linux/extcon.h> 14 : : #include <linux/notifier.h> 15 : : #include <linux/usb.h> 16 : : #include <uapi/linux/usb/charger.h> 17 : : 18 : : enum usb_phy_interface { 19 : : USBPHY_INTERFACE_MODE_UNKNOWN, 20 : : USBPHY_INTERFACE_MODE_UTMI, 21 : : USBPHY_INTERFACE_MODE_UTMIW, 22 : : USBPHY_INTERFACE_MODE_ULPI, 23 : : USBPHY_INTERFACE_MODE_SERIAL, 24 : : USBPHY_INTERFACE_MODE_HSIC, 25 : : }; 26 : : 27 : : enum usb_phy_events { 28 : : USB_EVENT_NONE, /* no events or cable disconnected */ 29 : : USB_EVENT_VBUS, /* vbus valid event */ 30 : : USB_EVENT_ID, /* id was grounded */ 31 : : USB_EVENT_CHARGER, /* usb dedicated charger */ 32 : : USB_EVENT_ENUMERATED, /* gadget driver enumerated */ 33 : : }; 34 : : 35 : : /* associate a type with PHY */ 36 : : enum usb_phy_type { 37 : : USB_PHY_TYPE_UNDEFINED, 38 : : USB_PHY_TYPE_USB2, 39 : : USB_PHY_TYPE_USB3, 40 : : }; 41 : : 42 : : /* OTG defines lots of enumeration states before device reset */ 43 : : enum usb_otg_state { 44 : : OTG_STATE_UNDEFINED = 0, 45 : : 46 : : /* single-role peripheral, and dual-role default-b */ 47 : : OTG_STATE_B_IDLE, 48 : : OTG_STATE_B_SRP_INIT, 49 : : OTG_STATE_B_PERIPHERAL, 50 : : 51 : : /* extra dual-role default-b states */ 52 : : OTG_STATE_B_WAIT_ACON, 53 : : OTG_STATE_B_HOST, 54 : : 55 : : /* dual-role default-a */ 56 : : OTG_STATE_A_IDLE, 57 : : OTG_STATE_A_WAIT_VRISE, 58 : : OTG_STATE_A_WAIT_BCON, 59 : : OTG_STATE_A_HOST, 60 : : OTG_STATE_A_SUSPEND, 61 : : OTG_STATE_A_PERIPHERAL, 62 : : OTG_STATE_A_WAIT_VFALL, 63 : : OTG_STATE_A_VBUS_ERR, 64 : : }; 65 : : 66 : : struct usb_phy; 67 : : struct usb_otg; 68 : : 69 : : /* for phys connected thru an ULPI interface, the user must 70 : : * provide access ops 71 : : */ 72 : : struct usb_phy_io_ops { 73 : : int (*read)(struct usb_phy *x, u32 reg); 74 : : int (*write)(struct usb_phy *x, u32 val, u32 reg); 75 : : }; 76 : : 77 : : struct usb_charger_current { 78 : : unsigned int sdp_min; 79 : : unsigned int sdp_max; 80 : : unsigned int dcp_min; 81 : : unsigned int dcp_max; 82 : : unsigned int cdp_min; 83 : : unsigned int cdp_max; 84 : : unsigned int aca_min; 85 : : unsigned int aca_max; 86 : : }; 87 : : 88 : : struct usb_phy { 89 : : struct device *dev; 90 : : const char *label; 91 : : unsigned int flags; 92 : : 93 : : enum usb_phy_type type; 94 : : enum usb_phy_events last_event; 95 : : 96 : : struct usb_otg *otg; 97 : : 98 : : struct device *io_dev; 99 : : struct usb_phy_io_ops *io_ops; 100 : : void __iomem *io_priv; 101 : : 102 : : /* to support extcon device */ 103 : : struct extcon_dev *edev; 104 : : struct extcon_dev *id_edev; 105 : : struct notifier_block vbus_nb; 106 : : struct notifier_block id_nb; 107 : : struct notifier_block type_nb; 108 : : 109 : : /* Support USB charger */ 110 : : enum usb_charger_type chg_type; 111 : : enum usb_charger_state chg_state; 112 : : struct usb_charger_current chg_cur; 113 : : struct work_struct chg_work; 114 : : 115 : : /* for notification of usb_phy_events */ 116 : : struct atomic_notifier_head notifier; 117 : : 118 : : /* to pass extra port status to the root hub */ 119 : : u16 port_status; 120 : : u16 port_change; 121 : : 122 : : /* to support controllers that have multiple phys */ 123 : : struct list_head head; 124 : : 125 : : /* initialize/shutdown the phy */ 126 : : int (*init)(struct usb_phy *x); 127 : : void (*shutdown)(struct usb_phy *x); 128 : : 129 : : /* enable/disable VBUS */ 130 : : int (*set_vbus)(struct usb_phy *x, int on); 131 : : 132 : : /* effective for B devices, ignored for A-peripheral */ 133 : : int (*set_power)(struct usb_phy *x, 134 : : unsigned mA); 135 : : 136 : : /* Set phy into suspend mode */ 137 : : int (*set_suspend)(struct usb_phy *x, 138 : : int suspend); 139 : : 140 : : /* 141 : : * Set wakeup enable for PHY, in that case, the PHY can be 142 : : * woken up from suspend status due to external events, 143 : : * like vbus change, dp/dm change and id. 144 : : */ 145 : : int (*set_wakeup)(struct usb_phy *x, bool enabled); 146 : : 147 : : /* notify phy connect status change */ 148 : : int (*notify_connect)(struct usb_phy *x, 149 : : enum usb_device_speed speed); 150 : : int (*notify_disconnect)(struct usb_phy *x, 151 : : enum usb_device_speed speed); 152 : : 153 : : /* 154 : : * Charger detection method can be implemented if you need to 155 : : * manually detect the charger type. 156 : : */ 157 : : enum usb_charger_type (*charger_detect)(struct usb_phy *x); 158 : : }; 159 : : 160 : : /* for board-specific init logic */ 161 : : extern int usb_add_phy(struct usb_phy *, enum usb_phy_type type); 162 : : extern int usb_add_phy_dev(struct usb_phy *); 163 : : extern void usb_remove_phy(struct usb_phy *); 164 : : 165 : : /* helpers for direct access thru low-level io interface */ 166 : : static inline int usb_phy_io_read(struct usb_phy *x, u32 reg) 167 : : { 168 : : if (x && x->io_ops && x->io_ops->read) 169 : : return x->io_ops->read(x, reg); 170 : : 171 : : return -EINVAL; 172 : : } 173 : : 174 : : static inline int usb_phy_io_write(struct usb_phy *x, u32 val, u32 reg) 175 : : { 176 : : if (x && x->io_ops && x->io_ops->write) 177 : : return x->io_ops->write(x, val, reg); 178 : : 179 : : return -EINVAL; 180 : : } 181 : : 182 : : static inline int 183 : : usb_phy_init(struct usb_phy *x) 184 : : { 185 : : if (x && x->init) 186 : : return x->init(x); 187 : : 188 : : return 0; 189 : : } 190 : : 191 : : static inline void 192 : : usb_phy_shutdown(struct usb_phy *x) 193 : : { 194 : : if (x && x->shutdown) 195 : : x->shutdown(x); 196 : : } 197 : : 198 : : static inline int 199 : : usb_phy_vbus_on(struct usb_phy *x) 200 : : { 201 : : if (!x || !x->set_vbus) 202 : : return 0; 203 : : 204 : : return x->set_vbus(x, true); 205 : : } 206 : : 207 : : static inline int 208 : : usb_phy_vbus_off(struct usb_phy *x) 209 : : { 210 : : if (!x || !x->set_vbus) 211 : : return 0; 212 : : 213 : : return x->set_vbus(x, false); 214 : : } 215 : : 216 : : /* for usb host and peripheral controller drivers */ 217 : : #if IS_ENABLED(CONFIG_USB_PHY) 218 : : extern struct usb_phy *usb_get_phy(enum usb_phy_type type); 219 : : extern struct usb_phy *devm_usb_get_phy(struct device *dev, 220 : : enum usb_phy_type type); 221 : : extern struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, 222 : : const char *phandle, u8 index); 223 : : extern struct usb_phy *devm_usb_get_phy_by_node(struct device *dev, 224 : : struct device_node *node, struct notifier_block *nb); 225 : : extern void usb_put_phy(struct usb_phy *); 226 : : extern void devm_usb_put_phy(struct device *dev, struct usb_phy *x); 227 : : extern void usb_phy_set_event(struct usb_phy *x, unsigned long event); 228 : : extern void usb_phy_set_charger_current(struct usb_phy *usb_phy, 229 : : unsigned int mA); 230 : : extern void usb_phy_get_charger_current(struct usb_phy *usb_phy, 231 : : unsigned int *min, unsigned int *max); 232 : : extern void usb_phy_set_charger_state(struct usb_phy *usb_phy, 233 : : enum usb_charger_state state); 234 : : #else 235 : : static inline struct usb_phy *usb_get_phy(enum usb_phy_type type) 236 : : { 237 : : return ERR_PTR(-ENXIO); 238 : : } 239 : : 240 : : static inline struct usb_phy *devm_usb_get_phy(struct device *dev, 241 : : enum usb_phy_type type) 242 : : { 243 : : return ERR_PTR(-ENXIO); 244 : : } 245 : : 246 : : static inline struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, 247 : : const char *phandle, u8 index) 248 : : { 249 : : return ERR_PTR(-ENXIO); 250 : : } 251 : : 252 : : static inline struct usb_phy *devm_usb_get_phy_by_node(struct device *dev, 253 : : struct device_node *node, struct notifier_block *nb) 254 : : { 255 : : return ERR_PTR(-ENXIO); 256 : : } 257 : : 258 : : static inline void usb_put_phy(struct usb_phy *x) 259 : : { 260 : : } 261 : : 262 : : static inline void devm_usb_put_phy(struct device *dev, struct usb_phy *x) 263 : : { 264 : : } 265 : : 266 : : static inline void usb_phy_set_event(struct usb_phy *x, unsigned long event) 267 : : { 268 : : } 269 : : 270 : : static inline void usb_phy_set_charger_current(struct usb_phy *usb_phy, 271 : : unsigned int mA) 272 : : { 273 : : } 274 : : 275 : : static inline void usb_phy_get_charger_current(struct usb_phy *usb_phy, 276 : : unsigned int *min, 277 : : unsigned int *max) 278 : : { 279 : : } 280 : : 281 : : static inline void usb_phy_set_charger_state(struct usb_phy *usb_phy, 282 : : enum usb_charger_state state) 283 : : { 284 : : } 285 : : #endif 286 : : 287 : : static inline int 288 : : usb_phy_set_power(struct usb_phy *x, unsigned mA) 289 : : { 290 : : if (!x) 291 : : return 0; 292 : : 293 : : usb_phy_set_charger_current(x, mA); 294 : : 295 : : if (x->set_power) 296 : : return x->set_power(x, mA); 297 : : return 0; 298 : : } 299 : : 300 : : /* Context: can sleep */ 301 : : static inline int 302 : : usb_phy_set_suspend(struct usb_phy *x, int suspend) 303 : : { 304 : : if (x && x->set_suspend != NULL) 305 : : return x->set_suspend(x, suspend); 306 : : else 307 : : return 0; 308 : : } 309 : : 310 : : static inline int 311 : : usb_phy_set_wakeup(struct usb_phy *x, bool enabled) 312 : : { 313 : : if (x && x->set_wakeup) 314 : : return x->set_wakeup(x, enabled); 315 : : else 316 : : return 0; 317 : : } 318 : : 319 : : static inline int 320 : : usb_phy_notify_connect(struct usb_phy *x, enum usb_device_speed speed) 321 : : { 322 : 0 : if (x && x->notify_connect) 323 : 0 : return x->notify_connect(x, speed); 324 : : else 325 : : return 0; 326 : : } 327 : : 328 : : static inline int 329 : : usb_phy_notify_disconnect(struct usb_phy *x, enum usb_device_speed speed) 330 : : { 331 : 0 : if (x && x->notify_disconnect) 332 : 0 : return x->notify_disconnect(x, speed); 333 : : else 334 : : return 0; 335 : : } 336 : : 337 : : /* notifiers */ 338 : : static inline int 339 : : usb_register_notifier(struct usb_phy *x, struct notifier_block *nb) 340 : : { 341 : : return atomic_notifier_chain_register(&x->notifier, nb); 342 : : } 343 : : 344 : : static inline void 345 : : usb_unregister_notifier(struct usb_phy *x, struct notifier_block *nb) 346 : : { 347 : : atomic_notifier_chain_unregister(&x->notifier, nb); 348 : : } 349 : : 350 : : static inline const char *usb_phy_type_string(enum usb_phy_type type) 351 : : { 352 : : switch (type) { 353 : : case USB_PHY_TYPE_USB2: 354 : : return "USB2 PHY"; 355 : : case USB_PHY_TYPE_USB3: 356 : : return "USB3 PHY"; 357 : : default: 358 : : return "UNKNOWN PHY TYPE"; 359 : : } 360 : : } 361 : : #endif /* __LINUX_USB_PHY_H */