.. | .. |
---|
15 | 15 | #include <linux/usb/of.h> |
---|
16 | 16 | #include <linux/usb/otg.h> |
---|
17 | 17 | #include <linux/of_platform.h> |
---|
| 18 | +#include <linux/debugfs.h> |
---|
| 19 | +#include "common.h" |
---|
| 20 | + |
---|
| 21 | +static const char *const ep_type_names[] = { |
---|
| 22 | + [USB_ENDPOINT_XFER_CONTROL] = "ctrl", |
---|
| 23 | + [USB_ENDPOINT_XFER_ISOC] = "isoc", |
---|
| 24 | + [USB_ENDPOINT_XFER_BULK] = "bulk", |
---|
| 25 | + [USB_ENDPOINT_XFER_INT] = "intr", |
---|
| 26 | +}; |
---|
| 27 | + |
---|
| 28 | +/** |
---|
| 29 | + * usb_ep_type_string() - Returns human readable-name of the endpoint type. |
---|
| 30 | + * @ep_type: The endpoint type to return human-readable name for. If it's not |
---|
| 31 | + * any of the types: USB_ENDPOINT_XFER_{CONTROL, ISOC, BULK, INT}, |
---|
| 32 | + * usually got by usb_endpoint_type(), the string 'unknown' will be returned. |
---|
| 33 | + */ |
---|
| 34 | +const char *usb_ep_type_string(int ep_type) |
---|
| 35 | +{ |
---|
| 36 | + if (ep_type < 0 || ep_type >= ARRAY_SIZE(ep_type_names)) |
---|
| 37 | + return "unknown"; |
---|
| 38 | + |
---|
| 39 | + return ep_type_names[ep_type]; |
---|
| 40 | +} |
---|
| 41 | +EXPORT_SYMBOL_GPL(usb_ep_type_string); |
---|
18 | 42 | |
---|
19 | 43 | const char *usb_otg_state_string(enum usb_otg_state state) |
---|
20 | 44 | { |
---|
.. | .. |
---|
51 | 75 | [USB_SPEED_SUPER_PLUS] = "super-speed-plus", |
---|
52 | 76 | }; |
---|
53 | 77 | |
---|
| 78 | +static const char *const ssp_rate[] = { |
---|
| 79 | + [USB_SSP_GEN_UNKNOWN] = "UNKNOWN", |
---|
| 80 | + [USB_SSP_GEN_2x1] = "super-speed-plus-gen2x1", |
---|
| 81 | + [USB_SSP_GEN_1x2] = "super-speed-plus-gen1x2", |
---|
| 82 | + [USB_SSP_GEN_2x2] = "super-speed-plus-gen2x2", |
---|
| 83 | +}; |
---|
| 84 | + |
---|
| 85 | +/** |
---|
| 86 | + * usb_speed_string() - Returns human readable-name of the speed. |
---|
| 87 | + * @speed: The speed to return human-readable name for. If it's not |
---|
| 88 | + * any of the speeds defined in usb_device_speed enum, string for |
---|
| 89 | + * USB_SPEED_UNKNOWN will be returned. |
---|
| 90 | + */ |
---|
54 | 91 | const char *usb_speed_string(enum usb_device_speed speed) |
---|
55 | 92 | { |
---|
56 | 93 | if (speed < 0 || speed >= ARRAY_SIZE(speed_names)) |
---|
.. | .. |
---|
59 | 96 | } |
---|
60 | 97 | EXPORT_SYMBOL_GPL(usb_speed_string); |
---|
61 | 98 | |
---|
| 99 | +/** |
---|
| 100 | + * usb_get_maximum_speed - Get maximum requested speed for a given USB |
---|
| 101 | + * controller. |
---|
| 102 | + * @dev: Pointer to the given USB controller device |
---|
| 103 | + * |
---|
| 104 | + * The function gets the maximum speed string from property "maximum-speed", |
---|
| 105 | + * and returns the corresponding enum usb_device_speed. |
---|
| 106 | + */ |
---|
62 | 107 | enum usb_device_speed usb_get_maximum_speed(struct device *dev) |
---|
63 | 108 | { |
---|
64 | 109 | const char *maximum_speed; |
---|
.. | .. |
---|
68 | 113 | if (ret < 0) |
---|
69 | 114 | return USB_SPEED_UNKNOWN; |
---|
70 | 115 | |
---|
71 | | - ret = match_string(speed_names, ARRAY_SIZE(speed_names), maximum_speed); |
---|
| 116 | + ret = match_string(ssp_rate, ARRAY_SIZE(ssp_rate), maximum_speed); |
---|
| 117 | + if (ret > 0) |
---|
| 118 | + return USB_SPEED_SUPER_PLUS; |
---|
72 | 119 | |
---|
| 120 | + ret = match_string(speed_names, ARRAY_SIZE(speed_names), maximum_speed); |
---|
73 | 121 | return (ret < 0) ? USB_SPEED_UNKNOWN : ret; |
---|
74 | 122 | } |
---|
75 | 123 | EXPORT_SYMBOL_GPL(usb_get_maximum_speed); |
---|
76 | 124 | |
---|
| 125 | +/** |
---|
| 126 | + * usb_get_maximum_ssp_rate - Get the signaling rate generation and lane count |
---|
| 127 | + * of a SuperSpeed Plus capable device. |
---|
| 128 | + * @dev: Pointer to the given USB controller device |
---|
| 129 | + * |
---|
| 130 | + * If the string from "maximum-speed" property is super-speed-plus-genXxY where |
---|
| 131 | + * 'X' is the generation number and 'Y' is the number of lanes, then this |
---|
| 132 | + * function returns the corresponding enum usb_ssp_rate. |
---|
| 133 | + */ |
---|
| 134 | +enum usb_ssp_rate usb_get_maximum_ssp_rate(struct device *dev) |
---|
| 135 | +{ |
---|
| 136 | + const char *maximum_speed; |
---|
| 137 | + int ret; |
---|
| 138 | + |
---|
| 139 | + ret = device_property_read_string(dev, "maximum-speed", &maximum_speed); |
---|
| 140 | + if (ret < 0) |
---|
| 141 | + return USB_SSP_GEN_UNKNOWN; |
---|
| 142 | + |
---|
| 143 | + ret = match_string(ssp_rate, ARRAY_SIZE(ssp_rate), maximum_speed); |
---|
| 144 | + return (ret < 0) ? USB_SSP_GEN_UNKNOWN : ret; |
---|
| 145 | +} |
---|
| 146 | +EXPORT_SYMBOL_GPL(usb_get_maximum_ssp_rate); |
---|
| 147 | + |
---|
| 148 | +/** |
---|
| 149 | + * usb_state_string - Returns human readable name for the state. |
---|
| 150 | + * @state: The state to return a human-readable name for. If it's not |
---|
| 151 | + * any of the states devices in usb_device_state_string enum, |
---|
| 152 | + * the string UNKNOWN will be returned. |
---|
| 153 | + */ |
---|
77 | 154 | const char *usb_state_string(enum usb_device_state state) |
---|
78 | 155 | { |
---|
79 | 156 | static const char *const names[] = { |
---|
.. | .. |
---|
100 | 177 | [USB_DR_MODE_HOST] = "host", |
---|
101 | 178 | [USB_DR_MODE_PERIPHERAL] = "peripheral", |
---|
102 | 179 | [USB_DR_MODE_OTG] = "otg", |
---|
103 | | - [USB_DR_MODE_DRD] = "drd", |
---|
104 | 180 | }; |
---|
105 | 181 | |
---|
106 | 182 | static enum usb_dr_mode usb_get_dr_mode_from_string(const char *str) |
---|
.. | .. |
---|
123 | 199 | return usb_get_dr_mode_from_string(dr_mode); |
---|
124 | 200 | } |
---|
125 | 201 | EXPORT_SYMBOL_GPL(usb_get_dr_mode); |
---|
| 202 | + |
---|
| 203 | +/** |
---|
| 204 | + * usb_decode_interval - Decode bInterval into the time expressed in 1us unit |
---|
| 205 | + * @epd: The descriptor of the endpoint |
---|
| 206 | + * @speed: The speed that the endpoint works as |
---|
| 207 | + * |
---|
| 208 | + * Function returns the interval expressed in 1us unit for servicing |
---|
| 209 | + * endpoint for data transfers. |
---|
| 210 | + */ |
---|
| 211 | +unsigned int usb_decode_interval(const struct usb_endpoint_descriptor *epd, |
---|
| 212 | + enum usb_device_speed speed) |
---|
| 213 | +{ |
---|
| 214 | + unsigned int interval = 0; |
---|
| 215 | + |
---|
| 216 | + switch (usb_endpoint_type(epd)) { |
---|
| 217 | + case USB_ENDPOINT_XFER_CONTROL: |
---|
| 218 | + /* uframes per NAK */ |
---|
| 219 | + if (speed == USB_SPEED_HIGH) |
---|
| 220 | + interval = epd->bInterval; |
---|
| 221 | + break; |
---|
| 222 | + case USB_ENDPOINT_XFER_ISOC: |
---|
| 223 | + interval = 1 << (epd->bInterval - 1); |
---|
| 224 | + break; |
---|
| 225 | + case USB_ENDPOINT_XFER_BULK: |
---|
| 226 | + /* uframes per NAK */ |
---|
| 227 | + if (speed == USB_SPEED_HIGH && usb_endpoint_dir_out(epd)) |
---|
| 228 | + interval = epd->bInterval; |
---|
| 229 | + break; |
---|
| 230 | + case USB_ENDPOINT_XFER_INT: |
---|
| 231 | + if (speed >= USB_SPEED_HIGH) |
---|
| 232 | + interval = 1 << (epd->bInterval - 1); |
---|
| 233 | + else |
---|
| 234 | + interval = epd->bInterval; |
---|
| 235 | + break; |
---|
| 236 | + } |
---|
| 237 | + |
---|
| 238 | + interval *= (speed >= USB_SPEED_HIGH) ? 125 : 1000; |
---|
| 239 | + |
---|
| 240 | + return interval; |
---|
| 241 | +} |
---|
| 242 | +EXPORT_SYMBOL_GPL(usb_decode_interval); |
---|
126 | 243 | |
---|
127 | 244 | #ifdef CONFIG_OF |
---|
128 | 245 | /** |
---|
.. | .. |
---|
276 | 393 | EXPORT_SYMBOL_GPL(usb_of_get_companion_dev); |
---|
277 | 394 | #endif |
---|
278 | 395 | |
---|
| 396 | +struct dentry *usb_debug_root; |
---|
| 397 | +EXPORT_SYMBOL_GPL(usb_debug_root); |
---|
| 398 | + |
---|
| 399 | +static int __init usb_common_init(void) |
---|
| 400 | +{ |
---|
| 401 | + usb_debug_root = debugfs_create_dir("usb", NULL); |
---|
| 402 | + ledtrig_usb_init(); |
---|
| 403 | + return 0; |
---|
| 404 | +} |
---|
| 405 | + |
---|
| 406 | +static void __exit usb_common_exit(void) |
---|
| 407 | +{ |
---|
| 408 | + ledtrig_usb_exit(); |
---|
| 409 | + debugfs_remove_recursive(usb_debug_root); |
---|
| 410 | +} |
---|
| 411 | + |
---|
| 412 | +subsys_initcall(usb_common_init); |
---|
| 413 | +module_exit(usb_common_exit); |
---|
| 414 | + |
---|
279 | 415 | MODULE_LICENSE("GPL"); |
---|