1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
/* USB OTG (On The Go) defines */
/*
*
* These APIs may be used between USB controllers. USB device drivers
* (for either host or peripheral roles) don't use these calls; they
* continue to use just usb_device and usb_gadget.
*/
#ifndef __LINUX_USB_OTG_H
#define __LINUX_USB_OTG_H
#include <linux/usb/phy.h>
enum usb_otg_event {
/* Device is not connected within
* TA_WAIT_BCON or not responding.
*/
OTG_EVENT_DEV_CONN_TMOUT,
/* B-device returned STALL for
* B_HNP_ENABLE feature request.
*/
OTG_EVENT_NO_RESP_FOR_HNP_ENABLE,
/* HUB class devices are not
* supported.
*/
OTG_EVENT_HUB_NOT_SUPPORTED,
/* Device is not supported i.e
* not listed in TPL.
*/
OTG_EVENT_DEV_NOT_SUPPORTED,
/* HNP failed due to
* TA_AIDL_BDIS timeout or
* TB_ASE0_BRST timeout
*/
OTG_EVENT_HNP_FAILED,
/* B-device did not detect VBUS
* within TB_SRP_FAIL time.
*/
OTG_EVENT_NO_RESP_FOR_SRP,
};
struct usb_otg {
u8 default_a;
struct usb_phy *phy;
struct usb_bus *host;
struct usb_gadget *gadget;
/* bind/unbind the host controller */
int (*set_host)(struct usb_otg *otg, struct usb_bus *host);
/* bind/unbind the peripheral controller */
int (*set_peripheral)(struct usb_otg *otg,
struct usb_gadget *gadget);
/* effective for A-peripheral, ignored for B devices */
int (*set_vbus)(struct usb_otg *otg, bool enabled);
/* for B devices only: start session with A-Host */
int (*start_srp)(struct usb_otg *otg);
/* start or continue HNP role switch */
int (*start_hnp)(struct usb_otg *otg);
/* send events to user space */
int (*send_event)(struct usb_otg *otg,
enum usb_otg_event event);
};
extern const char *usb_otg_state_string(enum usb_otg_state state);
/* Context: can sleep */
static inline int
otg_start_hnp(struct usb_otg *otg)
{
if (otg && otg->start_hnp)
return otg->start_hnp(otg);
return -ENOTSUPP;
}
/* Context: can sleep */
static inline int
otg_set_vbus(struct usb_otg *otg, bool enabled)
{
if (otg && otg->set_vbus)
return otg->set_vbus(otg, enabled);
return -ENOTSUPP;
}
/* for HCDs */
static inline int
otg_set_host(struct usb_otg *otg, struct usb_bus *host)
{
if (otg && otg->set_host)
return otg->set_host(otg, host);
return -ENOTSUPP;
}
/* for usb peripheral controller drivers */
/* Context: can sleep */
static inline int
otg_set_peripheral(struct usb_otg *otg, struct usb_gadget *periph)
{
if (otg && otg->set_peripheral)
return otg->set_peripheral(otg, periph);
return -ENOTSUPP;
}
static inline int
otg_start_srp(struct usb_otg *otg)
{
if (otg && otg->start_srp)
return otg->start_srp(otg);
return -ENOTSUPP;
}
static inline int
otg_send_event(struct usb_otg *otg, enum usb_otg_event event)
{
int ret = -ENOTSUPP;
if (otg && otg->send_event)
ret = otg->send_event(otg, event);
return ret;
}
/* for OTG controller drivers (and maybe other stuff) */
extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num);
enum usb_dr_mode {
USB_DR_MODE_UNKNOWN,
USB_DR_MODE_HOST,
USB_DR_MODE_PERIPHERAL,
USB_DR_MODE_OTG,
};
#endif /* __LINUX_USB_OTG_H */
|