^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Provides code common for host and device side USB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * If either host side (ie. CONFIG_USB=y) or device side USB stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * (ie. CONFIG_USB_GADGET=y) is compiled in the kernel, this module is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * compiled-in as well. Otherwise, if either of the two stacks is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * compiled as module, this file is compiled as module as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/usb/ch9.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/usb/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/usb/otg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static const char *const ep_type_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) [USB_ENDPOINT_XFER_CONTROL] = "ctrl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) [USB_ENDPOINT_XFER_ISOC] = "isoc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) [USB_ENDPOINT_XFER_BULK] = "bulk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) [USB_ENDPOINT_XFER_INT] = "intr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * usb_ep_type_string() - Returns human readable-name of the endpoint type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * @ep_type: The endpoint type to return human-readable name for. If it's not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * any of the types: USB_ENDPOINT_XFER_{CONTROL, ISOC, BULK, INT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * usually got by usb_endpoint_type(), the string 'unknown' will be returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) const char *usb_ep_type_string(int ep_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (ep_type < 0 || ep_type >= ARRAY_SIZE(ep_type_names))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return ep_type_names[ep_type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) EXPORT_SYMBOL_GPL(usb_ep_type_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) const char *usb_otg_state_string(enum usb_otg_state state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static const char *const names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) [OTG_STATE_A_IDLE] = "a_idle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) [OTG_STATE_A_WAIT_VRISE] = "a_wait_vrise",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) [OTG_STATE_A_WAIT_BCON] = "a_wait_bcon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) [OTG_STATE_A_HOST] = "a_host",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) [OTG_STATE_A_SUSPEND] = "a_suspend",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) [OTG_STATE_A_PERIPHERAL] = "a_peripheral",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) [OTG_STATE_A_WAIT_VFALL] = "a_wait_vfall",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) [OTG_STATE_A_VBUS_ERR] = "a_vbus_err",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) [OTG_STATE_B_IDLE] = "b_idle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) [OTG_STATE_B_SRP_INIT] = "b_srp_init",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) [OTG_STATE_B_PERIPHERAL] = "b_peripheral",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) [OTG_STATE_B_WAIT_ACON] = "b_wait_acon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) [OTG_STATE_B_HOST] = "b_host",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (state < 0 || state >= ARRAY_SIZE(names))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return "UNDEFINED";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return names[state];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) EXPORT_SYMBOL_GPL(usb_otg_state_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static const char *const speed_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) [USB_SPEED_UNKNOWN] = "UNKNOWN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) [USB_SPEED_LOW] = "low-speed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) [USB_SPEED_FULL] = "full-speed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) [USB_SPEED_HIGH] = "high-speed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) [USB_SPEED_WIRELESS] = "wireless",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) [USB_SPEED_SUPER] = "super-speed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) [USB_SPEED_SUPER_PLUS] = "super-speed-plus",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static const char *const ssp_rate[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) [USB_SSP_GEN_UNKNOWN] = "UNKNOWN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) [USB_SSP_GEN_2x1] = "super-speed-plus-gen2x1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) [USB_SSP_GEN_1x2] = "super-speed-plus-gen1x2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) [USB_SSP_GEN_2x2] = "super-speed-plus-gen2x2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * usb_speed_string() - Returns human readable-name of the speed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * @speed: The speed to return human-readable name for. If it's not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * any of the speeds defined in usb_device_speed enum, string for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * USB_SPEED_UNKNOWN will be returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) const char *usb_speed_string(enum usb_device_speed speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (speed < 0 || speed >= ARRAY_SIZE(speed_names))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) speed = USB_SPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return speed_names[speed];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) EXPORT_SYMBOL_GPL(usb_speed_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * usb_get_maximum_speed - Get maximum requested speed for a given USB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * @dev: Pointer to the given USB controller device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * The function gets the maximum speed string from property "maximum-speed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * and returns the corresponding enum usb_device_speed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) enum usb_device_speed usb_get_maximum_speed(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) const char *maximum_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ret = device_property_read_string(dev, "maximum-speed", &maximum_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return USB_SPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ret = match_string(ssp_rate, ARRAY_SIZE(ssp_rate), maximum_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return USB_SPEED_SUPER_PLUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ret = match_string(speed_names, ARRAY_SIZE(speed_names), maximum_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return (ret < 0) ? USB_SPEED_UNKNOWN : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) EXPORT_SYMBOL_GPL(usb_get_maximum_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * usb_get_maximum_ssp_rate - Get the signaling rate generation and lane count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * of a SuperSpeed Plus capable device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * @dev: Pointer to the given USB controller device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * If the string from "maximum-speed" property is super-speed-plus-genXxY where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * 'X' is the generation number and 'Y' is the number of lanes, then this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * function returns the corresponding enum usb_ssp_rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) enum usb_ssp_rate usb_get_maximum_ssp_rate(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) const char *maximum_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ret = device_property_read_string(dev, "maximum-speed", &maximum_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return USB_SSP_GEN_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ret = match_string(ssp_rate, ARRAY_SIZE(ssp_rate), maximum_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return (ret < 0) ? USB_SSP_GEN_UNKNOWN : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) EXPORT_SYMBOL_GPL(usb_get_maximum_ssp_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * usb_state_string - Returns human readable name for the state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * @state: The state to return a human-readable name for. If it's not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * any of the states devices in usb_device_state_string enum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * the string UNKNOWN will be returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) const char *usb_state_string(enum usb_device_state state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static const char *const names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) [USB_STATE_NOTATTACHED] = "not attached",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) [USB_STATE_ATTACHED] = "attached",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) [USB_STATE_POWERED] = "powered",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) [USB_STATE_RECONNECTING] = "reconnecting",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) [USB_STATE_UNAUTHENTICATED] = "unauthenticated",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) [USB_STATE_DEFAULT] = "default",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) [USB_STATE_ADDRESS] = "addressed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) [USB_STATE_CONFIGURED] = "configured",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) [USB_STATE_SUSPENDED] = "suspended",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (state < 0 || state >= ARRAY_SIZE(names))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return "UNKNOWN";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return names[state];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) EXPORT_SYMBOL_GPL(usb_state_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static const char *const usb_dr_modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) [USB_DR_MODE_UNKNOWN] = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) [USB_DR_MODE_HOST] = "host",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) [USB_DR_MODE_PERIPHERAL] = "peripheral",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) [USB_DR_MODE_OTG] = "otg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static enum usb_dr_mode usb_get_dr_mode_from_string(const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ret = match_string(usb_dr_modes, ARRAY_SIZE(usb_dr_modes), str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return (ret < 0) ? USB_DR_MODE_UNKNOWN : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) enum usb_dr_mode usb_get_dr_mode(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) const char *dr_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) err = device_property_read_string(dev, "dr_mode", &dr_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return USB_DR_MODE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return usb_get_dr_mode_from_string(dr_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) EXPORT_SYMBOL_GPL(usb_get_dr_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * usb_decode_interval - Decode bInterval into the time expressed in 1us unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * @epd: The descriptor of the endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * @speed: The speed that the endpoint works as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * Function returns the interval expressed in 1us unit for servicing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * endpoint for data transfers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) unsigned int usb_decode_interval(const struct usb_endpoint_descriptor *epd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) enum usb_device_speed speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) unsigned int interval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) switch (usb_endpoint_type(epd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case USB_ENDPOINT_XFER_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* uframes per NAK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (speed == USB_SPEED_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) interval = epd->bInterval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) case USB_ENDPOINT_XFER_ISOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) interval = 1 << (epd->bInterval - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case USB_ENDPOINT_XFER_BULK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /* uframes per NAK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (speed == USB_SPEED_HIGH && usb_endpoint_dir_out(epd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) interval = epd->bInterval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) case USB_ENDPOINT_XFER_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (speed >= USB_SPEED_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) interval = 1 << (epd->bInterval - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) interval = epd->bInterval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) interval *= (speed >= USB_SPEED_HIGH) ? 125 : 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) EXPORT_SYMBOL_GPL(usb_decode_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * of_usb_get_dr_mode_by_phy - Get dual role mode for the controller device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * which is associated with the given phy device_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * @np: Pointer to the given phy device_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * @arg0: phandle args[0] for phy's with #phy-cells >= 1, or -1 for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * phys which do not have phy-cells
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * In dts a usb controller associates with phy devices. The function gets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * the string from property 'dr_mode' of the controller associated with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * given phy device node, and returns the correspondig enum usb_dr_mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *np, int arg0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct device_node *controller = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct of_phandle_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) const char *dr_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) controller = of_find_node_with_property(controller, "phys");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (!of_device_is_available(controller))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (arg0 == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) args.np = of_parse_phandle(controller, "phys",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) args.args_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) err = of_parse_phandle_with_args(controller,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) "phys", "#phy-cells",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) index, &args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) of_node_put(args.np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (args.np == np && (args.args_count == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) args.args[0] == arg0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) goto finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) } while (args.np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) } while (controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) err = of_property_read_string(controller, "dr_mode", &dr_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) of_node_put(controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return USB_DR_MODE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return usb_get_dr_mode_from_string(dr_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) EXPORT_SYMBOL_GPL(of_usb_get_dr_mode_by_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * of_usb_host_tpl_support - to get if Targeted Peripheral List is supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * for given targeted hosts (non-PC hosts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * @np: Pointer to the given device_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * The function gets if the targeted hosts support TPL or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) bool of_usb_host_tpl_support(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return of_property_read_bool(np, "tpl-support");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) EXPORT_SYMBOL_GPL(of_usb_host_tpl_support);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * of_usb_update_otg_caps - to update usb otg capabilities according to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * the passed properties in DT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * @np: Pointer to the given device_node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * @otg_caps: Pointer to the target usb_otg_caps to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * The function updates the otg capabilities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int of_usb_update_otg_caps(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct usb_otg_caps *otg_caps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) u32 otg_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!otg_caps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (!of_property_read_u32(np, "otg-rev", &otg_rev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) switch (otg_rev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) case 0x0100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) case 0x0120:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) case 0x0130:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) case 0x0200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* Choose the lesser one if it's already been set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (otg_caps->otg_rev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) otg_caps->otg_rev = min_t(u16, otg_rev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) otg_caps->otg_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) otg_caps->otg_rev = otg_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) pr_err("%pOF: unsupported otg-rev: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) np, otg_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * otg-rev is mandatory for otg properties, if not passed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * we set it to be 0 and assume it's a legacy otg device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * Non-dt platform can set it afterwards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) otg_caps->otg_rev = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (of_property_read_bool(np, "hnp-disable"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) otg_caps->hnp_support = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (of_property_read_bool(np, "srp-disable"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) otg_caps->srp_support = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (of_property_read_bool(np, "adp-disable") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) (otg_caps->otg_rev < 0x0200))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) otg_caps->adp_support = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) EXPORT_SYMBOL_GPL(of_usb_update_otg_caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * usb_of_get_companion_dev - Find the companion device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * @dev: the device pointer to find a companion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * Find the companion device from platform bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * Takes a reference to the returned struct device which needs to be dropped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * after use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * Return: On success, a pointer to the companion device, %NULL on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct device *usb_of_get_companion_dev(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct device_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct platform_device *pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) node = of_parse_phandle(dev->of_node, "companion", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) pdev = of_find_device_by_node(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return pdev ? &pdev->dev : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) EXPORT_SYMBOL_GPL(usb_of_get_companion_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct dentry *usb_debug_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) EXPORT_SYMBOL_GPL(usb_debug_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static int __init usb_common_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) usb_debug_root = debugfs_create_dir("usb", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ledtrig_usb_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static void __exit usb_common_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ledtrig_usb_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) debugfs_remove_recursive(usb_debug_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) subsys_initcall(usb_common_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) module_exit(usb_common_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) MODULE_LICENSE("GPL");