All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/3] usb: gadget: udc: renesas_usb3: add USB3.0 DRD support
@ 2017-03-30  2:16 Yoshihiro Shimoda
  2017-03-30  2:16 ` [PATCH v3 1/3] usb: gadget: udc: add USB ID signal monitoring Yoshihiro Shimoda
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Yoshihiro Shimoda @ 2017-03-30  2:16 UTC (permalink / raw)
  To: balbi; +Cc: gregkh, linux-usb, linux-renesas-soc, Yoshihiro Shimoda

This patch set is based on the latest Felipe's usb.bit / testing/next branch
(commit id = 29986993f67341493988b6c5d68e0653061975b2).

The USB3.0 DRD controller on R-Car Gen3 can change the role via DRD_CON
register in the periperal side sadly, so this patch adds support
for usb role swap feature in this udc driver.
Furtunately, the default setting of the DRD is host side, if a user want
to use host side only, we can handle it easily just to disable the udc driver.

Changes from v2:
 - Remove hardcoded mode setting as B-Peripheral in patch 1/3.
 - Merge usb3_mode_[ab]_{host,peri}(usb3) to usb3_mode_config(usb3, host, a_dev)

Changes from v1:
 - Remove patch 1 not to add "b-device" mode.
 - Add device_remove_file() calling in renesas_usb3_remove().
 - Use usb3_connect() instead of usb3_check_vbus() in usb3_mode_a_peri().

Yoshihiro Shimoda (3):
  usb: gadget: udc: add USB ID signal monitoring
  usb: gadget: udc: renesas_usb3: add extcon support
  usb: gadget: udc: renesas_usb3: add support for usb role swap

 .../ABI/testing/sysfs-platform-renesas_usb3        |  15 ++
 drivers/usb/gadget/udc/Kconfig                     |   1 +
 drivers/usb/gadget/udc/renesas_usb3.c              | 164 ++++++++++++++++++++-
 3 files changed, 175 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-platform-renesas_usb3

-- 
1.9.1

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v3 1/3] usb: gadget: udc: add USB ID signal monitoring
  2017-03-30  2:16 [PATCH v3 0/3] usb: gadget: udc: renesas_usb3: add USB3.0 DRD support Yoshihiro Shimoda
@ 2017-03-30  2:16 ` Yoshihiro Shimoda
  2017-03-30  2:16 ` [PATCH v3 2/3] usb: gadget: udc: renesas_usb3: add extcon support Yoshihiro Shimoda
  2017-03-30  2:16 ` [PATCH v3 3/3] usb: gadget: udc: renesas_usb3: add support for usb role swap Yoshihiro Shimoda
  2 siblings, 0 replies; 6+ messages in thread
From: Yoshihiro Shimoda @ 2017-03-30  2:16 UTC (permalink / raw)
  To: balbi; +Cc: gregkh, linux-usb, linux-renesas-soc, Yoshihiro Shimoda

This usb 3.0 peripheral controller has a register (USB_OTG_STA) to monitor
the USB ID signal. So, this patch adds the ID signal monitoring to change
the mode to host (A-Host) or peripheral (B-Peripheral).
This patch also removes hardcoded setting as B-Peripheral mode.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 drivers/usb/gadget/udc/renesas_usb3.c | 67 ++++++++++++++++++++++++++++++++---
 1 file changed, 63 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c
index 2218f91..3e96c56 100644
--- a/drivers/usb/gadget/udc/renesas_usb3.c
+++ b/drivers/usb/gadget/udc/renesas_usb3.c
@@ -37,6 +37,9 @@
 #define USB3_USB_INT_ENA_2	0x22c
 #define USB3_STUP_DAT_0		0x230
 #define USB3_STUP_DAT_1		0x234
+#define USB3_USB_OTG_STA	0x268
+#define USB3_USB_OTG_INT_STA	0x26c
+#define USB3_USB_OTG_INT_ENA	0x270
 #define USB3_P0_MOD		0x280
 #define USB3_P0_CON		0x288
 #define USB3_P0_STA		0x28c
@@ -124,6 +127,9 @@
 /* USB_INT_ENA_2 and USB_INT_STA_2 */
 #define USB_INT_2_PIPE(n)	BIT(n)
 
+/* USB_OTG_STA, USB_OTG_INT_STA and USB_OTG_INT_ENA */
+#define USB_OTG_IDMON		BIT(4)
+
 /* P0_MOD */
 #define P0_MOD_DIR		BIT(6)
 
@@ -362,10 +368,6 @@ static void usb3_init_axi_bridge(struct renesas_usb3 *usb3)
 
 static void usb3_init_epc_registers(struct renesas_usb3 *usb3)
 {
-	/* FIXME: How to change host / peripheral mode as well? */
-	usb3_set_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON);
-	usb3_clear_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON);
-
 	usb3_write(usb3, ~0, USB3_USB_INT_STA_1);
 	usb3_enable_irq_1(usb3, USB_INT_1_VBUS_CNG);
 }
@@ -538,11 +540,49 @@ static void usb3_check_vbus(struct renesas_usb3 *usb3)
 	}
 }
 
+static void usb3_set_mode(struct renesas_usb3 *usb3, bool host)
+{
+	if (host)
+		usb3_clear_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON);
+	else
+		usb3_set_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON);
+}
+
+static void usb3_vbus_out(struct renesas_usb3 *usb3, bool enable)
+{
+	if (enable)
+		usb3_set_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON);
+	else
+		usb3_clear_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON);
+}
+
+static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev)
+{
+	usb3_set_mode(usb3, host);
+	usb3_vbus_out(usb3, a_dev);
+}
+
+static bool usb3_is_a_device(struct renesas_usb3 *usb3)
+{
+	return !(usb3_read(usb3, USB3_USB_OTG_STA) & USB_OTG_IDMON);
+}
+
+static void usb3_check_id(struct renesas_usb3 *usb3)
+{
+	if (usb3_is_a_device(usb3))
+		usb3_mode_config(usb3, true, true);
+	else
+		usb3_mode_config(usb3, false, false);
+}
+
 static void renesas_usb3_init_controller(struct renesas_usb3 *usb3)
 {
 	usb3_init_axi_bridge(usb3);
 	usb3_init_epc_registers(usb3);
+	usb3_write(usb3, USB_OTG_IDMON, USB3_USB_OTG_INT_STA);
+	usb3_write(usb3, USB_OTG_IDMON, USB3_USB_OTG_INT_ENA);
 
+	usb3_check_id(usb3);
 	usb3_check_vbus(usb3);
 }
 
@@ -551,6 +591,7 @@ static void renesas_usb3_stop_controller(struct renesas_usb3 *usb3)
 	usb3_disconnect(usb3);
 	usb3_write(usb3, 0, USB3_P0_INT_ENA);
 	usb3_write(usb3, 0, USB3_PN_INT_ENA);
+	usb3_write(usb3, 0, USB3_USB_OTG_INT_ENA);
 	usb3_write(usb3, 0, USB3_USB_INT_ENA_1);
 	usb3_write(usb3, 0, USB3_USB_INT_ENA_2);
 	usb3_write(usb3, 0, USB3_AXI_INT_ENA);
@@ -1474,10 +1515,22 @@ static void usb3_irq_epc_int_2(struct renesas_usb3 *usb3, u32 int_sta_2)
 	}
 }
 
+static void usb3_irq_idmon_change(struct renesas_usb3 *usb3)
+{
+	usb3_check_id(usb3);
+}
+
+static void usb3_irq_otg_int(struct renesas_usb3 *usb3, u32 otg_int_sta)
+{
+	if (otg_int_sta & USB_OTG_IDMON)
+		usb3_irq_idmon_change(usb3);
+}
+
 static void usb3_irq_epc(struct renesas_usb3 *usb3)
 {
 	u32 int_sta_1 = usb3_read(usb3, USB3_USB_INT_STA_1);
 	u32 int_sta_2 = usb3_read(usb3, USB3_USB_INT_STA_2);
+	u32 otg_int_sta = usb3_read(usb3, USB3_USB_OTG_INT_STA);
 
 	int_sta_1 &= usb3_read(usb3, USB3_USB_INT_ENA_1);
 	if (int_sta_1) {
@@ -1488,6 +1541,12 @@ static void usb3_irq_epc(struct renesas_usb3 *usb3)
 	int_sta_2 &= usb3_read(usb3, USB3_USB_INT_ENA_2);
 	if (int_sta_2)
 		usb3_irq_epc_int_2(usb3, int_sta_2);
+
+	otg_int_sta &= usb3_read(usb3, USB3_USB_OTG_INT_ENA);
+	if (otg_int_sta) {
+		usb3_write(usb3, otg_int_sta, USB3_USB_OTG_INT_STA);
+		usb3_irq_otg_int(usb3, otg_int_sta);
+	}
 }
 
 static irqreturn_t renesas_usb3_irq(int irq, void *_usb3)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 2/3] usb: gadget: udc: renesas_usb3: add extcon support
  2017-03-30  2:16 [PATCH v3 0/3] usb: gadget: udc: renesas_usb3: add USB3.0 DRD support Yoshihiro Shimoda
  2017-03-30  2:16 ` [PATCH v3 1/3] usb: gadget: udc: add USB ID signal monitoring Yoshihiro Shimoda
@ 2017-03-30  2:16 ` Yoshihiro Shimoda
  2017-03-30  2:16 ` [PATCH v3 3/3] usb: gadget: udc: renesas_usb3: add support for usb role swap Yoshihiro Shimoda
  2 siblings, 0 replies; 6+ messages in thread
From: Yoshihiro Shimoda @ 2017-03-30  2:16 UTC (permalink / raw)
  To: balbi; +Cc: gregkh, linux-usb, linux-renesas-soc, Yoshihiro Shimoda

This patch adds extcon support to see VBUS/ID signal states.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 drivers/usb/gadget/udc/Kconfig        |  1 +
 drivers/usb/gadget/udc/renesas_usb3.c | 43 +++++++++++++++++++++++++++++++++--
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig
index 4b69f28..66cb00b 100644
--- a/drivers/usb/gadget/udc/Kconfig
+++ b/drivers/usb/gadget/udc/Kconfig
@@ -191,6 +191,7 @@ config USB_RENESAS_USBHS_UDC
 config USB_RENESAS_USB3
 	tristate 'Renesas USB3.0 Peripheral controller'
 	depends on ARCH_RENESAS || COMPILE_TEST
+	depends on EXTCON
 	help
 	   Renesas USB3.0 Peripheral controller is a USB peripheral controller
 	   that supports super, high, and full speed USB 3.0 data transfers.
diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c
index 3e96c56..a1e79fc 100644
--- a/drivers/usb/gadget/udc/renesas_usb3.c
+++ b/drivers/usb/gadget/udc/renesas_usb3.c
@@ -10,6 +10,7 @@
 
 #include <linux/delay.h>
 #include <linux/err.h>
+#include <linux/extcon.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -263,6 +264,8 @@ struct renesas_usb3 {
 
 	struct usb_gadget gadget;
 	struct usb_gadget_driver *driver;
+	struct extcon_dev *extcon;
+	struct work_struct extcon_work;
 
 	struct renesas_usb3_ep *usb3_ep;
 	int num_usb3_eps;
@@ -275,6 +278,8 @@ struct renesas_usb3 {
 	u8 ep0_buf[USB3_EP0_BUF_SIZE];
 	bool softconnect;
 	bool workaround_for_vbus;
+	bool extcon_host;		/* check id and set EXTCON_USB_HOST */
+	bool extcon_usb;		/* check vbus and set EXTCON_USB */
 };
 
 #define gadget_to_renesas_usb3(_gadget)	\
@@ -338,6 +343,15 @@ static int usb3_wait(struct renesas_usb3 *usb3, u32 reg, u32 mask,
 	return -EBUSY;
 }
 
+static void renesas_usb3_extcon_work(struct work_struct *work)
+{
+	struct renesas_usb3 *usb3 = container_of(work, struct renesas_usb3,
+						 extcon_work);
+
+	extcon_set_state_sync(usb3->extcon, EXTCON_USB_HOST, usb3->extcon_host);
+	extcon_set_state_sync(usb3->extcon, EXTCON_USB, usb3->extcon_usb);
+}
+
 static void usb3_enable_irq_1(struct renesas_usb3 *usb3, u32 bits)
 {
 	usb3_set_bit(usb3, bits, USB3_USB_INT_ENA_1);
@@ -533,10 +547,14 @@ static void usb3_check_vbus(struct renesas_usb3 *usb3)
 	if (usb3->workaround_for_vbus) {
 		usb3_connect(usb3);
 	} else {
-		if (usb3_read(usb3, USB3_USB_STA) & USB_STA_VBUS_STA)
+		usb3->extcon_usb = !!(usb3_read(usb3, USB3_USB_STA) &
+							USB_STA_VBUS_STA);
+		if (usb3->extcon_usb)
 			usb3_connect(usb3);
 		else
 			usb3_disconnect(usb3);
+
+		schedule_work(&usb3->extcon_work);
 	}
 }
 
@@ -569,10 +587,14 @@ static bool usb3_is_a_device(struct renesas_usb3 *usb3)
 
 static void usb3_check_id(struct renesas_usb3 *usb3)
 {
-	if (usb3_is_a_device(usb3))
+	usb3->extcon_host = usb3_is_a_device(usb3);
+
+	if (usb3->extcon_host)
 		usb3_mode_config(usb3, true, true);
 	else
 		usb3_mode_config(usb3, false, false);
+
+	schedule_work(&usb3->extcon_work);
 }
 
 static void renesas_usb3_init_controller(struct renesas_usb3 *usb3)
@@ -1953,6 +1975,12 @@ static void renesas_usb3_init_ram(struct renesas_usb3 *usb3, struct device *dev,
 };
 MODULE_DEVICE_TABLE(of, usb3_of_match);
 
+static const unsigned int renesas_usb3_cable[] = {
+	EXTCON_USB,
+	EXTCON_USB_HOST,
+	EXTCON_NONE,
+};
+
 static int renesas_usb3_probe(struct platform_device *pdev)
 {
 	struct renesas_usb3 *usb3;
@@ -1996,6 +2024,17 @@ static int renesas_usb3_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 
+	INIT_WORK(&usb3->extcon_work, renesas_usb3_extcon_work);
+	usb3->extcon = devm_extcon_dev_allocate(&pdev->dev, renesas_usb3_cable);
+	if (IS_ERR(usb3->extcon))
+		return PTR_ERR(usb3->extcon);
+
+	ret = devm_extcon_dev_register(&pdev->dev, usb3->extcon);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register extcon\n");
+		return ret;
+	}
+
 	/* for ep0 handling */
 	usb3->ep0_req = __renesas_usb3_ep_alloc_request(GFP_KERNEL);
 	if (!usb3->ep0_req)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 3/3] usb: gadget: udc: renesas_usb3: add support for usb role swap
  2017-03-30  2:16 [PATCH v3 0/3] usb: gadget: udc: renesas_usb3: add USB3.0 DRD support Yoshihiro Shimoda
  2017-03-30  2:16 ` [PATCH v3 1/3] usb: gadget: udc: add USB ID signal monitoring Yoshihiro Shimoda
  2017-03-30  2:16 ` [PATCH v3 2/3] usb: gadget: udc: renesas_usb3: add extcon support Yoshihiro Shimoda
@ 2017-03-30  2:16 ` Yoshihiro Shimoda
  2017-03-30 10:36   ` Felipe Balbi
  2 siblings, 1 reply; 6+ messages in thread
From: Yoshihiro Shimoda @ 2017-03-30  2:16 UTC (permalink / raw)
  To: balbi; +Cc: gregkh, linux-usb, linux-renesas-soc, Yoshihiro Shimoda

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        | 15 ++++++
 drivers/usb/gadget/udc/renesas_usb3.c              | 56 ++++++++++++++++++++++
 2 files changed, 71 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-platform-renesas_usb3

diff --git a/Documentation/ABI/testing/sysfs-platform-renesas_usb3 b/Documentation/ABI/testing/sysfs-platform-renesas_usb3
new file mode 100644
index 0000000..1f63190
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-platform-renesas_usb3
@@ -0,0 +1,15 @@
+What:		/sys/devices/platform/<udc-name>/role
+Date:		March 2017
+KernelVersion:	4.13
+Contact:	Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Description:
+		This file can be read and write.
+		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.
+
+		Read the file, then it shows the following strings:
+		 "host" - The mode is host now.
+		 "peripheral" - The mode is peripheral now.
diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c
index a1e79fc..5a2d845 100644
--- a/drivers/usb/gadget/udc/renesas_usb3.c
+++ b/drivers/usb/gadget/udc/renesas_usb3.c
@@ -372,6 +372,11 @@ static void usb3_disable_pipe_irq(struct renesas_usb3 *usb3, int num)
 	usb3_clear_bit(usb3, USB_INT_2_PIPE(num), USB3_USB_INT_ENA_2);
 }
 
+static bool usb3_is_host(struct renesas_usb3 *usb3)
+{
+	return !(usb3_read(usb3, USB3_DRD_CON) & DRD_CON_PERI_CON);
+}
+
 static void usb3_init_axi_bridge(struct renesas_usb3 *usb3)
 {
 	/* Set AXI_INT */
@@ -576,8 +581,14 @@ static void usb3_vbus_out(struct renesas_usb3 *usb3, bool enable)
 
 static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&usb3->lock, flags);
 	usb3_set_mode(usb3, host);
 	usb3_vbus_out(usb3, a_dev);
+	if (!host && a_dev)		/* for A-Peripheral */
+		usb3_connect(usb3);
+	spin_unlock_irqrestore(&usb3->lock, flags);
 }
 
 static bool usb3_is_a_device(struct renesas_usb3 *usb3)
@@ -1837,11 +1848,49 @@ static int renesas_usb3_set_selfpowered(struct usb_gadget *gadget, int is_self)
 	.set_selfpowered	= renesas_usb3_set_selfpowered,
 };
 
+static ssize_t role_store(struct device *dev, struct device_attribute *attr,
+			  const char *buf, size_t count)
+{
+	struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
+	bool new_mode_is_host;
+
+	if (!usb3->driver)
+		return -ENODEV;
+
+	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;
+
+	usb3_mode_config(usb3, new_mode_is_host, usb3_is_a_device(usb3));
+
+	return count;
+}
+
+static ssize_t role_show(struct device *dev, struct device_attribute *attr,
+			 char *buf)
+{
+	struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
+
+	if (!usb3->driver)
+		return -ENODEV;
+
+	return sprintf(buf, "%s\n", usb3_is_host(usb3) ? "host" : "peripheral");
+}
+static DEVICE_ATTR_RW(role);
+
 /*------- platform_driver ------------------------------------------------*/
 static int renesas_usb3_remove(struct platform_device *pdev)
 {
 	struct renesas_usb3 *usb3 = platform_get_drvdata(pdev);
 
+	device_remove_file(&pdev->dev, &dev_attr_role);
+
 	pm_runtime_put(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
@@ -2044,6 +2093,10 @@ static int renesas_usb3_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto err_add_udc;
 
+	ret = device_create_file(&pdev->dev, &dev_attr_role);
+	if (ret < 0)
+		goto err_dev_create;
+
 	usb3->workaround_for_vbus = priv->workaround_for_vbus;
 
 	pm_runtime_enable(&pdev->dev);
@@ -2053,6 +2106,9 @@ static int renesas_usb3_probe(struct platform_device *pdev)
 
 	return 0;
 
+err_dev_create:
+	usb_del_gadget_udc(&usb3->gadget);
+
 err_add_udc:
 	__renesas_usb3_ep_free_request(usb3->ep0_req);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v3 3/3] usb: gadget: udc: renesas_usb3: add support for usb role swap
  2017-03-30  2:16 ` [PATCH v3 3/3] usb: gadget: udc: renesas_usb3: add support for usb role swap Yoshihiro Shimoda
@ 2017-03-30 10:36   ` Felipe Balbi
  2017-03-31  1:58     ` Yoshihiro Shimoda
  0 siblings, 1 reply; 6+ messages in thread
From: Felipe Balbi @ 2017-03-30 10:36 UTC (permalink / raw)
  To: Yoshihiro Shimoda, Greg KH
  Cc: gregkh, linux-usb, linux-renesas-soc, Yoshihiro Shimoda

[-- Attachment #1: Type: text/plain, Size: 5848 bytes --]


Hi,

Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> writes:
> 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        | 15 ++++++
>  drivers/usb/gadget/udc/renesas_usb3.c              | 56 ++++++++++++++++++++++
>  2 files changed, 71 insertions(+)
>  create mode 100644 Documentation/ABI/testing/sysfs-platform-renesas_usb3
>
> diff --git a/Documentation/ABI/testing/sysfs-platform-renesas_usb3 b/Documentation/ABI/testing/sysfs-platform-renesas_usb3
> new file mode 100644
> index 0000000..1f63190
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-platform-renesas_usb3
> @@ -0,0 +1,15 @@
> +What:		/sys/devices/platform/<udc-name>/role

I have one question here. This seems to imply that platform devices have
a "role" file which is not true for all platforms devices. I really
don't have a suggestion as to how this could/should be written out,
though :-s

Greg, any suggestions?

(keeping patch below for reference only)

> +Date:		March 2017
> +KernelVersion:	4.13
> +Contact:	Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> +Description:
> +		This file can be read and write.
> +		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.
> +
> +		Read the file, then it shows the following strings:
> +		 "host" - The mode is host now.
> +		 "peripheral" - The mode is peripheral now.
> diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c
> index a1e79fc..5a2d845 100644
> --- a/drivers/usb/gadget/udc/renesas_usb3.c
> +++ b/drivers/usb/gadget/udc/renesas_usb3.c
> @@ -372,6 +372,11 @@ static void usb3_disable_pipe_irq(struct renesas_usb3 *usb3, int num)
>  	usb3_clear_bit(usb3, USB_INT_2_PIPE(num), USB3_USB_INT_ENA_2);
>  }
>  
> +static bool usb3_is_host(struct renesas_usb3 *usb3)
> +{
> +	return !(usb3_read(usb3, USB3_DRD_CON) & DRD_CON_PERI_CON);
> +}
> +
>  static void usb3_init_axi_bridge(struct renesas_usb3 *usb3)
>  {
>  	/* Set AXI_INT */
> @@ -576,8 +581,14 @@ static void usb3_vbus_out(struct renesas_usb3 *usb3, bool enable)
>  
>  static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev)
>  {
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&usb3->lock, flags);
>  	usb3_set_mode(usb3, host);
>  	usb3_vbus_out(usb3, a_dev);
> +	if (!host && a_dev)		/* for A-Peripheral */
> +		usb3_connect(usb3);
> +	spin_unlock_irqrestore(&usb3->lock, flags);
>  }
>  
>  static bool usb3_is_a_device(struct renesas_usb3 *usb3)
> @@ -1837,11 +1848,49 @@ static int renesas_usb3_set_selfpowered(struct usb_gadget *gadget, int is_self)
>  	.set_selfpowered	= renesas_usb3_set_selfpowered,
>  };
>  
> +static ssize_t role_store(struct device *dev, struct device_attribute *attr,
> +			  const char *buf, size_t count)
> +{
> +	struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
> +	bool new_mode_is_host;
> +
> +	if (!usb3->driver)
> +		return -ENODEV;
> +
> +	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;
> +
> +	usb3_mode_config(usb3, new_mode_is_host, usb3_is_a_device(usb3));
> +
> +	return count;
> +}
> +
> +static ssize_t role_show(struct device *dev, struct device_attribute *attr,
> +			 char *buf)
> +{
> +	struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
> +
> +	if (!usb3->driver)
> +		return -ENODEV;
> +
> +	return sprintf(buf, "%s\n", usb3_is_host(usb3) ? "host" : "peripheral");
> +}
> +static DEVICE_ATTR_RW(role);
> +
>  /*------- platform_driver ------------------------------------------------*/
>  static int renesas_usb3_remove(struct platform_device *pdev)
>  {
>  	struct renesas_usb3 *usb3 = platform_get_drvdata(pdev);
>  
> +	device_remove_file(&pdev->dev, &dev_attr_role);
> +
>  	pm_runtime_put(&pdev->dev);
>  	pm_runtime_disable(&pdev->dev);
>  
> @@ -2044,6 +2093,10 @@ static int renesas_usb3_probe(struct platform_device *pdev)
>  	if (ret < 0)
>  		goto err_add_udc;
>  
> +	ret = device_create_file(&pdev->dev, &dev_attr_role);
> +	if (ret < 0)
> +		goto err_dev_create;
> +
>  	usb3->workaround_for_vbus = priv->workaround_for_vbus;
>  
>  	pm_runtime_enable(&pdev->dev);
> @@ -2053,6 +2106,9 @@ static int renesas_usb3_probe(struct platform_device *pdev)
>  
>  	return 0;
>  
> +err_dev_create:
> +	usb_del_gadget_udc(&usb3->gadget);
> +
>  err_add_udc:
>  	__renesas_usb3_ep_free_request(usb3->ep0_req);
>  
> -- 
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [PATCH v3 3/3] usb: gadget: udc: renesas_usb3: add support for usb role swap
  2017-03-30 10:36   ` Felipe Balbi
@ 2017-03-31  1:58     ` Yoshihiro Shimoda
  0 siblings, 0 replies; 6+ messages in thread
From: Yoshihiro Shimoda @ 2017-03-31  1:58 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: linux-usb, linux-renesas-soc, Greg KH

Hi,

> From: Felipe Balbi, Sent: Thursday, March 30, 2017 7:37 PM
> 
> Hi,
> 
> Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> writes:
> > 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        | 15 ++++++
> >  drivers/usb/gadget/udc/renesas_usb3.c              | 56 ++++++++++++++++++++++
> >  2 files changed, 71 insertions(+)
> >  create mode 100644 Documentation/ABI/testing/sysfs-platform-renesas_usb3
> >
> > diff --git a/Documentation/ABI/testing/sysfs-platform-renesas_usb3
> b/Documentation/ABI/testing/sysfs-platform-renesas_usb3
> > new file mode 100644
> > index 0000000..1f63190
> > --- /dev/null
> > +++ b/Documentation/ABI/testing/sysfs-platform-renesas_usb3
> > @@ -0,0 +1,15 @@
> > +What:		/sys/devices/platform/<udc-name>/role
> 
> I have one question here. This seems to imply that platform devices have
> a "role" file which is not true for all platforms devices. I really
> don't have a suggestion as to how this could/should be written out,
> though :-s

Thank you for the comment. I think that this "<udc-name>" is not good keyword.
Also actual name on a R-Car system (like /sys/device/platform/soc/ee020000.usb/role) is not good
because this name also seems to imply that platform devices have a "role".
So, I will change the "<udc-name>" to "<renesas_usb3's name>" as v4 patch.
Since patch 1/3 and 2/3 had merged into your testing/next branch (thanks!), I will do rebase.

Best regards,
Yoshihiro Shimoda

> Greg, any suggestions?
> 
> (keeping patch below for reference only)
> 
> > +Date:		March 2017
> > +KernelVersion:	4.13
> > +Contact:	Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> > +Description:
> > +		This file can be read and write.
> > +		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.
> > +
> > +		Read the file, then it shows the following strings:
> > +		 "host" - The mode is host now.
> > +		 "peripheral" - The mode is peripheral now.
> > diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c
> > index a1e79fc..5a2d845 100644
> > --- a/drivers/usb/gadget/udc/renesas_usb3.c
> > +++ b/drivers/usb/gadget/udc/renesas_usb3.c
> > @@ -372,6 +372,11 @@ static void usb3_disable_pipe_irq(struct renesas_usb3 *usb3, int num)
> >  	usb3_clear_bit(usb3, USB_INT_2_PIPE(num), USB3_USB_INT_ENA_2);
> >  }
> >
> > +static bool usb3_is_host(struct renesas_usb3 *usb3)
> > +{
> > +	return !(usb3_read(usb3, USB3_DRD_CON) & DRD_CON_PERI_CON);
> > +}
> > +
> >  static void usb3_init_axi_bridge(struct renesas_usb3 *usb3)
> >  {
> >  	/* Set AXI_INT */
> > @@ -576,8 +581,14 @@ static void usb3_vbus_out(struct renesas_usb3 *usb3, bool enable)
> >
> >  static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev)
> >  {
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&usb3->lock, flags);
> >  	usb3_set_mode(usb3, host);
> >  	usb3_vbus_out(usb3, a_dev);
> > +	if (!host && a_dev)		/* for A-Peripheral */
> > +		usb3_connect(usb3);
> > +	spin_unlock_irqrestore(&usb3->lock, flags);
> >  }
> >
> >  static bool usb3_is_a_device(struct renesas_usb3 *usb3)
> > @@ -1837,11 +1848,49 @@ static int renesas_usb3_set_selfpowered(struct usb_gadget *gadget, int is_self)
> >  	.set_selfpowered	= renesas_usb3_set_selfpowered,
> >  };
> >
> > +static ssize_t role_store(struct device *dev, struct device_attribute *attr,
> > +			  const char *buf, size_t count)
> > +{
> > +	struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
> > +	bool new_mode_is_host;
> > +
> > +	if (!usb3->driver)
> > +		return -ENODEV;
> > +
> > +	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;
> > +
> > +	usb3_mode_config(usb3, new_mode_is_host, usb3_is_a_device(usb3));
> > +
> > +	return count;
> > +}
> > +
> > +static ssize_t role_show(struct device *dev, struct device_attribute *attr,
> > +			 char *buf)
> > +{
> > +	struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
> > +
> > +	if (!usb3->driver)
> > +		return -ENODEV;
> > +
> > +	return sprintf(buf, "%s\n", usb3_is_host(usb3) ? "host" : "peripheral");
> > +}
> > +static DEVICE_ATTR_RW(role);
> > +
> >  /*------- platform_driver ------------------------------------------------*/
> >  static int renesas_usb3_remove(struct platform_device *pdev)
> >  {
> >  	struct renesas_usb3 *usb3 = platform_get_drvdata(pdev);
> >
> > +	device_remove_file(&pdev->dev, &dev_attr_role);
> > +
> >  	pm_runtime_put(&pdev->dev);
> >  	pm_runtime_disable(&pdev->dev);
> >
> > @@ -2044,6 +2093,10 @@ static int renesas_usb3_probe(struct platform_device *pdev)
> >  	if (ret < 0)
> >  		goto err_add_udc;
> >
> > +	ret = device_create_file(&pdev->dev, &dev_attr_role);
> > +	if (ret < 0)
> > +		goto err_dev_create;
> > +
> >  	usb3->workaround_for_vbus = priv->workaround_for_vbus;
> >
> >  	pm_runtime_enable(&pdev->dev);
> > @@ -2053,6 +2106,9 @@ static int renesas_usb3_probe(struct platform_device *pdev)
> >
> >  	return 0;
> >
> > +err_dev_create:
> > +	usb_del_gadget_udc(&usb3->gadget);
> > +
> >  err_add_udc:
> >  	__renesas_usb3_ep_free_request(usb3->ep0_req);
> >
> > --
> > 1.9.1
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> --
> balbi

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-03-31  1:59 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-30  2:16 [PATCH v3 0/3] usb: gadget: udc: renesas_usb3: add USB3.0 DRD support Yoshihiro Shimoda
2017-03-30  2:16 ` [PATCH v3 1/3] usb: gadget: udc: add USB ID signal monitoring Yoshihiro Shimoda
2017-03-30  2:16 ` [PATCH v3 2/3] usb: gadget: udc: renesas_usb3: add extcon support Yoshihiro Shimoda
2017-03-30  2:16 ` [PATCH v3 3/3] usb: gadget: udc: renesas_usb3: add support for usb role swap Yoshihiro Shimoda
2017-03-30 10:36   ` Felipe Balbi
2017-03-31  1:58     ` Yoshihiro Shimoda

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.