// SPDX-License-Identifier: GPL-2.0 /* * Provides code common for host and device side USB. * * If either host side (ie. CONFIG_USB=y) or device side USB stack * (ie. CONFIG_USB_GADGET=y) is compiled in the kernel, this module is * compiled-in as well. Otherwise, if either of the two stacks is * compiled as module, this file is compiled as module as well.
*/
/** * usb_ep_type_string() - Returns human readable-name of the endpoint type. * @ep_type: The endpoint type to return human-readable name for. If it's not * any of the types: USB_ENDPOINT_XFER_{CONTROL, ISOC, BULK, INT}, * usually got by usb_endpoint_type(), the string 'unknown' will be returned.
*/ constchar *usb_ep_type_string(int ep_type)
{ if (ep_type < 0 || ep_type >= ARRAY_SIZE(ep_type_names)) return"unknown";
/** * usb_otg_state_string() - returns human readable name of OTG state. * @state: the OTG state to return the human readable name of. If it's not * any of the states defined in usb_otg_state enum, 'UNDEFINED' will be * returned.
*/ constchar *usb_otg_state_string(enum usb_otg_state state)
{ staticconstchar *const names[] = {
[OTG_STATE_A_IDLE] = "a_idle",
[OTG_STATE_A_WAIT_VRISE] = "a_wait_vrise",
[OTG_STATE_A_WAIT_BCON] = "a_wait_bcon",
[OTG_STATE_A_HOST] = "a_host",
[OTG_STATE_A_SUSPEND] = "a_suspend",
[OTG_STATE_A_PERIPHERAL] = "a_peripheral",
[OTG_STATE_A_WAIT_VFALL] = "a_wait_vfall",
[OTG_STATE_A_VBUS_ERR] = "a_vbus_err",
[OTG_STATE_B_IDLE] = "b_idle",
[OTG_STATE_B_SRP_INIT] = "b_srp_init",
[OTG_STATE_B_PERIPHERAL] = "b_peripheral",
[OTG_STATE_B_WAIT_ACON] = "b_wait_acon",
[OTG_STATE_B_HOST] = "b_host",
};
if (state < 0 || state >= ARRAY_SIZE(names)) return"UNDEFINED";
/** * usb_speed_string() - Returns human readable-name of the speed. * @speed: The speed to return human-readable name for. If it's not * any of the speeds defined in usb_device_speed enum, string for * USB_SPEED_UNKNOWN will be returned.
*/ constchar *usb_speed_string(enum usb_device_speed speed)
{ if (speed < 0 || speed >= ARRAY_SIZE(speed_names))
speed = USB_SPEED_UNKNOWN; return speed_names[speed];
}
EXPORT_SYMBOL_GPL(usb_speed_string);
/** * usb_get_maximum_speed - Get maximum requested speed for a given USB * controller. * @dev: Pointer to the given USB controller device * * The function gets the maximum speed string from property "maximum-speed", * and returns the corresponding enum usb_device_speed.
*/ enum usb_device_speed usb_get_maximum_speed(struct device *dev)
{ constchar *p = "maximum-speed"; int ret;
ret = device_property_match_property_string(dev, p, ssp_rate, ARRAY_SIZE(ssp_rate)); if (ret > 0) return USB_SPEED_SUPER_PLUS;
ret = device_property_match_property_string(dev, p, speed_names, ARRAY_SIZE(speed_names)); if (ret > 0) return ret;
/** * usb_get_maximum_ssp_rate - Get the signaling rate generation and lane count * of a SuperSpeed Plus capable device. * @dev: Pointer to the given USB controller device * * If the string from "maximum-speed" property is super-speed-plus-genXxY where * 'X' is the generation number and 'Y' is the number of lanes, then this * function returns the corresponding enum usb_ssp_rate.
*/ enum usb_ssp_rate usb_get_maximum_ssp_rate(struct device *dev)
{ constchar *maximum_speed; int ret;
ret = device_property_read_string(dev, "maximum-speed", &maximum_speed); if (ret < 0) return USB_SSP_GEN_UNKNOWN;
/** * usb_state_string - Returns human readable name for the state. * @state: The state to return a human-readable name for. If it's not * any of the states devices in usb_device_state_string enum, * the string UNKNOWN will be returned.
*/ constchar *usb_state_string(enum usb_device_state state)
{ staticconstchar *const names[] = {
[USB_STATE_NOTATTACHED] = "not attached",
[USB_STATE_ATTACHED] = "attached",
[USB_STATE_POWERED] = "powered",
[USB_STATE_RECONNECTING] = "reconnecting",
[USB_STATE_UNAUTHENTICATED] = "unauthenticated",
[USB_STATE_DEFAULT] = "default",
[USB_STATE_ADDRESS] = "addressed",
[USB_STATE_CONFIGURED] = "configured",
[USB_STATE_SUSPENDED] = "suspended",
};
if (state < 0 || state >= ARRAY_SIZE(names)) return"UNKNOWN";
/** * usb_get_dr_mode_from_string() - Get dual role mode for given string * @str: String to find the corresponding dual role mode for * * This function performs a lookup for the given string and returns the * corresponding enum usb_dr_mode. If no match for the string could be found, * 'USB_DR_MODE_UNKNOWN' is returned.
*/ staticenum usb_dr_mode usb_get_dr_mode_from_string(constchar *str)
{ int ret;
/** * usb_get_role_switch_default_mode - Get default mode for given device * @dev: Pointer to the given device * * The function gets string from property 'role-switch-default-mode', * and returns the corresponding enum usb_dr_mode.
*/ enum usb_dr_mode usb_get_role_switch_default_mode(struct device *dev)
{ constchar *str; int ret;
ret = device_property_read_string(dev, "role-switch-default-mode", &str); if (ret < 0) return USB_DR_MODE_UNKNOWN;
/** * usb_decode_interval - Decode bInterval into the time expressed in 1us unit * @epd: The descriptor of the endpoint * @speed: The speed that the endpoint works as * * Function returns the interval expressed in 1us unit for servicing * endpoint for data transfers.
*/ unsignedint usb_decode_interval(conststruct usb_endpoint_descriptor *epd, enum usb_device_speed speed)
{ unsignedint interval = 0;
switch (usb_endpoint_type(epd)) { case USB_ENDPOINT_XFER_CONTROL: /* uframes per NAK */ if (speed == USB_SPEED_HIGH)
interval = epd->bInterval; break; case USB_ENDPOINT_XFER_ISOC:
interval = 1 << (epd->bInterval - 1); break; case USB_ENDPOINT_XFER_BULK: /* uframes per NAK */ if (speed == USB_SPEED_HIGH && usb_endpoint_dir_out(epd))
interval = epd->bInterval; break; case USB_ENDPOINT_XFER_INT: if (speed >= USB_SPEED_HIGH)
interval = 1 << (epd->bInterval - 1); else
interval = epd->bInterval; break;
}
#ifdef CONFIG_OF /** * of_usb_get_dr_mode_by_phy - Get dual role mode for the controller device * which is associated with the given phy device_node * @np: Pointer to the given phy device_node * @arg0: phandle args[0] for phy's with #phy-cells >= 1, or -1 for * phys which do not have phy-cells * * In dts a usb controller associates with phy devices. The function gets * the string from property 'dr_mode' of the controller associated with the * given phy device node, and returns the correspondig enum usb_dr_mode.
*/ enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *np, int arg0)
{ struct device_node *controller; struct of_phandle_args args; constchar *dr_mode; int index; int err;
for_each_node_with_property(controller, "phys") { if (!of_device_is_available(controller)) continue;
index = 0; do { if (arg0 == -1) {
args.np = of_parse_phandle(controller, "phys",
index);
args.args_count = 0;
} else {
err = of_parse_phandle_with_args(controller, "phys", "#phy-cells",
index, &args); if (err) break;
}
of_node_put(args.np); if (args.np == np && (args.args_count == 0 ||
args.args[0] == arg0)) goto finish;
index++;
} while (args.np);
}
/** * of_usb_host_tpl_support - to get if Targeted Peripheral List is supported * for given targeted hosts (non-PC hosts) * @np: Pointer to the given device_node * * The function gets if the targeted hosts support TPL or not
*/ bool of_usb_host_tpl_support(struct device_node *np)
{ return of_property_read_bool(np, "tpl-support");
}
EXPORT_SYMBOL_GPL(of_usb_host_tpl_support);
/** * of_usb_update_otg_caps - to update usb otg capabilities according to * the passed properties in DT. * @np: Pointer to the given device_node * @otg_caps: Pointer to the target usb_otg_caps to be set * * The function updates the otg capabilities
*/ int of_usb_update_otg_caps(struct device_node *np, struct usb_otg_caps *otg_caps)
{
u32 otg_rev;
if (!otg_caps) return -EINVAL;
if (!of_property_read_u32(np, "otg-rev", &otg_rev)) { switch (otg_rev) { case 0x0100: case 0x0120: case 0x0130: case 0x0200: /* Choose the lesser one if it's already been set */ if (otg_caps->otg_rev)
otg_caps->otg_rev = min_t(u16, otg_rev,
otg_caps->otg_rev); else
otg_caps->otg_rev = otg_rev; break; default:
pr_err("%pOF: unsupported otg-rev: 0x%x\n",
np, otg_rev); return -EINVAL;
}
} else { /* * otg-rev is mandatory for otg properties, if not passed * we set it to be 0 and assume it's a legacy otg device. * Non-dt platform can set it afterwards.
*/
otg_caps->otg_rev = 0;
}
if (of_property_read_bool(np, "hnp-disable"))
otg_caps->hnp_support = false; if (of_property_read_bool(np, "srp-disable"))
otg_caps->srp_support = false; if (of_property_read_bool(np, "adp-disable") ||
(otg_caps->otg_rev < 0x0200))
otg_caps->adp_support = false;
/** * usb_of_get_companion_dev - Find the companion device * @dev: the device pointer to find a companion * * Find the companion device from platform bus. * * Takes a reference to the returned struct device which needs to be dropped * after use. * * Return: On success, a pointer to the companion device, %NULL on failure.
*/ struct device *usb_of_get_companion_dev(struct device *dev)
{ struct device_node *node; struct platform_device *pdev = NULL;
node = of_parse_phandle(dev->of_node, "companion", 0); if (node)
pdev = of_find_device_by_node(node);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.