cip-dev.lists.cip-project.org archive mirror
 help / color / mirror / Atom feed
From: marian-cristian.rotariu.rb@bp.renesas.com (Marian-Cristian Rotariu)
To: cip-dev@lists.cip-project.org
Subject: [cip-dev] [PATCH 4.19.y-cip 20/23] usb: gadget: udc: renesas_usb3: Enhance role switch support
Date: Tue, 18 Feb 2020 14:05:17 +0000	[thread overview]
Message-ID: <1582034720-5249-21-git-send-email-marian-cristian.rotariu.rb@bp.renesas.com> (raw)
In-Reply-To: <1582034720-5249-1-git-send-email-marian-cristian.rotariu.rb@bp.renesas.com>

From: Biju Das <biju.das@bp.renesas.com>

commit 0604160d8c0b6082727182398d432a68bdd58872 upstream.

The RZ/G2E cat874 board has a type-c connector connected to hd3ss3220 usb
type-c drp port controller. Enhance role switch support to assign the role
requested by connector device using the usb role switch class framework.

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Biju Das <biju.das@bp.renesas.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
(fixed checkpatch alignment warnings)
Signed-off-by: Marian-Cristian Rotariu <marian-cristian.rotariu.rb@bp.renesas.com>
---
 drivers/usb/gadget/udc/renesas_usb3.c | 91 ++++++++++++++++++++++++++++++++---
 1 file changed, 84 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c
index b6eec81..d9668f8 100644
--- a/drivers/usb/gadget/udc/renesas_usb3.c
+++ b/drivers/usb/gadget/udc/renesas_usb3.c
@@ -352,6 +352,8 @@ struct renesas_usb3 {
 	int disabled_count;
 
 	struct usb_request *ep0_req;
+
+	enum usb_role connection_state;
 	u16 test_mode;
 	u8 ep0_buf[USB3_EP0_BUF_SIZE];
 	bool softconnect;
@@ -360,6 +362,7 @@ struct renesas_usb3 {
 	bool extcon_usb;		/* check vbus and set EXTCON_USB */
 	bool forced_b_device;
 	bool start_to_connect;
+	bool role_sw_by_connector;
 };
 
 #define gadget_to_renesas_usb3(_gadget)	\
@@ -700,8 +703,11 @@ 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_by_role_sw(usb3, host);
-	usb3_vbus_out(usb3, a_dev);
+	if (!usb3->role_sw_by_connector ||
+	    usb3->connection_state != USB_ROLE_NONE) {
+		usb3_set_mode_by_role_sw(usb3, host);
+		usb3_vbus_out(usb3, a_dev);
+	}
 	/* for A-Peripheral or forced B-device mode */
 	if ((!host && a_dev) || usb3->start_to_connect)
 		usb3_connect(usb3);
@@ -717,7 +723,8 @@ static void usb3_check_id(struct renesas_usb3 *usb3)
 {
 	usb3->extcon_host = usb3_is_a_device(usb3);
 
-	if (usb3->extcon_host && !usb3->forced_b_device)
+	if ((!usb3->role_sw_by_connector && usb3->extcon_host &&
+	     !usb3->forced_b_device) || usb3->connection_state == USB_ROLE_HOST)
 		usb3_mode_config(usb3, true, true);
 	else
 		usb3_mode_config(usb3, false, false);
@@ -2344,14 +2351,65 @@ static enum usb_role renesas_usb3_role_switch_get(struct device *dev)
 	return cur_role;
 }
 
-static int renesas_usb3_role_switch_set(struct device *dev,
-					enum usb_role role)
+static void handle_ext_role_switch_states(struct device *dev,
+					  enum usb_role role)
+{
+	struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
+	struct device *host = usb3->host_dev;
+	enum usb_role cur_role = renesas_usb3_role_switch_get(dev);
+
+	switch (role) {
+	case USB_ROLE_NONE:
+		usb3->connection_state = USB_ROLE_NONE;
+		if (usb3->driver)
+			usb3_disconnect(usb3);
+		usb3_vbus_out(usb3, false);
+		break;
+	case USB_ROLE_DEVICE:
+		if (usb3->connection_state == USB_ROLE_NONE) {
+			usb3->connection_state = USB_ROLE_DEVICE;
+			usb3_set_mode(usb3, false);
+			if (usb3->driver)
+				usb3_connect(usb3);
+		} else if (cur_role == USB_ROLE_HOST)  {
+			device_release_driver(host);
+			usb3_set_mode(usb3, false);
+			if (usb3->driver)
+				usb3_connect(usb3);
+		}
+		usb3_vbus_out(usb3, false);
+		break;
+	case USB_ROLE_HOST:
+		if (usb3->connection_state == USB_ROLE_NONE) {
+			if (usb3->driver)
+				usb3_disconnect(usb3);
+
+			usb3->connection_state = USB_ROLE_HOST;
+			usb3_set_mode(usb3, true);
+			usb3_vbus_out(usb3, true);
+			if (device_attach(host) < 0)
+				dev_err(dev, "device_attach(host) failed\n");
+		} else if (cur_role == USB_ROLE_DEVICE) {
+			usb3_disconnect(usb3);
+			/* Must set the mode before device_attach of the host */
+			usb3_set_mode(usb3, true);
+			/* This device_attach() might sleep */
+			if (device_attach(host) < 0)
+				dev_err(dev, "device_attach(host) failed\n");
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+static void handle_role_switch_states(struct device *dev,
+				      enum usb_role role)
 {
 	struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
 	struct device *host = usb3->host_dev;
 	enum usb_role cur_role = renesas_usb3_role_switch_get(dev);
 
-	pm_runtime_get_sync(dev);
 	if (cur_role == USB_ROLE_HOST && role == USB_ROLE_DEVICE) {
 		device_release_driver(host);
 		usb3_set_mode(usb3, false);
@@ -2362,6 +2420,20 @@ static int renesas_usb3_role_switch_set(struct device *dev,
 		if (device_attach(host) < 0)
 			dev_err(dev, "device_attach(host) failed\n");
 	}
+}
+
+static int renesas_usb3_role_switch_set(struct device *dev,
+					enum usb_role role)
+{
+	struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
+
+	pm_runtime_get_sync(dev);
+
+	if (usb3->role_sw_by_connector)
+		handle_ext_role_switch_states(dev, role);
+	else
+		handle_role_switch_states(dev, role);
+
 	pm_runtime_put(dev);
 
 	return 0;
@@ -2651,7 +2723,7 @@ static const unsigned int renesas_usb3_cable[] = {
 	EXTCON_NONE,
 };
 
-static const struct usb_role_switch_desc renesas_usb3_role_switch_desc = {
+static struct usb_role_switch_desc renesas_usb3_role_switch_desc = {
 	.set = renesas_usb3_role_switch_set,
 	.get = renesas_usb3_role_switch_get,
 	.allow_userspace_control = true,
@@ -2742,6 +2814,11 @@ static int renesas_usb3_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto err_dev_create;
 
+	if (device_property_read_bool(&pdev->dev, "usb-role-switch")) {
+		usb3->role_sw_by_connector = true;
+		renesas_usb3_role_switch_desc.fwnode = dev_fwnode(&pdev->dev);
+	}
+
 	INIT_WORK(&usb3->role_work, renesas_usb3_role_work);
 	usb3->role_sw = usb_role_switch_register(&pdev->dev,
 					&renesas_usb3_role_switch_desc);
-- 
2.7.4

  parent reply	other threads:[~2020-02-18 14:05 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-18 14:04 [cip-dev] [PATCH 4.19.y-cip 00/23] Renesas RZ/G2E USB Type-C Backport Marian-Cristian Rotariu
2020-02-18 14:04 ` [cip-dev] [PATCH 4.19.y-cip 01/23] device connection: Add fwnode member to struct device_connection Marian-Cristian Rotariu
2020-02-19  7:42   ` Pavel Machek
2020-02-19 19:11     ` Marian-Cristian Rotariu
2020-02-18 14:04 ` [cip-dev] [PATCH 4.19.y-cip 02/23] usb: typec: mux: Find the muxes by also matching against the device node Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 03/23] usb: typec: mux: Fix unsigned comparison with less than zero Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 04/23] usb: roles: Find the muxes by also matching against the device node Marian-Cristian Rotariu
2020-02-19  7:51   ` Pavel Machek
2020-02-19 19:04     ` Marian-Cristian Rotariu
2020-02-19 21:38       ` Pavel Machek
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 05/23] usb: typec: Find the ports " Marian-Cristian Rotariu
2020-02-19  7:56   ` Pavel Machek
2020-02-20 10:44     ` [cip-dev] " Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 06/23] device connection: Prepare support for firmware described connections Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 07/23] device connection: Find device connections also from device graphs Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 08/23] device property: Introduce fwnode_find_reference() Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 09/23] device connection: Find connections also by checking the references Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 10/23] usb: roles: Introduce stubs for the exiting functions in role.h Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 11/23] device connection: Add fwnode_connection_find_match() Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 12/23] usb: roles: Add fwnode_usb_role_switch_get() function Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 13/23] dt-bindings: usb: hd3ss3220 device tree binding document Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 14/23] dt-bindings: usb: renesas_usb3: Document usb role switch support Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 15/23] usb: typec: driver for TI HD3SS3220 USB Type-C DRP port controller Marian-Cristian Rotariu
2020-02-19  8:12   ` Pavel Machek
2020-02-20 11:20     ` [cip-dev] " Marian-Cristian Rotariu
2020-02-20 15:46       ` Pavel Machek
2020-02-20 16:28         ` Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 16/23] usb: typec: hd3ss3220_irq() can be static Marian-Cristian Rotariu
2020-02-19  8:20   ` Pavel Machek
2020-02-19 19:15     ` Marian-Cristian Rotariu
2020-02-19 21:40       ` Pavel Machek
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 17/23] usb: typec: add dependency for TYPEC_HD3SS3220 Marian-Cristian Rotariu
2020-02-19  8:16   ` Pavel Machek
2020-02-20 11:40     ` [cip-dev] " Marian-Cristian Rotariu
2020-02-20 15:50       ` Pavel Machek
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 18/23] usb: typec: hd3ss3220: hd3ss3220_probe() warn: passing zero to 'PTR_ERR' Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 19/23] usb: typec: fix an IS_ERR() vs NULL bug in hd3ss3220_probe() Marian-Cristian Rotariu
2020-02-18 14:05 ` Marian-Cristian Rotariu [this message]
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 21/23] arm64: defconfig: enable TYPEC_HD3SS3220 config option Marian-Cristian Rotariu
2020-02-19  8:19   ` Pavel Machek
2020-02-19 19:18     ` Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 22/23] arm64: dts: renesas: cat874: Enable USB3.0 host/peripheral device node Marian-Cristian Rotariu
2020-02-18 14:05 ` [cip-dev] [PATCH 4.19.y-cip 23/23] arm64: dts: renesas: cat874: Enable usb role switch support Marian-Cristian Rotariu
2020-02-19  7:41 ` [PATCH 4.19.y-cip 00/23] Renesas RZ/G2E USB Type-C Backport Pavel Machek
2020-02-19 18:43   ` Marian-Cristian Rotariu
2020-02-19 21:35     ` Pavel Machek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1582034720-5249-21-git-send-email-marian-cristian.rotariu.rb@bp.renesas.com \
    --to=marian-cristian.rotariu.rb@bp.renesas.com \
    --cc=cip-dev@lists.cip-project.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).