linux/include/linux/usb/phy.h
<<
>>
Prefs
   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 */
 234