diff options
author | Daniel Mack <daniel@caiaq.de> | 2009-10-15 10:09:34 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 14:55:16 -0500 |
commit | 91c8a5a9985d5bf9c55f6f82f183f57b050b2a3a (patch) | |
tree | e7154eca2ca6356889b407c0334bffbc516155d7 /include/linux/usb | |
parent | c3f22d92a1249665d4cd87a68a4078a56002c3ab (diff) |
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>
Diffstat (limited to 'include/linux/usb')
-rw-r--r-- | include/linux/usb/otg.h | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 2443c0e7a80c..52bb917641f0 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h | |||
@@ -33,6 +33,23 @@ enum usb_otg_state { | |||
33 | OTG_STATE_A_VBUS_ERR, | 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 | * the otg driver needs to interact with both device side and host side | 54 | * the otg driver needs to interact with both device side and host side |
38 | * usb controllers. it decides which controller is active at a given | 55 | * usb controllers. it decides which controller is active at a given |
@@ -42,6 +59,7 @@ enum usb_otg_state { | |||
42 | struct otg_transceiver { | 59 | struct otg_transceiver { |
43 | struct device *dev; | 60 | struct device *dev; |
44 | const char *label; | 61 | const char *label; |
62 | unsigned int flags; | ||
45 | 63 | ||
46 | u8 default_a; | 64 | u8 default_a; |
47 | enum usb_otg_state state; | 65 | enum usb_otg_state state; |
@@ -49,10 +67,17 @@ struct otg_transceiver { | |||
49 | struct usb_bus *host; | 67 | struct usb_bus *host; |
50 | struct usb_gadget *gadget; | 68 | struct usb_gadget *gadget; |
51 | 69 | ||
70 | struct otg_io_access_ops *io_ops; | ||
71 | void __iomem *io_priv; | ||
72 | |||
52 | /* to pass extra port status to the root hub */ | 73 | /* to pass extra port status to the root hub */ |
53 | u16 port_status; | 74 | u16 port_status; |
54 | u16 port_change; | 75 | u16 port_change; |
55 | 76 | ||
77 | /* initialize/shutdown the OTG controller */ | ||
78 | int (*init)(struct otg_transceiver *otg); | ||
79 | void (*shutdown)(struct otg_transceiver *otg); | ||
80 | |||
56 | /* bind/unbind the host controller */ | 81 | /* bind/unbind the host controller */ |
57 | int (*set_host)(struct otg_transceiver *otg, | 82 | int (*set_host)(struct otg_transceiver *otg, |
58 | struct usb_bus *host); | 83 | struct usb_bus *host); |
@@ -65,6 +90,10 @@ struct otg_transceiver { | |||
65 | int (*set_power)(struct otg_transceiver *otg, | 90 | int (*set_power)(struct otg_transceiver *otg, |
66 | unsigned mA); | 91 | unsigned mA); |
67 | 92 | ||
93 | /* effective for A-peripheral, ignored for B devices */ | ||
94 | int (*set_vbus)(struct otg_transceiver *otg, | ||
95 | bool enabled); | ||
96 | |||
68 | /* for non-OTG B devices: set transceiver into suspend mode */ | 97 | /* for non-OTG B devices: set transceiver into suspend mode */ |
69 | int (*set_suspend)(struct otg_transceiver *otg, | 98 | int (*set_suspend)(struct otg_transceiver *otg, |
70 | int suspend); | 99 | int suspend); |
@@ -85,6 +114,38 @@ extern int otg_set_transceiver(struct otg_transceiver *); | |||
85 | extern void usb_nop_xceiv_register(void); | 114 | extern void usb_nop_xceiv_register(void); |
86 | extern void usb_nop_xceiv_unregister(void); | 115 | extern void usb_nop_xceiv_unregister(void); |
87 | 116 | ||
117 | /* helpers for direct access thru low-level io interface */ | ||
118 | static inline int otg_io_read(struct otg_transceiver *otg, u32 reg) | ||
119 | { | ||
120 | if (otg->io_ops && otg->io_ops->read) | ||
121 | return otg->io_ops->read(otg, reg); | ||
122 | |||
123 | return -EINVAL; | ||
124 | } | ||
125 | |||
126 | static inline int otg_io_write(struct otg_transceiver *otg, u32 reg, u32 val) | ||
127 | { | ||
128 | if (otg->io_ops && otg->io_ops->write) | ||
129 | return otg->io_ops->write(otg, reg, val); | ||
130 | |||
131 | return -EINVAL; | ||
132 | } | ||
133 | |||
134 | static inline int | ||
135 | otg_init(struct otg_transceiver *otg) | ||
136 | { | ||
137 | if (otg->init) | ||
138 | return otg->init(otg); | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static inline void | ||
144 | otg_shutdown(struct otg_transceiver *otg) | ||
145 | { | ||
146 | if (otg->shutdown) | ||
147 | otg->shutdown(otg); | ||
148 | } | ||
88 | 149 | ||
89 | /* for usb host and peripheral controller drivers */ | 150 | /* for usb host and peripheral controller drivers */ |
90 | extern struct otg_transceiver *otg_get_transceiver(void); | 151 | extern struct otg_transceiver *otg_get_transceiver(void); |
@@ -97,6 +158,12 @@ otg_start_hnp(struct otg_transceiver *otg) | |||
97 | return otg->start_hnp(otg); | 158 | return otg->start_hnp(otg); |
98 | } | 159 | } |
99 | 160 | ||
161 | /* Context: can sleep */ | ||
162 | static inline int | ||
163 | otg_set_vbus(struct otg_transceiver *otg, bool enabled) | ||
164 | { | ||
165 | return otg->set_vbus(otg, enabled); | ||
166 | } | ||
100 | 167 | ||
101 | /* for HCDs */ | 168 | /* for HCDs */ |
102 | static inline int | 169 | static inline int |
@@ -105,7 +172,6 @@ otg_set_host(struct otg_transceiver *otg, struct usb_bus *host) | |||
105 | return otg->set_host(otg, host); | 172 | return otg->set_host(otg, host); |
106 | } | 173 | } |
107 | 174 | ||
108 | |||
109 | /* for usb peripheral controller drivers */ | 175 | /* for usb peripheral controller drivers */ |
110 | 176 | ||
111 | /* Context: can sleep */ | 177 | /* Context: can sleep */ |