Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB OTG: add support for ulpi connected external transceivers

This adds support for OTG transceivers directly connected to the ULPI
interface. In particular, the following details are added

- a struct for low level io functions (read/write)
- a priv field to be used as 'viewport' by low level access functions
- an (*init) and (*shutdown) callbacks, along with static inline helpers
- a (*set_vbus) callback to switch the port power on and off
- a flags field for per-transceiver settings
- some defines for the flags bitmask to configure platform specific
details

Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Heikki Krogerus <ext-heikki.krogerus@nokia.com>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Daniel Mack and committed by
Greg Kroah-Hartman
91c8a5a9 c3f22d92

+67 -1
+67 -1
include/linux/usb/otg.h
··· 33 33 OTG_STATE_A_VBUS_ERR, 34 34 }; 35 35 36 + #define USB_OTG_PULLUP_ID (1 << 0) 37 + #define USB_OTG_PULLDOWN_DP (1 << 1) 38 + #define USB_OTG_PULLDOWN_DM (1 << 2) 39 + #define USB_OTG_EXT_VBUS_INDICATOR (1 << 3) 40 + #define USB_OTG_DRV_VBUS (1 << 4) 41 + #define USB_OTG_DRV_VBUS_EXT (1 << 5) 42 + 43 + struct otg_transceiver; 44 + 45 + /* for transceivers connected thru an ULPI interface, the user must 46 + * provide access ops 47 + */ 48 + struct otg_io_access_ops { 49 + int (*read)(struct otg_transceiver *otg, u32 reg); 50 + int (*write)(struct otg_transceiver *otg, u32 val, u32 reg); 51 + }; 52 + 36 53 /* 37 54 * the otg driver needs to interact with both device side and host side 38 55 * usb controllers. it decides which controller is active at a given ··· 59 42 struct otg_transceiver { 60 43 struct device *dev; 61 44 const char *label; 45 + unsigned int flags; 62 46 63 47 u8 default_a; 64 48 enum usb_otg_state state; ··· 67 49 struct usb_bus *host; 68 50 struct usb_gadget *gadget; 69 51 52 + struct otg_io_access_ops *io_ops; 53 + void __iomem *io_priv; 54 + 70 55 /* to pass extra port status to the root hub */ 71 56 u16 port_status; 72 57 u16 port_change; 58 + 59 + /* initialize/shutdown the OTG controller */ 60 + int (*init)(struct otg_transceiver *otg); 61 + void (*shutdown)(struct otg_transceiver *otg); 73 62 74 63 /* bind/unbind the host controller */ 75 64 int (*set_host)(struct otg_transceiver *otg, ··· 89 64 /* effective for B devices, ignored for A-peripheral */ 90 65 int (*set_power)(struct otg_transceiver *otg, 91 66 unsigned mA); 67 + 68 + /* effective for A-peripheral, ignored for B devices */ 69 + int (*set_vbus)(struct otg_transceiver *otg, 70 + bool enabled); 92 71 93 72 /* for non-OTG B devices: set transceiver into suspend mode */ 94 73 int (*set_suspend)(struct otg_transceiver *otg, ··· 114 85 extern void usb_nop_xceiv_register(void); 115 86 extern void usb_nop_xceiv_unregister(void); 116 87 88 + /* helpers for direct access thru low-level io interface */ 89 + static inline int otg_io_read(struct otg_transceiver *otg, u32 reg) 90 + { 91 + if (otg->io_ops && otg->io_ops->read) 92 + return otg->io_ops->read(otg, reg); 93 + 94 + return -EINVAL; 95 + } 96 + 97 + static inline int otg_io_write(struct otg_transceiver *otg, u32 reg, u32 val) 98 + { 99 + if (otg->io_ops && otg->io_ops->write) 100 + return otg->io_ops->write(otg, reg, val); 101 + 102 + return -EINVAL; 103 + } 104 + 105 + static inline int 106 + otg_init(struct otg_transceiver *otg) 107 + { 108 + if (otg->init) 109 + return otg->init(otg); 110 + 111 + return 0; 112 + } 113 + 114 + static inline void 115 + otg_shutdown(struct otg_transceiver *otg) 116 + { 117 + if (otg->shutdown) 118 + otg->shutdown(otg); 119 + } 117 120 118 121 /* for usb host and peripheral controller drivers */ 119 122 extern struct otg_transceiver *otg_get_transceiver(void); ··· 158 97 return otg->start_hnp(otg); 159 98 } 160 99 100 + /* Context: can sleep */ 101 + static inline int 102 + otg_set_vbus(struct otg_transceiver *otg, bool enabled) 103 + { 104 + return otg->set_vbus(otg, enabled); 105 + } 161 106 162 107 /* for HCDs */ 163 108 static inline int ··· 171 104 { 172 105 return otg->set_host(otg, host); 173 106 } 174 - 175 107 176 108 /* for usb peripheral controller drivers */ 177 109