This patch enables USB Test Mode control from a new "testmode" file in sysfs: - write "-1" to this file to get some help - write another value to select a test mode - read this file to get current TM register value This control can be used in USB Host or Device mode. This will be very useful in case of host mode. Signed-off-by: GÃrald BaÃza <gerald.baeza@xxxxxxxxxxxxxx> Signed-off-by: Praveena Nadahally <praveen.nadahally@xxxxxxxxxxxxxx> Acked-by: Linus Walleij <linus.walleij@xxxxxxxxxxxxxx> --- drivers/usb/musb/musb_core.c | 46 +++++++++++++++++++++++++++++++++++++++ drivers/usb/musb/musb_virthub.c | 3 -- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 630ae7f..291b185 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1812,12 +1812,58 @@ static DEVICE_ATTR(srp, 0644, NULL, musb_srp_store); #endif /* CONFIG_USB_GADGET_MUSB_HDRC */ +static ssize_t +musb_testmode_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t n) +{ + struct musb *musb = dev_to_musb(dev); + struct usb_hcd *hcd = musb_to_hcd(musb); + unsigned long val; + int status; + + if (sscanf(buf, "%lu", &val) < 1) { + dev_err(dev, "Invalid testmode value\n"); + dev_info(dev, " 1=TEST_J (set bit[1]=TSTJ)\n"); + dev_info(dev, " 2=TEST_K (set bit[2]=TSTK)\n"); + dev_info(dev, " 3=TEST_SE0_NAK (set bit[0]=TSTNAK)\n"); + dev_info(dev, " 4=TEST_PACKET (set bit[3]=TSTPKT)\n"); + dev_info(dev, " 5=TEST_FORCE_ENABLE (set bit[7]=FRH and bit[4]=FHS)\n"); + dev_info(dev, " 6=TEST_FIFO_ACCESS (set bit[6]=FIFOA)\n"); + return -EINVAL; + } + + /* Left shift the selected test mode and set bit[0] + * as expected by hub_control + */ + val = (val << 8) + 1; + + status = hcd->driver->hub_control(hcd, + SetPortFeature, USB_PORT_FEAT_TEST, val, + NULL, 0); + + return n; +} + +static ssize_t +musb_testmode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct musb *musb = dev_to_musb(dev); + unsigned long val; + + val = musb_readb(musb->mregs, MUSB_TESTMODE); + dev_info(dev, "Register MUSB_TESTMODE = 0x%x\n", val); + + return 1; +} +static DEVICE_ATTR(testmode, 0644, musb_testmode_show, musb_testmode_store); + static struct attribute *musb_attributes[] = { &dev_attr_mode.attr, &dev_attr_vbus.attr, #ifdef CONFIG_USB_GADGET_MUSB_HDRC &dev_attr_srp.attr, #endif + &dev_attr_testmode.attr, NULL }; diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index 489104a..583bbec 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -381,9 +381,6 @@ int musb_hub_control( musb_port_suspend(musb, true); break; case USB_PORT_FEAT_TEST: - if (unlikely(is_host_active(musb))) - goto error; - wIndex >>= 8; switch (wIndex) { case 1: -- 1.7.2.dirty -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html