lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <Fz2Ehjftp2eVDCxfgd4j3TYcrmSf5ForizOdT7rngo@cp7-web-042.plabs.ch>
Date:   Tue, 27 Jul 2021 09:56:41 +0000
From:   Yassine Oudjana <y.oudjana@...tonmail.com>
To:     Michael Auchter <michael.auchter@...com>
Cc:     Yassine Oudjana <y.oudjana@...tonmail.com>,
        MyungJoo Ham <myungjoo.ham@...sung.com>,
        Chanwoo Choi <cw00.choi@...sung.com>,
        Rob Herring <robh+dt@...nel.org>, linux-kernel@...r.kernel.org,
        devicetree@...r.kernel.org
Subject: [PATCH v2 1/3] extcon: usbc-tusb320: Add support for mode setting and reset

Reset the chip and set its mode to default (maintain mode set by PORT pin)
during probe to make sure it comes up in the default state.

Signed-off-by: Yassine Oudjana <y.oudjana@...tonmail.com>
---
 drivers/extcon/extcon-usbc-tusb320.c | 111 +++++++++++++++++++++++----
 1 file changed, 97 insertions(+), 14 deletions(-)

diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c
index 805af73b4152..c8d931abbf9f 100644
--- a/drivers/extcon/extcon-usbc-tusb320.c
+++ b/drivers/extcon/extcon-usbc-tusb320.c
@@ -19,15 +19,32 @@
 #define TUSB320_REG9_ATTACHED_STATE_MASK	0x3
 #define TUSB320_REG9_CABLE_DIRECTION		BIT(5)
 #define TUSB320_REG9_INTERRUPT_STATUS		BIT(4)
-#define TUSB320_ATTACHED_STATE_NONE		0x0
-#define TUSB320_ATTACHED_STATE_DFP		0x1
-#define TUSB320_ATTACHED_STATE_UFP		0x2
-#define TUSB320_ATTACHED_STATE_ACC		0x3
+
+#define TUSB320_REGA				0xa
+#define TUSB320_REGA_I2C_SOFT_RESET		BIT(3)
+#define TUSB320_REGA_MODE_SELECT_SHIFT		4
+#define TUSB320_REGA_MODE_SELECT_MASK		0x3
+
+enum tusb320_attached_state {
+	TUSB320_ATTACHED_STATE_NONE,
+	TUSB320_ATTACHED_STATE_DFP,
+	TUSB320_ATTACHED_STATE_UFP,
+	TUSB320_ATTACHED_STATE_ACC,
+};
+
+enum tusb320_mode {
+	TUSB320_MODE_PORT,
+	TUSB320_MODE_UFP,
+	TUSB320_MODE_DFP,
+	TUSB320_MODE_DRP,
+};
 
 struct tusb320_priv {
 	struct device *dev;
 	struct regmap *regmap;
 	struct extcon_dev *edev;
+
+	enum tusb320_attached_state state;
 };
 
 static const char * const tusb_attached_states[] = {
@@ -37,6 +54,13 @@ static const char * const tusb_attached_states[] = {
 	[TUSB320_ATTACHED_STATE_ACC]  = "accessory",
 };
 
+static const char * const tusb_modes[] = {
+	[TUSB320_MODE_PORT] = "maintain mode set by PORT pin",
+	[TUSB320_MODE_UFP]  = "upstream facing port",
+	[TUSB320_MODE_DFP]  = "downstream facing port",
+	[TUSB320_MODE_DRP]  = "dual role port",
+};
+
 static const unsigned int tusb320_extcon_cable[] = {
 	EXTCON_USB,
 	EXTCON_USB_HOST,
@@ -62,26 +86,77 @@ static int tusb320_check_signature(struct tusb320_priv *priv)
 	return 0;
 }
 
+static int tusb320_set_mode(struct tusb320_priv *priv, enum tusb320_mode mode)
+{
+	int ret;
+
+	/* Mode cannot be changed while cable is attached */
+	if(priv->state != TUSB320_ATTACHED_STATE_NONE)
+		return -EBUSY;
+
+	/* Write mode */
+	ret = regmap_write_bits(priv->regmap, TUSB320_REGA,
+		TUSB320_REGA_MODE_SELECT_MASK << TUSB320_REGA_MODE_SELECT_SHIFT,
+		mode << TUSB320_REGA_MODE_SELECT_SHIFT);
+	if(ret) {
+		dev_err(priv->dev, "failed to write mode: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int tusb320_reset(struct tusb320_priv *priv)
+{
+	int ret;
+
+	/* Set mode to default (follow PORT pin) */
+	ret = tusb320_set_mode(priv, TUSB320_MODE_PORT);
+	if(ret && ret != -EBUSY) {
+		dev_err(priv->dev,
+			"failed to set mode to PORT: %d\n", ret);
+		return ret;
+	}
+
+	/* Perform soft reset */
+	ret = regmap_write_bits(priv->regmap, TUSB320_REGA,
+			TUSB320_REGA_I2C_SOFT_RESET, 1);
+	if(ret) {
+		dev_err(priv->dev,
+			"failed to write soft reset bit: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 static irqreturn_t tusb320_irq_handler(int irq, void *dev_id)
 {
 	struct tusb320_priv *priv = dev_id;
-	int state, polarity;
-	unsigned reg;
+	int state, polarity, mode;
+	unsigned reg9, rega;
+
+	if (regmap_read(priv->regmap, TUSB320_REG9, &reg9)) {
+		dev_err(priv->dev, "error during register 0x9 i2c read!\n");
+		return IRQ_NONE;
+	}
 
-	if (regmap_read(priv->regmap, TUSB320_REG9, &reg)) {
-		dev_err(priv->dev, "error during i2c read!\n");
+	if (regmap_read(priv->regmap, TUSB320_REGA, &rega)) {
+		dev_err(priv->dev, "error during register 0xa i2c read!\n");
 		return IRQ_NONE;
 	}
 
-	if (!(reg & TUSB320_REG9_INTERRUPT_STATUS))
+	if (!(reg9 & TUSB320_REG9_INTERRUPT_STATUS))
 		return IRQ_NONE;
 
-	state = (reg >> TUSB320_REG9_ATTACHED_STATE_SHIFT) &
+	state = (reg9 >> TUSB320_REG9_ATTACHED_STATE_SHIFT) &
 		TUSB320_REG9_ATTACHED_STATE_MASK;
-	polarity = !!(reg & TUSB320_REG9_CABLE_DIRECTION);
+	polarity = !!(reg9 & TUSB320_REG9_CABLE_DIRECTION);
+	mode = (rega >> TUSB320_REGA_MODE_SELECT_SHIFT) &
+		TUSB320_REGA_MODE_SELECT_MASK;
 
-	dev_dbg(priv->dev, "attached state: %s, polarity: %d\n",
-		tusb_attached_states[state], polarity);
+	dev_dbg(priv->dev, "mode: %s, attached state: %s, polarity: %d\n",
+		tusb_modes[mode], tusb_attached_states[state], polarity);
 
 	extcon_set_state(priv->edev, EXTCON_USB,
 			 state == TUSB320_ATTACHED_STATE_UFP);
@@ -96,7 +171,10 @@ static irqreturn_t tusb320_irq_handler(int irq, void *dev_id)
 	extcon_sync(priv->edev, EXTCON_USB);
 	extcon_sync(priv->edev, EXTCON_USB_HOST);
 
-	regmap_write(priv->regmap, TUSB320_REG9, reg);
+	priv->state = state;
+
+	regmap_write(priv->regmap, TUSB320_REG9, reg9);
+	regmap_write(priv->regmap, TUSB320_REGA, rega);
 
 	return IRQ_HANDLED;
 }
@@ -137,6 +215,11 @@ static int tusb320_extcon_probe(struct i2c_client *client,
 		return ret;
 	}
 
+	/* Reset chip to its default state */
+	ret = tusb320_reset(priv);
+	if(ret)
+		dev_warn(priv->dev, "failed to reset chip: %d\n", ret);
+
 	extcon_set_property_capability(priv->edev, EXTCON_USB,
 				       EXTCON_PROP_USB_TYPEC_POLARITY);
 	extcon_set_property_capability(priv->edev, EXTCON_USB_HOST,
-- 
2.32.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ