All of lore.kernel.org
 help / color / mirror / Atom feed
From: Li Jun <jun.li@nxp.com>
To: myungjoo.ham@samsung.com, cw00.choi@samsung.com, krzk@kernel.org
Cc: linux-kernel@vger.kernel.org, frank.li@nxp.com, xu.yang_2@nxp.com
Subject: [PATCH v3 2/2] extcon: ptn5150: Add usb role class support
Date: Tue, 19 Apr 2022 20:44:09 +0800	[thread overview]
Message-ID: <1650372249-10787-2-git-send-email-jun.li@nxp.com> (raw)
In-Reply-To: <1650372249-10787-1-git-send-email-jun.li@nxp.com>

Some usb controller drivers may not support extcon but use
usb role class as it's the preferred approach, so to support
usb dual role switch with usb role class, add usb role class
consumer support.

Signed-off-by: Li Jun <jun.li@nxp.com>
---
Change for v3:
- Use 'depends on' intead of select USB_ROLE_SWITCH in Kconfig.

change for v2:
- Add one patch to sync queue work before driver remove.
- improve git commit log
- use a variable of usb_role to set target role in
  ptn5150_check_state() to simplify code.
- use dev_err_probe for usb_role_switch_get() return value.

 drivers/extcon/Kconfig          |  1 +
 drivers/extcon/extcon-ptn5150.c | 25 +++++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
index 88a8b3d7d78a..dca7cecb37e3 100644
--- a/drivers/extcon/Kconfig
+++ b/drivers/extcon/Kconfig
@@ -131,6 +131,7 @@ config EXTCON_PALMAS
 config EXTCON_PTN5150
 	tristate "NXP PTN5150 CC LOGIC USB EXTCON support"
 	depends on I2C && (GPIOLIB || COMPILE_TEST)
+	depends on USB_ROLE_SWITCH || !USB_ROLE_SWITCH
 	select REGMAP_I2C
 	help
 	  Say Y here to enable support for USB peripheral and USB host
diff --git a/drivers/extcon/extcon-ptn5150.c b/drivers/extcon/extcon-ptn5150.c
index 2a7874108df8..017a07197f38 100644
--- a/drivers/extcon/extcon-ptn5150.c
+++ b/drivers/extcon/extcon-ptn5150.c
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/extcon-provider.h>
 #include <linux/gpio/consumer.h>
+#include <linux/usb/role.h>
 
 /* PTN5150 registers */
 #define PTN5150_REG_DEVICE_ID			0x01
@@ -52,6 +53,7 @@ struct ptn5150_info {
 	int irq;
 	struct work_struct irq_work;
 	struct mutex mutex;
+	struct usb_role_switch *role_sw;
 };
 
 /* List of detectable cables */
@@ -70,6 +72,7 @@ static const struct regmap_config ptn5150_regmap_config = {
 static void ptn5150_check_state(struct ptn5150_info *info)
 {
 	unsigned int port_status, reg_data, vbus;
+	enum usb_role usb_role = USB_ROLE_NONE;
 	int ret;
 
 	ret = regmap_read(info->regmap, PTN5150_REG_CC_STATUS, &reg_data);
@@ -85,6 +88,7 @@ static void ptn5150_check_state(struct ptn5150_info *info)
 		extcon_set_state_sync(info->edev, EXTCON_USB_HOST, false);
 		gpiod_set_value_cansleep(info->vbus_gpiod, 0);
 		extcon_set_state_sync(info->edev, EXTCON_USB, true);
+		usb_role = USB_ROLE_DEVICE;
 		break;
 	case PTN5150_UFP_ATTACHED:
 		extcon_set_state_sync(info->edev, EXTCON_USB, false);
@@ -95,10 +99,18 @@ static void ptn5150_check_state(struct ptn5150_info *info)
 			gpiod_set_value_cansleep(info->vbus_gpiod, 1);
 
 		extcon_set_state_sync(info->edev, EXTCON_USB_HOST, true);
+		usb_role = USB_ROLE_HOST;
 		break;
 	default:
 		break;
 	}
+
+	if (usb_role) {
+		ret = usb_role_switch_set_role(info->role_sw, usb_role);
+		if (ret)
+			dev_err(info->dev, "failed to set %s role: %d\n",
+				usb_role_string(usb_role), ret);
+	}
 }
 
 static void ptn5150_irq_work(struct work_struct *work)
@@ -133,6 +145,13 @@ static void ptn5150_irq_work(struct work_struct *work)
 			extcon_set_state_sync(info->edev,
 					EXTCON_USB, false);
 			gpiod_set_value_cansleep(info->vbus_gpiod, 0);
+
+			ret = usb_role_switch_set_role(info->role_sw,
+						       USB_ROLE_NONE);
+			if (ret)
+				dev_err(info->dev,
+					"failed to set none role: %d\n",
+					ret);
 		}
 	}
 
@@ -199,6 +218,7 @@ static void ptn5150_work_sync_and_put(void *data)
 	struct ptn5150_info *info = data;
 
 	cancel_work_sync(&info->irq_work);
+	usb_role_switch_put(info->role_sw);
 }
 
 static int ptn5150_i2c_probe(struct i2c_client *i2c)
@@ -291,6 +311,11 @@ static int ptn5150_i2c_probe(struct i2c_client *i2c)
 	if (ret)
 		return -EINVAL;
 
+	info->role_sw = usb_role_switch_get(info->dev);
+	if (IS_ERR(info->role_sw))
+		return dev_err_probe(info->dev, PTR_ERR(info->role_sw),
+				     "failed to get role switch\n");
+
 	ret = devm_add_action_or_reset(dev, ptn5150_work_sync_and_put, info);
 	if (ret)
 		return ret;
-- 
2.25.1


  reply	other threads:[~2022-04-19 12:55 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-19 12:44 [PATCH v3 1/2] extcon: ptn5150: add queue work sync before driver release Li Jun
2022-04-19 12:44 ` Li Jun [this message]
2022-04-19 13:08   ` [PATCH v3 2/2] extcon: ptn5150: Add usb role class support Krzysztof Kozlowski
2022-04-26  0:04 ` [PATCH v3 1/2] extcon: ptn5150: add queue work sync before driver release Chanwoo Choi

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=1650372249-10787-2-git-send-email-jun.li@nxp.com \
    --to=jun.li@nxp.com \
    --cc=cw00.choi@samsung.com \
    --cc=frank.li@nxp.com \
    --cc=krzk@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=myungjoo.ham@samsung.com \
    --cc=xu.yang_2@nxp.com \
    /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 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.