1
2
3
4
5
6
7
8
9
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/of.h>
14#include <linux/usb/ch9.h>
15#include <linux/usb/of.h>
16#include <linux/usb/otg.h>
17
18const char *usb_otg_state_string(enum usb_otg_state state)
19{
20 static const char *const names[] = {
21 [OTG_STATE_A_IDLE] = "a_idle",
22 [OTG_STATE_A_WAIT_VRISE] = "a_wait_vrise",
23 [OTG_STATE_A_WAIT_BCON] = "a_wait_bcon",
24 [OTG_STATE_A_HOST] = "a_host",
25 [OTG_STATE_A_SUSPEND] = "a_suspend",
26 [OTG_STATE_A_PERIPHERAL] = "a_peripheral",
27 [OTG_STATE_A_WAIT_VFALL] = "a_wait_vfall",
28 [OTG_STATE_A_VBUS_ERR] = "a_vbus_err",
29 [OTG_STATE_B_IDLE] = "b_idle",
30 [OTG_STATE_B_SRP_INIT] = "b_srp_init",
31 [OTG_STATE_B_PERIPHERAL] = "b_peripheral",
32 [OTG_STATE_B_WAIT_ACON] = "b_wait_acon",
33 [OTG_STATE_B_HOST] = "b_host",
34 };
35
36 if (state < 0 || state >= ARRAY_SIZE(names))
37 return "UNDEFINED";
38
39 return names[state];
40}
41EXPORT_SYMBOL_GPL(usb_otg_state_string);
42
43static const char *const speed_names[] = {
44 [USB_SPEED_UNKNOWN] = "UNKNOWN",
45 [USB_SPEED_LOW] = "low-speed",
46 [USB_SPEED_FULL] = "full-speed",
47 [USB_SPEED_HIGH] = "high-speed",
48 [USB_SPEED_WIRELESS] = "wireless",
49 [USB_SPEED_SUPER] = "super-speed",
50 [USB_SPEED_SUPER_PLUS] = "super-speed-plus",
51};
52
53const char *usb_speed_string(enum usb_device_speed speed)
54{
55 if (speed < 0 || speed >= ARRAY_SIZE(speed_names))
56 speed = USB_SPEED_UNKNOWN;
57 return speed_names[speed];
58}
59EXPORT_SYMBOL_GPL(usb_speed_string);
60
61const char *usb_state_string(enum usb_device_state state)
62{
63 static const char *const names[] = {
64 [USB_STATE_NOTATTACHED] = "not attached",
65 [USB_STATE_ATTACHED] = "attached",
66 [USB_STATE_POWERED] = "powered",
67 [USB_STATE_RECONNECTING] = "reconnecting",
68 [USB_STATE_UNAUTHENTICATED] = "unauthenticated",
69 [USB_STATE_DEFAULT] = "default",
70 [USB_STATE_ADDRESS] = "addressed",
71 [USB_STATE_CONFIGURED] = "configured",
72 [USB_STATE_SUSPENDED] = "suspended",
73 };
74
75 if (state < 0 || state >= ARRAY_SIZE(names))
76 return "UNKNOWN";
77
78 return names[state];
79}
80EXPORT_SYMBOL_GPL(usb_state_string);
81
82#ifdef CONFIG_OF
83static const char *const usb_dr_modes[] = {
84 [USB_DR_MODE_UNKNOWN] = "",
85 [USB_DR_MODE_HOST] = "host",
86 [USB_DR_MODE_PERIPHERAL] = "peripheral",
87 [USB_DR_MODE_OTG] = "otg",
88};
89
90
91
92
93
94
95
96
97enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np)
98{
99 const char *dr_mode;
100 int err, i;
101
102 err = of_property_read_string(np, "dr_mode", &dr_mode);
103 if (err < 0)
104 return USB_DR_MODE_UNKNOWN;
105
106 for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++)
107 if (!strcmp(dr_mode, usb_dr_modes[i]))
108 return i;
109
110 return USB_DR_MODE_UNKNOWN;
111}
112EXPORT_SYMBOL_GPL(of_usb_get_dr_mode);
113
114
115
116
117
118
119
120
121
122enum usb_device_speed of_usb_get_maximum_speed(struct device_node *np)
123{
124 const char *maximum_speed;
125 int err;
126 int i;
127
128 err = of_property_read_string(np, "maximum-speed", &maximum_speed);
129 if (err < 0)
130 return USB_SPEED_UNKNOWN;
131
132 for (i = 0; i < ARRAY_SIZE(speed_names); i++)
133 if (strcmp(maximum_speed, speed_names[i]) == 0)
134 return i;
135
136 return USB_SPEED_UNKNOWN;
137}
138EXPORT_SYMBOL_GPL(of_usb_get_maximum_speed);
139
140
141
142
143
144
145
146
147bool of_usb_host_tpl_support(struct device_node *np)
148{
149 return of_property_read_bool(np, "tpl-support");
150}
151EXPORT_SYMBOL_GPL(of_usb_host_tpl_support);
152
153
154
155
156
157
158
159
160
161int of_usb_update_otg_caps(struct device_node *np,
162 struct usb_otg_caps *otg_caps)
163{
164 u32 otg_rev;
165
166 if (!otg_caps)
167 return -EINVAL;
168
169 if (!of_property_read_u32(np, "otg-rev", &otg_rev)) {
170 switch (otg_rev) {
171 case 0x0100:
172 case 0x0120:
173 case 0x0130:
174 case 0x0200:
175
176 if (otg_caps->otg_rev)
177 otg_caps->otg_rev = min_t(u16, otg_rev,
178 otg_caps->otg_rev);
179 else
180 otg_caps->otg_rev = otg_rev;
181 break;
182 default:
183 pr_err("%pOF: unsupported otg-rev: 0x%x\n",
184 np, otg_rev);
185 return -EINVAL;
186 }
187 } else {
188
189
190
191
192
193 otg_caps->otg_rev = 0;
194 }
195
196 if (of_property_read_bool(np, "hnp-disable"))
197 otg_caps->hnp_support = false;
198 if (of_property_read_bool(np, "srp-disable"))
199 otg_caps->srp_support = false;
200 if (of_property_read_bool(np, "adp-disable") ||
201 (otg_caps->otg_rev < 0x0200))
202 otg_caps->adp_support = false;
203
204 return 0;
205}
206EXPORT_SYMBOL_GPL(of_usb_update_otg_caps);
207
208#endif
209
210MODULE_LICENSE("GPL");
211