@@ -7,6 +7,8 @@ Description:
The file can show/change the drd mode of usb.
Write the following string to change the mode:
+ "host" - switching mode from peripheral to host.
+ "peripheral" - switching mode from host to peripheral.
"b-device" - switching mode as forced b-device mode.
Read the file, then it shows the following strings:
@@ -570,12 +570,29 @@ static void usb3_mode_a_host(struct renesas_usb3 *usb3)
usb3_set_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON);
}
+static void usb3_mode_a_peri(struct renesas_usb3 *usb3)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&usb3->lock, flags);
+ usb3_set_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON);
+ usb3_set_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON);
+ usb3_check_vbus(usb3);
+ spin_unlock_irqrestore(&usb3->lock, flags);
+}
+
static void usb3_mode_b_peri(struct renesas_usb3 *usb3)
{
usb3_set_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON);
usb3_clear_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON);
}
+static void usb3_mode_b_host(struct renesas_usb3 *usb3)
+{
+ usb3_clear_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON);
+ usb3_clear_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON);
+}
+
static bool usb3_is_a_device(struct renesas_usb3 *usb3)
{
return !(usb3_read(usb3, USB3_USB_OTG_STA) & USB_OTG_IDMON);
@@ -1865,8 +1882,30 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
usb3->forced_b_device = true;
renesas_usb3_init_forced_b_device(usb3);
} else {
+ bool new_mode_is_host;
+
usb3->forced_b_device = false;
- return -EINVAL;
+ if (!strncmp(buf, "host", strlen("host")))
+ new_mode_is_host = true;
+ else if (!strncmp(buf, "peripheral", strlen("peripheral")))
+ new_mode_is_host = false;
+ else
+ return -EINVAL;
+
+ if (new_mode_is_host == usb3_is_host(usb3))
+ return -EINVAL;
+
+ if (new_mode_is_host) {
+ if (usb3_is_a_device(usb3))
+ usb3_mode_a_host(usb3);
+ else
+ usb3_mode_b_host(usb3);
+ } else {
+ if (usb3_is_a_device(usb3))
+ usb3_mode_a_peri(usb3);
+ else
+ usb3_mode_b_peri(usb3);
+ }
}
return count;
This patch adds support for usb role swap via sysfs "role". For example: 1) Connect a usb cable using 2 Salvator-X boards. - For A-Device, the cable is connected to CN11 (USB3.0 ch0). - For B-Device, the cable is connected to CN9 (USB2.0 ch0). 2) On A-Device, you input the following command: # echo peripheral > /sys/devices/platform/soc/ee020000.usb/role 3) On B-Device, you input the following command: # echo host > /sys/devices/platform/soc/ee080200.usb-phy/role Then, the A-Device acts as a peripheral and the B-Device acts as a host. Please note that A-Device must input the following command if you want the board to act as a host again. # echo host > /sys/devices/platform/soc/ee020000.usb/role Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> --- .../ABI/testing/sysfs-platform-renesas_usb3 | 2 ++ drivers/usb/gadget/udc/renesas_usb3.c | 41 +++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-)