Commit 8f900a9a authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Felipe Balbi

usb: gadget: consider link speed for bMaxPower

The USB 2.0 specification says that bMaxPower is the maximum power
consumption expressed in 2 mA units and the USB 3.0 specification says
that it is expressed in 8 mA units.

This patch renames bMaxPower to MaxPower and the various /2 and *2 are
removed. Before reporting the config descriptor, the proper value is
computer based on the speed, all in-tree users are updated. MaxPower is
also increased to u16 so we can store the nokia gadget value which is
larger than the max value allowed for u8.
Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 98f3a1b9
...@@ -320,6 +320,25 @@ int usb_interface_id(struct usb_configuration *config, ...@@ -320,6 +320,25 @@ int usb_interface_id(struct usb_configuration *config,
} }
EXPORT_SYMBOL_GPL(usb_interface_id); EXPORT_SYMBOL_GPL(usb_interface_id);
static u8 encode_bMaxPower(enum usb_device_speed speed,
struct usb_configuration *c)
{
unsigned val;
if (c->MaxPower)
val = c->MaxPower;
else
val = CONFIG_USB_GADGET_VBUS_DRAW;
if (!val)
return 0;
switch (speed) {
case USB_SPEED_SUPER:
return DIV_ROUND_UP(val, 8);
default:
return DIV_ROUND_UP(val, 2);
};
}
static int config_buf(struct usb_configuration *config, static int config_buf(struct usb_configuration *config,
enum usb_device_speed speed, void *buf, u8 type) enum usb_device_speed speed, void *buf, u8 type)
{ {
...@@ -339,7 +358,7 @@ static int config_buf(struct usb_configuration *config, ...@@ -339,7 +358,7 @@ static int config_buf(struct usb_configuration *config,
c->bConfigurationValue = config->bConfigurationValue; c->bConfigurationValue = config->bConfigurationValue;
c->iConfiguration = config->iConfiguration; c->iConfiguration = config->iConfiguration;
c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes; c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes;
c->bMaxPower = config->bMaxPower ? : (CONFIG_USB_GADGET_VBUS_DRAW / 2); c->bMaxPower = encode_bMaxPower(speed, config);
/* There may be e.g. OTG descriptors */ /* There may be e.g. OTG descriptors */
if (config->descriptors) { if (config->descriptors) {
...@@ -656,7 +675,7 @@ static int set_config(struct usb_composite_dev *cdev, ...@@ -656,7 +675,7 @@ static int set_config(struct usb_composite_dev *cdev,
} }
/* when we return, be sure our power usage is valid */ /* when we return, be sure our power usage is valid */
power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW; power = c->MaxPower ? c->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW;
done: done:
usb_gadget_vbus_draw(gadget, power); usb_gadget_vbus_draw(gadget, power);
if (result >= 0 && cdev->delayed_status) if (result >= 0 && cdev->delayed_status)
...@@ -1518,10 +1537,10 @@ composite_resume(struct usb_gadget *gadget) ...@@ -1518,10 +1537,10 @@ composite_resume(struct usb_gadget *gadget)
f->resume(f); f->resume(f);
} }
maxpower = cdev->config->bMaxPower; maxpower = cdev->config->MaxPower;
usb_gadget_vbus_draw(gadget, maxpower ? usb_gadget_vbus_draw(gadget, maxpower ?
(2 * maxpower) : CONFIG_USB_GADGET_VBUS_DRAW); maxpower : CONFIG_USB_GADGET_VBUS_DRAW);
} }
cdev->suspended = 0; cdev->suspended = 0;
......
...@@ -125,7 +125,7 @@ static struct usb_configuration midi_config = { ...@@ -125,7 +125,7 @@ static struct usb_configuration midi_config = {
.bConfigurationValue = 1, .bConfigurationValue = 1,
/* .iConfiguration = DYNAMIC */ /* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_ONE, .bmAttributes = USB_CONFIG_ATT_ONE,
.bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, .MaxPower = CONFIG_USB_GADGET_VBUS_DRAW,
}; };
static int __init midi_bind_config(struct usb_configuration *c) static int __init midi_bind_config(struct usb_configuration *c)
......
...@@ -133,7 +133,7 @@ static struct usb_configuration nokia_config_500ma_driver = { ...@@ -133,7 +133,7 @@ static struct usb_configuration nokia_config_500ma_driver = {
.bConfigurationValue = 1, .bConfigurationValue = 1,
/* .iConfiguration = DYNAMIC */ /* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_ONE, .bmAttributes = USB_CONFIG_ATT_ONE,
.bMaxPower = 250, /* 500mA */ .MaxPower = 500,
}; };
static struct usb_configuration nokia_config_100ma_driver = { static struct usb_configuration nokia_config_100ma_driver = {
...@@ -141,7 +141,7 @@ static struct usb_configuration nokia_config_100ma_driver = { ...@@ -141,7 +141,7 @@ static struct usb_configuration nokia_config_100ma_driver = {
.bConfigurationValue = 2, .bConfigurationValue = 2,
/* .iConfiguration = DYNAMIC */ /* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
.bMaxPower = 50, /* 100 mA */ .MaxPower = 100,
}; };
static int __init nokia_bind(struct usb_composite_dev *cdev) static int __init nokia_bind(struct usb_composite_dev *cdev)
......
...@@ -336,7 +336,7 @@ static struct usb_configuration webcam_config_driver = { ...@@ -336,7 +336,7 @@ static struct usb_configuration webcam_config_driver = {
.bConfigurationValue = 1, .bConfigurationValue = 1,
.iConfiguration = 0, /* dynamic */ .iConfiguration = 0, /* dynamic */
.bmAttributes = USB_CONFIG_ATT_SELFPOWER, .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
.bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, .MaxPower = CONFIG_USB_GADGET_VBUS_DRAW,
}; };
static int /* __init_or_exit */ static int /* __init_or_exit */
......
...@@ -184,7 +184,8 @@ int config_ep_by_speed(struct usb_gadget *g, struct usb_function *f, ...@@ -184,7 +184,8 @@ int config_ep_by_speed(struct usb_gadget *g, struct usb_function *f,
* @bConfigurationValue: Copied into configuration descriptor. * @bConfigurationValue: Copied into configuration descriptor.
* @iConfiguration: Copied into configuration descriptor. * @iConfiguration: Copied into configuration descriptor.
* @bmAttributes: Copied into configuration descriptor. * @bmAttributes: Copied into configuration descriptor.
* @bMaxPower: Copied into configuration descriptor. * @MaxPower: Power consumtion in mA. Used to compute bMaxPower in the
* configuration descriptor after considering the bus speed.
* @cdev: assigned by @usb_add_config() before calling @bind(); this is * @cdev: assigned by @usb_add_config() before calling @bind(); this is
* the device associated with this configuration. * the device associated with this configuration.
* *
...@@ -230,7 +231,7 @@ struct usb_configuration { ...@@ -230,7 +231,7 @@ struct usb_configuration {
u8 bConfigurationValue; u8 bConfigurationValue;
u8 iConfiguration; u8 iConfiguration;
u8 bmAttributes; u8 bmAttributes;
u8 bMaxPower; u16 MaxPower;
struct usb_composite_dev *cdev; struct usb_composite_dev *cdev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment