linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect
@ 2020-08-25  4:21 Badhri Jagan Sridharan
  2020-08-25  4:21 ` [PATCH 01/14 v1] usb: typec: tcpci: Add register definitions to tcpci Badhri Jagan Sridharan
                   ` (13 more replies)
  0 siblings, 14 replies; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:21 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

Hi all,

With this patchset, I am hoping to add Sink Fast Role swap support to TCPM.
Sink Fast Role swap is described by the USB Power Delivery Specification
Revision 3.0. The patchset also adds support to Auto Discharge Disconnect
described in the USB Type-C Port Controller Interface Specification.
I am also sending the chip level driver for the TCPCI based type-c controller
that supports Fast role swap.

I tested the fast role swap implementation with the following
accessories:
1. https://ezq.com/usb-c-multimedia-hub-adapter-8-ports.html
2. https://www.iogear.com/product/GUH3C22P/

Note: I will rebase the patchset on top of https://lkml.org/lkml/2020/8/19/52
once it's picked up in usb-next.

Badhri Jagan Sridharan (14):
  usb: typec: tcpci: Add register definitions to tcpci
  usb: typec: tcpci: Add support when hidden tx registers are
    inaccessible
  usb: typec: tcpci: update ROLE_CONTROL for DRP
  usb: typec: tcpci: Add a getter method to retrieve tcpm_port reference
  usb: typec: tcpci: Add set_vbus tcpci callback
  dt-bindings: usb: Maxim type-c controller device tree binding document
  usb: typec: tcpci_maxim: Chip level TCPC driver
  dt-bindings: connector: Add property to set initial current cap for
    FRS
  usb: typec: tcpm: Add support for Sink Fast Role SWAP(FRS)
  usb: typec: tcpci: Implement callbacks for FRS
  usb: typec: tcpci_maxim: Add support for Sink FRS
  usb: typec: tcpm: Implement enabling Auto Discharge disconnect support
  usb: typec: tcpci: Implement Auto discharge disconnect callbacks
  usb: typec: tcpci_maxim: Implemnent set_auto_vbus_discharge_threshold

 .../bindings/connector/usb-connector.txt      | 128 ++++
 .../devicetree/bindings/usb/maxim,tcpci.txt   |  44 ++
 drivers/usb/typec/tcpm/Kconfig                |   6 +
 drivers/usb/typec/tcpm/Makefile               |  13 +-
 drivers/usb/typec/tcpm/tcpci.c                | 149 ++++-
 drivers/usb/typec/tcpm/tcpci.h                |  43 ++
 drivers/usb/typec/tcpm/tcpci_maxim.c          | 564 ++++++++++++++++++
 drivers/usb/typec/tcpm/tcpm.c                 | 271 ++++++++-
 include/dt-bindings/usb/pd.h                  |  10 +
 include/linux/usb/pd.h                        |  20 +-
 include/linux/usb/tcpm.h                      |  24 +-
 include/linux/usb/typec.h                     |  13 +
 12 files changed, 1249 insertions(+), 36 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/connector/usb-connector.txt
 create mode 100644 Documentation/devicetree/bindings/usb/maxim,tcpci.txt
 create mode 100644 drivers/usb/typec/tcpm/tcpci_maxim.c

-- 
2.28.0.297.g1956fa8f8d-goog


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

* [PATCH 01/14 v1] usb: typec: tcpci: Add register definitions to tcpci
  2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
@ 2020-08-25  4:21 ` Badhri Jagan Sridharan
  2020-08-25  4:21 ` [PATCH 02/14 v2] usb: typec: tcpci: Add support when hidden tx registers are inaccessible Badhri Jagan Sridharan
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:21 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

Add register definitions to trap extended alerts.

Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
---
 drivers/usb/typec/tcpm/tcpci.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h
index 11c36d086c86..fd26ca35814c 100644
--- a/drivers/usb/typec/tcpm/tcpci.h
+++ b/drivers/usb/typec/tcpm/tcpci.h
@@ -16,6 +16,7 @@
 #define TCPC_PD_INT_REV			0xa
 
 #define TCPC_ALERT			0x10
+#define TCPC_ALERT_EXTENDED_STATUS	BIT(13)
 #define TCPC_ALERT_VBUS_DISCNCT		BIT(11)
 #define TCPC_ALERT_RX_BUF_OVF		BIT(10)
 #define TCPC_ALERT_FAULT		BIT(9)
@@ -32,6 +33,10 @@
 #define TCPC_ALERT_MASK			0x12
 #define TCPC_POWER_STATUS_MASK		0x14
 #define TCPC_FAULT_STATUS_MASK		0x15
+
+#define TCPC_EXTENDED_STATUS_MASK		0x16
+#define TCPC_EXTENDED_STATUS_MASK_VSAFE0V	BIT(0)
+
 #define TCPC_CONFIG_STD_OUTPUT		0x18
 
 #define TCPC_TCPC_CTRL			0x19
-- 
2.28.0.297.g1956fa8f8d-goog


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

* [PATCH 02/14 v2] usb: typec: tcpci: Add support when hidden tx registers are inaccessible
  2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
  2020-08-25  4:21 ` [PATCH 01/14 v1] usb: typec: tcpci: Add register definitions to tcpci Badhri Jagan Sridharan
@ 2020-08-25  4:21 ` Badhri Jagan Sridharan
  2020-08-28 13:12   ` Heikki Krogerus
  2020-08-25  4:21 ` [PATCH 03/14 v1] usb: typec: tcpci: update ROLE_CONTROL for DRP Badhri Jagan Sridharan
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:21 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

TCPCI spec forbids direct access of TX_BUF_BYTE_x register.
The existing version of tcpci driver assumes that those registers
are directly addressible. Add support for tcpci chips which do
not support direct access to TX_BUF_BYTE_x registers. TX_BUF_BYTE_x
can only be accessed by I2C_WRITE_BYTE_COUNT.

Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
---
 drivers/usb/typec/tcpm/tcpci.c | 49 +++++++++++++++++++++++++---------
 drivers/usb/typec/tcpm/tcpci.h |  8 ++++++
 2 files changed, 44 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
index f57d91fd0e09..90d348caa6a8 100644
--- a/drivers/usb/typec/tcpm/tcpci.c
+++ b/drivers/usb/typec/tcpm/tcpci.c
@@ -320,8 +320,7 @@ static int tcpci_set_vbus(struct tcpc_dev *tcpc, bool source, bool sink)
 	return 0;
 }
 
-static int tcpci_pd_transmit(struct tcpc_dev *tcpc,
-			     enum tcpm_transmit_type type,
+static int tcpci_pd_transmit(struct tcpc_dev *tcpc, enum tcpm_transmit_type type,
 			     const struct pd_message *msg)
 {
 	struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
@@ -330,23 +329,47 @@ static int tcpci_pd_transmit(struct tcpc_dev *tcpc,
 	int ret;
 
 	cnt = msg ? pd_header_cnt(header) * 4 : 0;
-	ret = regmap_write(tcpci->regmap, TCPC_TX_BYTE_CNT, cnt + 2);
-	if (ret < 0)
-		return ret;
+	/**
+	 * TCPCI spec forbids direct access of TCPC_TX_DATA.
+	 * But, since some of the chipsets offer this capability,
+	 * it's fair to support both.
+	 */
+	if (!tcpci->data->TX_BUF_BYTE_x_hidden) {
+		ret = regmap_write(tcpci->regmap, TCPC_TX_BYTE_CNT, cnt + 2);
+		if (ret < 0)
+			return ret;
 
-	ret = tcpci_write16(tcpci, TCPC_TX_HDR, header);
-	if (ret < 0)
-		return ret;
+		ret = tcpci_write16(tcpci, TCPC_TX_HDR, header);
+		if (ret < 0)
+			return ret;
+
+		if (cnt > 0) {
+			ret = regmap_raw_write(tcpci->regmap, TCPC_TX_DATA, &msg->payload, cnt);
+			if (ret < 0)
+				return ret;
+		}
+	} else {
+		u8 buf[TCPC_TRANSMIT_BUFFER_MAX_LEN] = {0,};
+		u8 pos = 0;
+
+		/* Payload + header + TCPC_TX_BYTE_CNT */
+		buf[pos++] = cnt + 2;
+
+		if (msg)
+			memcpy(&buf[pos], &msg->header, sizeof(msg->header));
+
+		pos += sizeof(header);
+
+		if (cnt > 0)
+			memcpy(&buf[pos], msg->payload, cnt);
 
-	if (cnt > 0) {
-		ret = regmap_raw_write(tcpci->regmap, TCPC_TX_DATA,
-				       &msg->payload, cnt);
+		pos += cnt;
+		ret = regmap_raw_write(tcpci->regmap, TCPC_TX_BYTE_CNT, buf, pos);
 		if (ret < 0)
 			return ret;
 	}
 
-	reg = (PD_RETRY_COUNT << TCPC_TRANSMIT_RETRY_SHIFT) |
-		(type << TCPC_TRANSMIT_TYPE_SHIFT);
+	reg = (PD_RETRY_COUNT << TCPC_TRANSMIT_RETRY_SHIFT) | (type << TCPC_TRANSMIT_TYPE_SHIFT);
 	ret = regmap_write(tcpci->regmap, TCPC_TRANSMIT, reg);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h
index fd26ca35814c..cf9d8b63adcb 100644
--- a/drivers/usb/typec/tcpm/tcpci.h
+++ b/drivers/usb/typec/tcpm/tcpci.h
@@ -128,9 +128,17 @@
 #define TCPC_VBUS_VOLTAGE_ALARM_HI_CFG		0x76
 #define TCPC_VBUS_VOLTAGE_ALARM_LO_CFG		0x78
 
+/* I2C_WRITE_BYTE_COUNT + 1 when TX_BUF_BYTE_x is only accessible I2C_WRITE_BYTE_COUNT */
+#define TCPC_TRANSMIT_BUFFER_MAX_LEN		31
+
+/*
+ * @TX_BUF_BYTE_x_hidden
+ *		optional; Set when TX_BUF_BYTE_x can only be accessed through I2C_WRITE_BYTE_COUNT.
+ */
 struct tcpci;
 struct tcpci_data {
 	struct regmap *regmap;
+	unsigned char TX_BUF_BYTE_x_hidden:1;
 	int (*init)(struct tcpci *tcpci, struct tcpci_data *data);
 	int (*set_vconn)(struct tcpci *tcpci, struct tcpci_data *data,
 			 bool enable);
-- 
2.28.0.297.g1956fa8f8d-goog


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

* [PATCH 03/14 v1] usb: typec: tcpci: update ROLE_CONTROL for DRP
  2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
  2020-08-25  4:21 ` [PATCH 01/14 v1] usb: typec: tcpci: Add register definitions to tcpci Badhri Jagan Sridharan
  2020-08-25  4:21 ` [PATCH 02/14 v2] usb: typec: tcpci: Add support when hidden tx registers are inaccessible Badhri Jagan Sridharan
@ 2020-08-25  4:21 ` Badhri Jagan Sridharan
  2020-08-25  4:22 ` [PATCH 04/14 v1] usb: typec: tcpci: Add a getter method to retrieve tcpm_port reference Badhri Jagan Sridharan
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:21 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

ROLE_CONTROL register would not have the actual CC terminations
unless the port does not set ROLE_CONTROL.DRP. For DRP ports,
CC_STATUS.cc1/cc2 indicates the final terminations applied
when TCPC enters potential_connect_as_source/_sink.
For DRP ports, infer port role from CC_STATUS and set corresponding
CC terminations before setting the orientation.

Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
---
 drivers/usb/typec/tcpm/tcpci.c | 37 +++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
index 90d348caa6a8..9e814d454d14 100644
--- a/drivers/usb/typec/tcpm/tcpci.c
+++ b/drivers/usb/typec/tcpm/tcpci.c
@@ -191,12 +191,47 @@ static int tcpci_set_polarity(struct tcpc_dev *tcpc,
 	struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
 	unsigned int reg;
 	int ret;
+	enum typec_cc_status cc1, cc2;
 
-	/* Keep the disconnect cc line open */
+	/* Obtain Rp setting from role control */
 	ret = regmap_read(tcpci->regmap, TCPC_ROLE_CTRL, &reg);
 	if (ret < 0)
 		return ret;
 
+	ret = tcpci_get_cc(tcpc, &cc1, &cc2);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * When port has drp toggling enabled, ROLE_CONTROL would only have the initial
+	 * terminations for the toggling and does not indicate the final cc
+	 * terminations when ConnectionResult is 0 i.e. drp toggling stops and
+	 * the connection is resolbed. Infer port role from TCPC_CC_STATUS based on the
+	 * terminations seen. The port role is then used to set the cc terminations.
+	 */
+	if (reg & TCPC_ROLE_CTRL_DRP) {
+		/* Disable DRP for the OPEN setting to take effect */
+		reg = reg & ~TCPC_ROLE_CTRL_DRP;
+
+		if (polarity == TYPEC_POLARITY_CC2) {
+			reg &= ~(TCPC_ROLE_CTRL_CC2_MASK << TCPC_ROLE_CTRL_CC2_SHIFT);
+			/* Local port is source */
+			if (cc2 == TYPEC_CC_RD)
+				/* Role control would have the Rp setting when DRP was enabled */
+				reg |= TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC2_SHIFT;
+			else
+				reg |= TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC2_SHIFT;
+		} else {
+			reg &= ~(TCPC_ROLE_CTRL_CC1_MASK << TCPC_ROLE_CTRL_CC1_SHIFT);
+			/* Local port is source */
+			if (cc1 == TYPEC_CC_RD)
+				/* Role control would have the Rp setting when DRP was enabled */
+				reg |= TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC1_SHIFT;
+			else
+				reg |= TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC1_SHIFT;
+		}
+	}
+
 	if (polarity == TYPEC_POLARITY_CC2)
 		reg |= TCPC_ROLE_CTRL_CC_OPEN << TCPC_ROLE_CTRL_CC1_SHIFT;
 	else
-- 
2.28.0.297.g1956fa8f8d-goog


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

* [PATCH 04/14 v1] usb: typec: tcpci: Add a getter method to retrieve tcpm_port reference
  2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
                   ` (2 preceding siblings ...)
  2020-08-25  4:21 ` [PATCH 03/14 v1] usb: typec: tcpci: update ROLE_CONTROL for DRP Badhri Jagan Sridharan
@ 2020-08-25  4:22 ` Badhri Jagan Sridharan
  2020-08-28 14:11   ` Heikki Krogerus
  2020-08-25  4:22 ` [PATCH 05/14 v5] usb: typec: tcpci: Add set_vbus tcpci callback Badhri Jagan Sridharan
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:22 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

Allow chip level drivers to retrieve reference to tcpm_port.

Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
---
 drivers/usb/typec/tcpm/tcpci.c | 6 ++++++
 drivers/usb/typec/tcpm/tcpci.h | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
index 9e814d454d14..7b7991c8ac87 100644
--- a/drivers/usb/typec/tcpm/tcpci.c
+++ b/drivers/usb/typec/tcpm/tcpci.c
@@ -38,6 +38,12 @@ struct tcpci_chip {
 	struct tcpci_data data;
 };
 
+struct tcpm_port *tcpci_get_tcpm_port(struct tcpci *tcpci)
+{
+	return tcpci->port;
+}
+EXPORT_SYMBOL_GPL(tcpci_get_tcpm_port);
+
 static inline struct tcpci *tcpc_to_tcpci(struct tcpc_dev *tcpc)
 {
 	return container_of(tcpc, struct tcpci, tcpc);
diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h
index cf9d8b63adcb..04c49a0b0368 100644
--- a/drivers/usb/typec/tcpm/tcpci.h
+++ b/drivers/usb/typec/tcpm/tcpci.h
@@ -150,4 +150,6 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data);
 void tcpci_unregister_port(struct tcpci *tcpci);
 irqreturn_t tcpci_irq(struct tcpci *tcpci);
 
+struct tcpm_port;
+struct tcpm_port *tcpci_get_tcpm_port(struct tcpci *tcpci);
 #endif /* __LINUX_USB_TCPCI_H */
-- 
2.28.0.297.g1956fa8f8d-goog


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

* [PATCH 05/14 v5] usb: typec: tcpci: Add set_vbus tcpci callback
  2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
                   ` (3 preceding siblings ...)
  2020-08-25  4:22 ` [PATCH 04/14 v1] usb: typec: tcpci: Add a getter method to retrieve tcpm_port reference Badhri Jagan Sridharan
@ 2020-08-25  4:22 ` Badhri Jagan Sridharan
  2020-08-28  7:37   ` Greg Kroah-Hartman
  2020-08-25  4:22 ` [PATCH 06/14 v1] dt-bindings: usb: Maxim type-c controller device tree binding document Badhri Jagan Sridharan
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:22 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

set_vbus callback allows TCPC which are TCPCI based, however,
does not support turning on sink and source mode through
Command.SinkVbus and Command.SourceVbusDefaultVoltage.

Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
---
 drivers/usb/typec/tcpm/tcpci.c | 7 +++++++
 drivers/usb/typec/tcpm/tcpci.h | 1 +
 2 files changed, 8 insertions(+)

diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
index 7b7991c8ac87..89d28e3fbee8 100644
--- a/drivers/usb/typec/tcpm/tcpci.c
+++ b/drivers/usb/typec/tcpm/tcpci.c
@@ -328,6 +328,13 @@ static int tcpci_set_vbus(struct tcpc_dev *tcpc, bool source, bool sink)
 	struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
 	int ret;
 
+	if (tcpci->data->set_vbus) {
+		ret = tcpci->data->set_vbus(tcpci, tcpci->data, source, sink);
+		/* Bypass when ret > 0 */
+		if (ret != 0)
+			return ret < 0 ? ret : 0;
+	}
+
 	/* Disable both source and sink first before enabling anything */
 
 	if (!source) {
diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h
index 04c49a0b0368..4d441bdf24d5 100644
--- a/drivers/usb/typec/tcpm/tcpci.h
+++ b/drivers/usb/typec/tcpm/tcpci.h
@@ -144,6 +144,7 @@ struct tcpci_data {
 			 bool enable);
 	int (*start_drp_toggling)(struct tcpci *tcpci, struct tcpci_data *data,
 				  enum typec_cc_status cc);
+	int (*set_vbus)(struct tcpci *tcpci, struct tcpci_data *data, bool source, bool sink);
 };
 
 struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data);
-- 
2.28.0.297.g1956fa8f8d-goog


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

* [PATCH 06/14 v1] dt-bindings: usb: Maxim type-c controller device tree binding document
  2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
                   ` (4 preceding siblings ...)
  2020-08-25  4:22 ` [PATCH 05/14 v5] usb: typec: tcpci: Add set_vbus tcpci callback Badhri Jagan Sridharan
@ 2020-08-25  4:22 ` Badhri Jagan Sridharan
  2020-08-25  4:22 ` [PATCH 07/14 v1] usb: typec: tcpci_maxim: Chip level TCPC driver Badhri Jagan Sridharan
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:22 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

Add device tree binding document for Maxim TCPCI based Type-C chip driver

Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
---
 .../devicetree/bindings/usb/maxim,tcpci.txt   | 44 +++++++++++++++++++
 1 file changed, 44 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/maxim,tcpci.txt

diff --git a/Documentation/devicetree/bindings/usb/maxim,tcpci.txt b/Documentation/devicetree/bindings/usb/maxim,tcpci.txt
new file mode 100644
index 000000000000..8a5b08e57b2d
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/maxim,tcpci.txt
@@ -0,0 +1,44 @@
+Maxim TCPCI Type-C PD controller:
+---------------------------------
+
+Required properties:
+- compatible:       should be set maxim,tcpci:
+
+- reg:              0x25:the i2c slave address of typec port controller device.
+- interrupt-parent: the phandle to the interrupt controller which provides
+                    the interrupt.
+- usbpd,usbpd_int:  interrupt specification for tcpci alert.
+
+Required sub-node:
+- connector: The "usb-c-connector" attached to the tcpci chip, the bindings
+  of connector node are specified in
+  Documentation/devicetree/bindings/connector/usb-connector.txt
+
+maxtcpc: maxtcpc@25 {
+	status = "okay";
+	compatible = "maxim,tcpc";
+	reg = <0x25>;
+	interrupt-parent = <&gpa8>;
+	usbpd,usbpd_int = <&gpa8 2 GPIO_ACTIVE_LOW>;
+
+	connector {
+		compatible = "usb-c-connector";
+		label = "USB-C";
+		data-role = "dual";
+		power-role = "dual";
+		try-power-role = "sink";
+		self-powered;
+		op-sink-microwatt = <2600000>;
+		source-pdos = <PDO_FIXED(5000, 900,
+					 PDO_FIXED_SUSPEND |
+					 PDO_FIXED_USB_COMM |
+					 PDO_FIXED_DATA_SWAP |
+					 PDO_FIXED_DUAL_ROLE)>;
+		sink-pdos = <PDO_FIXED(5000, 3000,
+				       PDO_FIXED_USB_COMM |
+				       PDO_FIXED_DATA_SWAP |
+				       PDO_FIXED_DUAL_ROLE)
+				       PDO_FIXED(9000, 2000, 0)
+		frs-typec-current = <FRS_5V_1P5A>;
+	};
+};
-- 
2.28.0.297.g1956fa8f8d-goog


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

* [PATCH 07/14 v1] usb: typec: tcpci_maxim: Chip level TCPC driver
  2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
                   ` (5 preceding siblings ...)
  2020-08-25  4:22 ` [PATCH 06/14 v1] dt-bindings: usb: Maxim type-c controller device tree binding document Badhri Jagan Sridharan
@ 2020-08-25  4:22 ` Badhri Jagan Sridharan
  2020-08-25  5:16   ` Randy Dunlap
  2020-08-25  4:22 ` [PATCH 08/14 v1] dt-bindings: connector: Add property to set initial current cap for FRS Badhri Jagan Sridharan
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:22 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

Chip level TCPC driver for Maxim's TCPCI implementation.
This TCPC implementation does not support the following
commands: COMMAND.SinkVbus, COMMAND.SourceVbusDefaultVoltage,
COMMAND.SourceVbusHighVoltage. Instead the sinking and sourcing
from vbus is supported by writes to custom registers.

Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
---
 drivers/usb/typec/tcpm/Kconfig       |   6 +
 drivers/usb/typec/tcpm/Makefile      |  13 +-
 drivers/usb/typec/tcpm/tcpci.h       |   1 +
 drivers/usb/typec/tcpm/tcpci_maxim.c | 474 +++++++++++++++++++++++++++
 4 files changed, 488 insertions(+), 6 deletions(-)
 create mode 100644 drivers/usb/typec/tcpm/tcpci_maxim.c

diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
index fa3f39336246..7c9722b02afe 100644
--- a/drivers/usb/typec/tcpm/Kconfig
+++ b/drivers/usb/typec/tcpm/Kconfig
@@ -27,6 +27,12 @@ config TYPEC_RT1711H
 	  Type-C Port Controller Manager to provide USB PD and USB
 	  Type-C functionalities.
 
+config TYPEC_TCPCI_MAXIM
+	tristate "Maxim TCPCI based Type-C chip driver"
+	select USB_PSY
+	help
+	  MAXIM TCPCI based Type-C chip driver
+
 endif # TYPEC_TCPCI
 
 config TYPEC_FUSB302
diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile
index a5ff6c8eb892..58d001cf0dd2 100644
--- a/drivers/usb/typec/tcpm/Makefile
+++ b/drivers/usb/typec/tcpm/Makefile
@@ -1,7 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_TYPEC_TCPM)	+= tcpm.o
-obj-$(CONFIG_TYPEC_FUSB302)	+= fusb302.o
-obj-$(CONFIG_TYPEC_WCOVE)	+= typec_wcove.o
-typec_wcove-y			:= wcove.o
-obj-$(CONFIG_TYPEC_TCPCI)	+= tcpci.o
-obj-$(CONFIG_TYPEC_RT1711H)	+= tcpci_rt1711h.o
+obj-$(CONFIG_TYPEC_TCPM)		+= tcpm.o
+obj-$(CONFIG_TYPEC_FUSB302)		+= fusb302.o
+obj-$(CONFIG_TYPEC_WCOVE)		+= typec_wcove.o
+typec_wcove-y				:= wcove.o
+obj-$(CONFIG_TYPEC_TCPCI)		+= tcpci.o
+obj-$(CONFIG_TYPEC_RT1711H)		+= tcpci_rt1711h.o
+obj-$(CONFIG_TYPEC_TCPCI_MAXIM)		+= tcpci_maxim.o
diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h
index 4d441bdf24d5..82f021a82456 100644
--- a/drivers/usb/typec/tcpm/tcpci.h
+++ b/drivers/usb/typec/tcpm/tcpci.h
@@ -109,6 +109,7 @@
 
 #define TCPC_RX_BYTE_CNT		0x30
 #define TCPC_RX_BUF_FRAME_TYPE		0x31
+#define TCPC_RX_BUF_FRAME_TYPE_SOP	0
 #define TCPC_RX_HDR			0x32
 #define TCPC_RX_DATA			0x34 /* through 0x4f */
 
diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.c b/drivers/usb/typec/tcpm/tcpci_maxim.c
new file mode 100644
index 000000000000..b61f290a8f96
--- /dev/null
+++ b/drivers/usb/typec/tcpm/tcpci_maxim.c
@@ -0,0 +1,474 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020, Google LLC
+ *
+ * MAXIM TCPCI based TCPC driver
+ */
+
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/regmap.h>
+#include <linux/usb/pd.h>
+#include <linux/usb/tcpm.h>
+#include <linux/usb/typec.h>
+
+#include "tcpci.h"
+
+#define PD_ACTIVITY_TIMEOUT_MS				10000
+
+#define TCPC_VENDOR_ALERT				0x80
+
+#define TCPC_RECEIVE_BUFFER_COUNT_OFFSET		0
+#define TCPC_RECEIVE_BUFFER_FRAME_TYPE_OFFSET		1
+#define TCPC_RECEIVE_BUFFER_RX_BYTE_BUF_OFFSET		2
+
+/*
+ * LongMessage not supported, hence 32 bytes for buf to be read from RECEIVE_BUFFER.
+ * DEVICE_CAPABILITIES_2.LongMessage = 0, the value in READABLE_BYTE_COUNT reg shall be
+ * less than or equal to 31. Since, RECEIVE_BUFFER len = 31 + 1(READABLE_BYTE_COUNT).
+ */
+#define TCPC_RECEIVE_BUFFER_LEN				32
+
+#define MAX_BUCK_BOOST_SID				0x69
+#define MAX_BUCK_BOOST_OP				0xb9
+#define MAX_BUCK_BOOST_OFF				0
+#define MAX_BUCK_BOOST_SOURCE				0xa
+#define MAX_BUCK_BOOST_SINK				0x5
+
+struct max_tcpci_chip {
+	struct tcpci_data data;
+	struct tcpci *tcpci;
+	struct device *dev;
+	struct i2c_client *client;
+	struct tcpm_port *port;
+};
+
+static const struct regmap_range max_tcpci_tcpci_range[] = {
+	regmap_reg_range(0x00, 0x95)
+};
+
+const struct regmap_access_table max_tcpci_tcpci_write_table = {
+	.yes_ranges = max_tcpci_tcpci_range,
+	.n_yes_ranges = ARRAY_SIZE(max_tcpci_tcpci_range),
+};
+
+static const struct regmap_config max_tcpci_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = 0x95,
+	.wr_table = &max_tcpci_tcpci_write_table,
+};
+
+static struct max_tcpci_chip *tdata_to_max_tcpci(struct tcpci_data *tdata)
+{
+	return container_of(tdata, struct max_tcpci_chip, data);
+}
+
+static int max_tcpci_read16(struct max_tcpci_chip *chip, unsigned int reg, u16 *val)
+{
+	return regmap_raw_read(chip->data.regmap, reg, val, sizeof(u16));
+}
+
+static int max_tcpci_write16(struct max_tcpci_chip *chip, unsigned int reg, u16 val)
+{
+	return regmap_raw_write(chip->data.regmap, reg, &val, sizeof(u16));
+}
+
+static int max_tcpci_read8(struct max_tcpci_chip *chip, unsigned int reg, u8 *val)
+{
+	return regmap_raw_read(chip->data.regmap, reg, val, sizeof(u8));
+}
+
+static int max_tcpci_write8(struct max_tcpci_chip *chip, unsigned int reg, u8 val)
+{
+	return regmap_raw_write(chip->data.regmap, reg, &val, sizeof(u8));
+}
+
+static void max_tcpci_init_regs(struct max_tcpci_chip *chip)
+{
+	u16 alert_mask = 0;
+	int ret;
+
+	ret = max_tcpci_write16(chip, TCPC_ALERT, 0xffff);
+	if (ret < 0) {
+		dev_err(chip->dev, "Error writing to TCPC_ALERT ret:%d\n", ret);
+		return;
+	}
+
+	ret = max_tcpci_write16(chip, TCPC_VENDOR_ALERT, 0xffff);
+	if (ret < 0) {
+		dev_err(chip->dev, "Error writing to TCPC_VENDOR_ALERT ret:%d\n", ret);
+		return;
+	}
+
+	alert_mask = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_DISCARDED | TCPC_ALERT_TX_FAILED |
+		TCPC_ALERT_RX_HARD_RST | TCPC_ALERT_RX_STATUS | TCPC_ALERT_CC_STATUS |
+		TCPC_ALERT_VBUS_DISCNCT | TCPC_ALERT_RX_BUF_OVF | TCPC_ALERT_POWER_STATUS;
+
+	ret = max_tcpci_write16(chip, TCPC_ALERT_MASK, alert_mask);
+	if (ret < 0) {
+		dev_err(chip->dev, "Error writing to TCPC_ALERT_MASK ret:%d\n", ret);
+		return;
+	}
+
+	/* Enable vbus voltage monitoring and voltage alerts */
+	ret = max_tcpci_write8(chip, TCPC_POWER_CTRL, 0);
+	if (ret < 0) {
+		dev_err(chip->dev, "Error writing to TCPC_POWER_CTRL ret:%d\n", ret);
+		return;
+	}
+}
+
+static void process_rx(struct max_tcpci_chip *chip, u16 status)
+{
+	struct pd_message msg;
+	u8 count, frame_type, rx_buf[TCPC_RECEIVE_BUFFER_LEN];
+	int ret, payload_index;
+	u8 *rx_buf_ptr;
+
+	/*
+	 * READABLE_BYTE_COUNT: Indicates the number of bytes in the RX_BUF_BYTE_x registers
+	 * plus one (for the RX_BUF_FRAME_TYPE) Table 4-36.
+	 * Read the count and frame type.
+	 */
+	ret = regmap_raw_read(chip->data.regmap, TCPC_RX_BYTE_CNT, rx_buf, 2);
+	if (ret < 0) {
+		dev_err(chip->dev, "TCPC_RX_BYTE_CNT read failed ret:%d", ret);
+		return;
+	}
+
+	count = rx_buf[TCPC_RECEIVE_BUFFER_COUNT_OFFSET];
+	frame_type = rx_buf[TCPC_RECEIVE_BUFFER_FRAME_TYPE_OFFSET];
+
+	if (count == 0 || frame_type != TCPC_RX_BUF_FRAME_TYPE_SOP) {
+		max_tcpci_write16(chip, TCPC_ALERT, TCPC_ALERT_RX_STATUS);
+		dev_err(chip->dev, "%s", count ==  0 ? "error: count is 0" :
+			"error frame_type is not SOP");
+		return;
+	}
+
+	if (count > sizeof(struct pd_message) || count + 1 > TCPC_RECEIVE_BUFFER_LEN) {
+		dev_err(chip->dev, "Invalid TCPC_RX_BYTE_CNT %d", count);
+		return;
+	}
+
+	/*
+	 * Read count + 1 as RX_BUF_BYTE_x is hidden and can only be read through
+	 * TCPC_RX_BYTE_CNT
+	 */
+	count += 1;
+	ret = regmap_raw_read(chip->data.regmap, TCPC_RX_BYTE_CNT, rx_buf, count);
+	if (ret < 0) {
+		dev_err(chip->dev, "Error: TCPC_RX_BYTE_CNT read failed: %d", ret);
+		return;
+	}
+
+	rx_buf_ptr = rx_buf + TCPC_RECEIVE_BUFFER_RX_BYTE_BUF_OFFSET;
+	msg.header = cpu_to_le16(*(u16 *)rx_buf_ptr);
+	rx_buf_ptr = rx_buf_ptr + sizeof(msg.header);
+	for (payload_index = 0; payload_index < pd_header_cnt_le(msg.header); payload_index++,
+	     rx_buf_ptr += sizeof(msg.payload[0]))
+		msg.payload[payload_index] = cpu_to_le32(*(u32 *)rx_buf_ptr);
+
+	/*
+	 * Read complete, clear RX status alert bit.
+	 * Clear overflow as well if set.
+	 */
+	ret = max_tcpci_write16(chip, TCPC_ALERT, status & TCPC_ALERT_RX_BUF_OVF ?
+				TCPC_ALERT_RX_STATUS | TCPC_ALERT_RX_BUF_OVF :
+				TCPC_ALERT_RX_STATUS);
+	if (ret < 0)
+		return;
+
+	tcpm_pd_receive(chip->port, &msg);
+}
+
+static int max_tcpci_set_vbus(struct tcpci *tcpci, struct tcpci_data *tdata, bool source, bool sink)
+{
+	struct max_tcpci_chip *chip = tdata_to_max_tcpci(tdata);
+	u8 buffer_source[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_SOURCE};
+	u8 buffer_sink[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_SINK};
+	u8 buffer_none[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_OFF};
+	struct i2c_client *i2c = chip->client;
+	int ret;
+
+	struct i2c_msg msgs[] = {
+		{
+			.addr = MAX_BUCK_BOOST_SID,
+			.flags = i2c->flags & I2C_M_TEN,
+			.len = 2,
+			.buf = source ? buffer_source : sink ? buffer_sink : buffer_none,
+		},
+	};
+
+	if (source && sink) {
+		dev_err(chip->dev, "Both source and sink set\n");
+		return -EINVAL;
+	}
+
+	ret = i2c_transfer(i2c->adapter, msgs, 1);
+
+	return  ret < 0 ? ret : 1;
+}
+
+static void process_power_status(struct max_tcpci_chip *chip)
+{
+	u8 pwr_status;
+	int ret;
+
+	ret = max_tcpci_read8(chip, TCPC_POWER_STATUS, &pwr_status);
+	if (ret < 0)
+		return;
+
+	if (pwr_status == 0xff)
+		max_tcpci_init_regs(chip);
+	else
+		tcpm_vbus_change(chip->port);
+}
+
+static void process_tx(struct max_tcpci_chip *chip, u16 status)
+{
+	if (status & TCPC_ALERT_TX_SUCCESS)
+		tcpm_pd_transmit_complete(chip->port, TCPC_TX_SUCCESS);
+	else if (status & TCPC_ALERT_TX_DISCARDED)
+		tcpm_pd_transmit_complete(chip->port, TCPC_TX_DISCARDED);
+	else if (status & TCPC_ALERT_TX_FAILED)
+		tcpm_pd_transmit_complete(chip->port, TCPC_TX_FAILED);
+
+	/* Reinit regs as Hard reset sets them to default value */
+	if ((status & TCPC_ALERT_TX_SUCCESS) && (status & TCPC_ALERT_TX_FAILED))
+		max_tcpci_init_regs(chip);
+}
+
+static irqreturn_t _max_tcpci_irq(struct max_tcpci_chip *chip, u16 status)
+{
+	u16 mask;
+	int ret;
+
+	/*
+	 * Clear alert status for everything except RX_STATUS, which shouldn't
+	 * be cleared until we have successfully retrieved message.
+	 */
+	if (status & ~TCPC_ALERT_RX_STATUS) {
+		mask = status & TCPC_ALERT_RX_BUF_OVF ?
+			status & ~(TCPC_ALERT_RX_STATUS | TCPC_ALERT_RX_BUF_OVF) :
+			status & ~TCPC_ALERT_RX_STATUS;
+		ret = max_tcpci_write16(chip, TCPC_ALERT, mask);
+		if (ret < 0) {
+			dev_err(chip->dev, "ALERT clear failed\n");
+			return ret;
+		}
+	}
+
+	if (status & TCPC_ALERT_RX_BUF_OVF && !(status & TCPC_ALERT_RX_STATUS)) {
+		ret = max_tcpci_write16(chip, TCPC_ALERT, (TCPC_ALERT_RX_STATUS |
+							  TCPC_ALERT_RX_BUF_OVF));
+		if (ret < 0) {
+			dev_err(chip->dev, "ALERT clear failed\n");
+			return ret;
+		}
+	}
+
+	if (status & TCPC_ALERT_RX_STATUS)
+		process_rx(chip, status);
+
+	if (status & TCPC_ALERT_TX_DISCARDED)
+		dev_info(chip->dev, "TX_DISCARDED");
+
+	if (status & TCPC_ALERT_VBUS_DISCNCT)
+		tcpm_vbus_change(chip->port);
+
+	if (status & TCPC_ALERT_CC_STATUS)
+		tcpm_cc_change(chip->port);
+
+	if (status & TCPC_ALERT_POWER_STATUS)
+		process_power_status(chip);
+
+	if (status & TCPC_ALERT_RX_HARD_RST) {
+		tcpm_pd_hard_reset(chip->port);
+		max_tcpci_init_regs(chip);
+	}
+
+	if (status & TCPC_ALERT_TX_SUCCESS || status & TCPC_ALERT_TX_DISCARDED || status &
+	    TCPC_ALERT_TX_FAILED)
+		process_tx(chip, status);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t max_tcpci_irq(int irq, void *dev_id)
+{
+	struct max_tcpci_chip *chip = dev_id;
+	u16 status;
+	irqreturn_t irq_return;
+	int ret;
+
+	if (!chip->port)
+		return IRQ_HANDLED;
+
+	ret = max_tcpci_read16(chip, TCPC_ALERT, &status);
+	if (ret < 0) {
+		dev_err(chip->dev, "ALERT read failed\n");
+		return ret;
+	}
+	while (status) {
+		irq_return = _max_tcpci_irq(chip, status);
+		/* Do not return if the ALERT is already set. */
+		ret = max_tcpci_read16(chip, TCPC_ALERT, &status);
+		if (ret < 0)
+			break;
+	}
+
+	return irq_return;
+}
+
+static irqreturn_t max_tcpci_isr(int irq, void *dev_id)
+{
+	struct max_tcpci_chip *chip = dev_id;
+
+	pm_wakeup_event(chip->dev, PD_ACTIVITY_TIMEOUT_MS);
+
+	if (!chip->port)
+		return IRQ_HANDLED;
+
+	return IRQ_WAKE_THREAD;
+}
+
+static int max_tcpci_init_alert(struct max_tcpci_chip *chip, struct i2c_client *client)
+{
+	int ret, irq_gpio;
+
+	irq_gpio = of_get_named_gpio(client->dev.of_node, "usbpd,usbpd_int", 0);
+	client->irq = gpio_to_irq(irq_gpio);
+	if (!client->irq)
+		return -ENODEV;
+
+	ret = devm_request_threaded_irq(chip->dev, client->irq, max_tcpci_isr, max_tcpci_irq,
+					(IRQF_TRIGGER_LOW | IRQF_ONESHOT), dev_name(chip->dev),
+					chip);
+
+	if (ret < 0)
+		return ret;
+
+	enable_irq_wake(client->irq);
+	return 0;
+}
+
+static int max_tcpci_start_toggling(struct tcpci *tcpci, struct tcpci_data *tdata,
+				    enum typec_cc_status cc)
+{
+	struct max_tcpci_chip *chip = tdata_to_max_tcpci(tdata);
+
+	max_tcpci_init_regs(chip);
+
+	return 0;
+}
+
+static int tcpci_init(struct tcpci *tcpci, struct tcpci_data *data)
+{
+	/*
+	 * Generic TCPCI overwrites the regs once this driver initializes
+	 * them. Prevent this by returning -1.
+	 */
+	return -1;
+}
+
+static int max_tcpci_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id)
+{
+	int ret;
+	struct max_tcpci_chip *chip;
+	u8 power_status;
+
+	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->client = client;
+	chip->data.regmap = devm_regmap_init_i2c(client, &max_tcpci_regmap_config);
+	if (IS_ERR(chip->data.regmap)) {
+		dev_err(&client->dev, "Regmap init failed\n");
+		return PTR_ERR(chip->data.regmap);
+	}
+
+	chip->dev = &client->dev;
+	i2c_set_clientdata(client, chip);
+
+	ret = max_tcpci_read8(chip, TCPC_POWER_STATUS, &power_status);
+	if (ret < 0)
+		return ret;
+
+	if (power_status & TCPC_POWER_STATUS_UNINIT) {
+		dev_err(&client->dev, "TCPC not ready!");
+		return -EPROBE_DEFER;
+	}
+
+	/* Chip level tcpci callbacks */
+	chip->data.set_vbus = max_tcpci_set_vbus;
+	chip->data.start_drp_toggling = max_tcpci_start_toggling;
+	chip->data.TX_BUF_BYTE_x_hidden = true;
+	chip->data.init = tcpci_init;
+
+	max_tcpci_init_regs(chip);
+	chip->tcpci = tcpci_register_port(chip->dev, &chip->data);
+	if (IS_ERR_OR_NULL(chip->tcpci)) {
+		dev_err(&client->dev, "TCPCI port registration failed");
+		ret = PTR_ERR(chip->tcpci);
+		return PTR_ERR(chip->tcpci);
+	}
+	chip->port = tcpci_get_tcpm_port(chip->tcpci);
+	ret = max_tcpci_init_alert(chip, client);
+	if (ret < 0)
+		goto unreg_port;
+
+	device_init_wakeup(chip->dev, true);
+	return 0;
+
+unreg_port:
+	tcpci_unregister_port(chip->tcpci);
+
+	return ret;
+}
+
+static int max_tcpci_remove(struct i2c_client *client)
+{
+	struct max_tcpci_chip *chip = i2c_get_clientdata(client);
+
+	if (!IS_ERR_OR_NULL(chip->tcpci))
+		tcpci_unregister_port(chip->tcpci);
+
+	return 0;
+}
+
+static const struct i2c_device_id max_tcpci_id[] = {
+	{ "maxtcpc", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, max_tcpci_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id max_tcpci_of_match[] = {
+	{ .compatible = "maxim,tcpc", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, max_tcpci_of_match);
+#endif
+
+static struct i2c_driver max_tcpci_i2c_driver = {
+	.driver = {
+		.name = "maxtcpc",
+		.of_match_table = of_match_ptr(max_tcpci_of_match),
+	},
+	.probe = max_tcpci_probe,
+	.remove = max_tcpci_remove,
+	.id_table = max_tcpci_id,
+};
+module_i2c_driver(max_tcpci_i2c_driver);
+
+MODULE_AUTHOR("Badhri Jagan Sridharan <badhri@google.com>");
+MODULE_DESCRIPTION("Maxim TCPCI based USB Type-C Port Controller Interface Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.28.0.297.g1956fa8f8d-goog


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

* [PATCH 08/14 v1] dt-bindings: connector: Add property to set initial current cap for FRS
  2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
                   ` (6 preceding siblings ...)
  2020-08-25  4:22 ` [PATCH 07/14 v1] usb: typec: tcpci_maxim: Chip level TCPC driver Badhri Jagan Sridharan
@ 2020-08-25  4:22 ` Badhri Jagan Sridharan
  2020-08-25  4:22 ` [PATCH 09/14 v1] usb: typec: tcpm: Add support for Sink Fast Role SWAP(FRS) Badhri Jagan Sridharan
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:22 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

This change adds frs-typec-current which allows setting the initial current
capability of the new source when vSafe5V is applied during PD3.0
sink Fast Role Swap.

Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
---
 .../bindings/connector/usb-connector.txt      | 128 ++++++++++++++++++
 include/dt-bindings/usb/pd.h                  |  10 ++
 2 files changed, 138 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/connector/usb-connector.txt

diff --git a/Documentation/devicetree/bindings/connector/usb-connector.txt b/Documentation/devicetree/bindings/connector/usb-connector.txt
new file mode 100644
index 000000000000..e2f6e0f07d00
--- /dev/null
+++ b/Documentation/devicetree/bindings/connector/usb-connector.txt
@@ -0,0 +1,128 @@
+USB Connector
+=============
+
+USB connector node represents physical USB connector. It should be
+a child of USB interface controller.
+
+Required properties:
+- compatible: describes type of the connector, must be one of:
+    "usb-a-connector",
+    "usb-b-connector",
+    "usb-c-connector".
+
+Optional properties:
+- label: symbolic name for the connector,
+- type: size of the connector, should be specified in case of USB-A, USB-B
+  non-fullsize connectors: "mini", "micro".
+
+Optional properties for usb-c-connector:
+- power-role: should be one of "source", "sink" or "dual"(DRP) if typec
+  connector has power support.
+- try-power-role: preferred power role if "dual"(DRP) can support Try.SNK
+  or Try.SRC, should be "sink" for Try.SNK or "source" for Try.SRC.
+- data-role: should be one of "host", "device", "dual"(DRD) if typec
+  connector supports USB data.
+- frs-typec-current - Initial current capability of the new source when vSafe5V
+  is applied during PD3.0 Fast Role Swap. "Table 6-14 Fixed Supply PDO - Sink"
+  of "USB Power Delivery Specification Revision 3.0, Version 1.2" provides the
+  different power levels and "6.4.1.3.1.6 Fast Role Swap USB Type-C Current"
+  provides a detailed description of the field.
+  0: Fast role swap not supported
+  1: Default USB Power
+  2: 1.5A @ 5V
+  3: 3A @ 5V.
+
+Required properties for usb-c-connector with power delivery support:
+- source-pdos: An array of u32 with each entry providing supported power
+  source data object(PDO), the detailed bit definitions of PDO can be found
+  in "Universal Serial Bus Power Delivery Specification" chapter 6.4.1.2
+  Source_Capabilities Message, the order of each entry(PDO) should follow
+  the PD spec chapter 6.4.1. Required for power source and power dual role.
+  User can specify the source PDO array via PDO_FIXED/BATT/VAR/PPS_APDO()
+  defined in dt-bindings/usb/pd.h.
+- sink-pdos: An array of u32 with each entry providing supported power
+  sink data object(PDO), the detailed bit definitions of PDO can be found
+  in "Universal Serial Bus Power Delivery Specification" chapter 6.4.1.3
+  Sink Capabilities Message, the order of each entry(PDO) should follow
+  the PD spec chapter 6.4.1. Required for power sink and power dual role.
+  User can specify the sink PDO array via PDO_FIXED/BATT/VAR/PPS_APDO() defined
+  in dt-bindings/usb/pd.h.
+- op-sink-microwatt: Sink required operating power in microwatt, if source
+  can't offer the power, Capability Mismatch is set. Required for power
+  sink and power dual role.
+
+Required nodes:
+- any data bus to the connector should be modeled using the OF graph bindings
+  specified in bindings/graph.txt, unless the bus is between parent node and
+  the connector. Since single connector can have multpile data buses every bus
+  has assigned OF graph port number as follows:
+    0: High Speed (HS), present in all connectors,
+    1: Super Speed (SS), present in SS capable connectors,
+    2: Sideband use (SBU), present in USB-C.
+
+Examples
+--------
+
+1. Micro-USB connector with HS lines routed via controller (MUIC):
+
+muic-max77843@66 {
+	...
+	usb_con: connector {
+		compatible = "usb-b-connector";
+		label = "micro-USB";
+		type = "micro";
+	};
+};
+
+2. USB-C connector attached to CC controller (s2mm005), HS lines routed
+to companion PMIC (max77865), SS lines to USB3 PHY and SBU to DisplayPort.
+DisplayPort video lines are routed to the connector via SS mux in USB3 PHY.
+
+ccic: s2mm005@33 {
+	...
+	usb_con: connector {
+		compatible = "usb-c-connector";
+		label = "USB-C";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				usb_con_hs: endpoint {
+					remote-endpoint = <&max77865_usbc_hs>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				usb_con_ss: endpoint {
+					remote-endpoint = <&usbdrd_phy_ss>;
+				};
+			};
+			port@2 {
+				reg = <2>;
+				usb_con_sbu: endpoint {
+					remote-endpoint = <&dp_aux>;
+				};
+			};
+		};
+	};
+};
+
+3. USB-C connector attached to a typec port controller(ptn5110), which has
+power delivery support and enables drp.
+
+typec: ptn5110@50 {
+	...
+	usb_con: connector {
+		compatible = "usb-c-connector";
+		label = "USB-C";
+		power-role = "dual";
+		try-power-role = "sink";
+		source-pdos = <PDO_FIXED(5000, 2000, PDO_FIXED_USB_COMM)>;
+		sink-pdos = <PDO_FIXED(5000, 2000, PDO_FIXED_USB_COMM)
+			     PDO_VAR(5000, 12000, 2000)>;
+		op-sink-microwatt = <10000000>;
+	};
+};
diff --git a/include/dt-bindings/usb/pd.h b/include/dt-bindings/usb/pd.h
index 985f2bbd4d24..db1ad4532197 100644
--- a/include/dt-bindings/usb/pd.h
+++ b/include/dt-bindings/usb/pd.h
@@ -35,6 +35,16 @@
 
 #define VSAFE5V 5000 /* mv units */
 
+/*
+ * Based on "Table 6-14 Fixed Supply PDO - Sink" of "USB Power Delivery Specification Revision 3.0,
+ * Version 1.2"
+ * Initial current capability of the new source when vSafe5V is applied.
+ */
+#define FRS_NOT_SUPPORTED	0
+#define FRS_DEFAULT_POWER	1
+#define FRS_5V_1P5A		2
+#define FRS_5V_3A		3
+
 #define PDO_BATT_MAX_VOLT_SHIFT	20	/* 50mV units */
 #define PDO_BATT_MIN_VOLT_SHIFT	10	/* 50mV units */
 #define PDO_BATT_MAX_PWR_SHIFT	0	/* 250mW units */
-- 
2.28.0.297.g1956fa8f8d-goog


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

* [PATCH 09/14 v1] usb: typec: tcpm: Add support for Sink Fast Role SWAP(FRS)
  2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
                   ` (7 preceding siblings ...)
  2020-08-25  4:22 ` [PATCH 08/14 v1] dt-bindings: connector: Add property to set initial current cap for FRS Badhri Jagan Sridharan
@ 2020-08-25  4:22 ` Badhri Jagan Sridharan
  2020-08-26 12:42   ` kernel test robot
  2020-08-25  4:22 ` [PATCH 10/14 v1] usb: typec: tcpci: Implement callbacks for FRS Badhri Jagan Sridharan
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:22 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

PD 3.0 spec defines a new mechanism for power role swap called
Fast role swap. This change enables TCPM to support FRS when
acting as sink.

Once the explicit contract is negotiated, sink port is
expected to query the source port for sink caps to
determine whether the source is FRS capable.
Bits 23 & 24 of fixed pdo of the sink caps from the source, when
set, indicates the current needed by the source when fast role
swap is in progress(Implicit contract phasae). 0 indicates that
the source does not support Fast Role Swap.

Upon receiving the FRS signal from the source,
TCPC(TCPM_FRS_EVENT) informs TCPM to start the Fast role swap sequence.

1. TCPM sends FRS PD message: FR_SWAP_SEND
2. If response is not received within the expiry of
   SenderResponseTimer, Error recovery is triggered.:
   FR_SWAP_SEND_TIMEOUT
3. Upon receipt of the accept message, TCPM waits for
   PSSourceOffTimer for PS_READY message from the partner:
   FR_SWAP_SNK_SRC_NEW_SINK_READY.

TCPC is expected to autonomously turn on vbus once the FRS
signal is received and vbus voltage falls below vsafe5v within
tSrcFrSwap. This is different from traditional power role swap
where the vbus sourcing is turned on by TCPM.

4. By this time, TCPC most likely would have started to
   source vbus, TCPM waits for tSrcFrSwap to see  if the
   lower level TCPC driver signals TCPM_SOURCING_VBUS event:
   FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED.
5. When TCPC signals sourcing vbus, TCPM sends PS_READY msg and
   changes the CC pin from Rd to Rp. This is the end of fast
   role swap sequence and TCPM initiates the sequnce to negotiate
   explicit contract by transitioning into SRC_STARTUP after
   SwapSrcStart.

The code is written based on the sequence described in "Figure 8-107:
Dual-role Port in Sink to Source Fast Role Swap State Diagram" of
USB Power Delivery Specification Revision 3.0, Version 1.2.

Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
---
 drivers/usb/typec/tcpm/tcpm.c | 191 +++++++++++++++++++++++++++++++++-
 include/linux/usb/pd.h        |  20 ++--
 include/linux/usb/tcpm.h      |   8 +-
 include/linux/usb/typec.h     |  13 +++
 4 files changed, 220 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index 3ef37202ee37..6ea4613af905 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -103,6 +103,13 @@
 	S(VCONN_SWAP_TURN_ON_VCONN),		\
 	S(VCONN_SWAP_TURN_OFF_VCONN),		\
 						\
+	S(FR_SWAP_SEND),			\
+	S(FR_SWAP_SEND_TIMEOUT),		\
+	S(FR_SWAP_SNK_SRC_TRANSITION_TO_OFF),			\
+	S(FR_SWAP_SNK_SRC_NEW_SINK_READY),		\
+	S(FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED),	\
+	S(FR_SWAP_CANCEL),			\
+						\
 	S(SNK_TRY),				\
 	S(SNK_TRY_WAIT),			\
 	S(SNK_TRY_WAIT_DEBOUNCE),               \
@@ -124,6 +131,9 @@
 	S(GET_PPS_STATUS_SEND),			\
 	S(GET_PPS_STATUS_SEND_TIMEOUT),		\
 						\
+	S(GET_SINK_CAP),			\
+	S(GET_SINK_CAP_TIMEOUT),		\
+						\
 	S(ERROR_RECOVERY),			\
 	S(PORT_RESET),				\
 	S(PORT_RESET_WAIT_OFF)
@@ -172,6 +182,8 @@ enum adev_actions {
 #define TCPM_CC_EVENT		BIT(0)
 #define TCPM_VBUS_EVENT		BIT(1)
 #define TCPM_RESET_EVENT	BIT(2)
+#define TCPM_FRS_EVENT		BIT(3)
+#define TCPM_SOURCING_VBUS	BIT(4)
 
 #define LOG_BUFFER_ENTRIES	1024
 #define LOG_BUFFER_ENTRY_SIZE	128
@@ -181,6 +193,8 @@ enum adev_actions {
 #define SVID_DISCOVERY_MAX	16
 #define ALTMODE_DISCOVERY_MAX	(SVID_DISCOVERY_MAX * MODE_DISCOVERY_MAX)
 
+#define GET_SINK_CAP_RETRY_MS	100
+
 struct pd_mode_data {
 	int svid_index;		/* current SVID index		*/
 	int nsvids;
@@ -256,6 +270,7 @@ struct tcpm_port {
 	struct work_struct event_work;
 	struct delayed_work state_machine;
 	struct delayed_work vdm_state_machine;
+	struct delayed_work enable_frs;
 	bool state_machine_running;
 
 	struct completion tx_complete;
@@ -330,6 +345,12 @@ struct tcpm_port {
 	/* port belongs to a self powered device */
 	bool self_powered;
 
+	/* FRS */
+	enum frs_typec_current frs_current;
+
+	/* Sink caps have been queried */
+	bool sink_cap_done;
+
 #ifdef CONFIG_DEBUG_FS
 	struct dentry *dentry;
 	struct mutex logbuffer_lock;	/* log buffer access lock */
@@ -1646,6 +1667,9 @@ static void tcpm_pd_data_request(struct tcpm_port *port,
 	unsigned int cnt = pd_header_cnt_le(msg->header);
 	unsigned int rev = pd_header_rev_le(msg->header);
 	unsigned int i;
+	enum frs_typec_current frs_current;
+	bool frs_enable;
+	int ret;
 
 	switch (type) {
 	case PD_DATA_SOURCE_CAP:
@@ -1715,7 +1739,21 @@ static void tcpm_pd_data_request(struct tcpm_port *port,
 		/* We don't do anything with this at the moment... */
 		for (i = 0; i < cnt; i++)
 			port->sink_caps[i] = le32_to_cpu(msg->payload[i]);
+
+		frs_current = (port->sink_caps[0] & PDO_FIXED_FRS_CURR_MASK) >>
+			PDO_FIXED_FRS_CURR_SHIFT;
+		frs_enable = frs_current && (frs_current <= port->typec_caps.frs_current);
+		tcpm_log(port,
+			 "Port partner FRS capable partner_frs_current:%u port_frs_current:%u enable:%c",
+			 frs_current, port->typec_caps.frs_current, frs_enable ? 'y' : 'n');
+		if (frs_enable) {
+			ret  = port->tcpc->enable_frs(port->tcpc, true);
+			tcpm_log(port, "Enable FRS %s, ret:%d\n", ret ? "fail" : "success", ret);
+		}
+
 		port->nr_sink_caps = cnt;
+		port->sink_cap_done = true;
+		tcpm_set_state(port, SNK_READY, 0);
 		break;
 	case PD_DATA_VENDOR_DEF:
 		tcpm_handle_vdm_request(port, msg->payload, cnt);
@@ -1810,6 +1848,9 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
 		case VCONN_SWAP_WAIT_FOR_VCONN:
 			tcpm_set_state(port, VCONN_SWAP_TURN_OFF_VCONN, 0);
 			break;
+		case FR_SWAP_SNK_SRC_TRANSITION_TO_OFF:
+			tcpm_set_state(port, FR_SWAP_SNK_SRC_NEW_SINK_READY, 0);
+			break;
 		default:
 			break;
 		}
@@ -1849,6 +1890,13 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
 					     -EAGAIN : -EOPNOTSUPP);
 			tcpm_set_state(port, VCONN_SWAP_CANCEL, 0);
 			break;
+		case FR_SWAP_SEND:
+			tcpm_set_state(port, FR_SWAP_CANCEL, 0);
+			break;
+		case GET_SINK_CAP:
+			port->sink_cap_done = true;
+			tcpm_set_state(port, ready_state(port), 0);
+			break;
 		default:
 			break;
 		}
@@ -1883,6 +1931,9 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
 		case VCONN_SWAP_SEND:
 			tcpm_set_state(port, VCONN_SWAP_START, 0);
 			break;
+		case FR_SWAP_SEND:
+			tcpm_set_state(port, FR_SWAP_SNK_SRC_TRANSITION_TO_OFF, 0);
+			break;
 		default:
 			break;
 		}
@@ -2783,6 +2834,10 @@ static void tcpm_reset_port(struct tcpm_port *port)
 	port->try_src_count = 0;
 	port->try_snk_count = 0;
 	port->usb_type = POWER_SUPPLY_USB_TYPE_C;
+	port->nr_sink_caps = 0;
+	port->sink_cap_done = false;
+	if (port->tcpc->enable_frs)
+		port->tcpc->enable_frs(port->tcpc, false);
 
 	power_supply_changed(port->psy);
 }
@@ -3334,10 +3389,9 @@ static void run_state_machine(struct tcpm_port *port)
 		tcpm_swap_complete(port, 0);
 		tcpm_typec_connect(port);
 		tcpm_check_send_discover(port);
+		mod_delayed_work(port->wq, &port->enable_frs, msecs_to_jiffies(0));
 		tcpm_pps_complete(port, port->pps_status);
-
 		power_supply_changed(port->psy);
-
 		break;
 
 	/* Accessory states */
@@ -3361,9 +3415,13 @@ static void run_state_machine(struct tcpm_port *port)
 		tcpm_set_state(port, HARD_RESET_START, 0);
 		break;
 	case HARD_RESET_START:
+		port->sink_cap_done = false;
+		if (port->tcpc->enable_frs)
+			port->tcpc->enable_frs(port->tcpc, false);
 		port->hard_reset_count++;
 		port->tcpc->set_pd_rx(port->tcpc, false);
 		tcpm_unregister_altmodes(port);
+		port->nr_sink_caps = 0;
 		port->send_discover = true;
 		if (port->pwr_role == TYPEC_SOURCE)
 			tcpm_set_state(port, SRC_HARD_RESET_VBUS_OFF,
@@ -3477,6 +3535,35 @@ static void run_state_machine(struct tcpm_port *port)
 		tcpm_set_state(port, ready_state(port), 0);
 		break;
 
+	case FR_SWAP_SEND:
+		if (tcpm_pd_send_control(port, PD_CTRL_FR_SWAP)) {
+			tcpm_set_state(port, ERROR_RECOVERY, 0);
+			break;
+		}
+		tcpm_set_state_cond(port, FR_SWAP_SEND_TIMEOUT, PD_T_SENDER_RESPONSE);
+		break;
+	case FR_SWAP_SEND_TIMEOUT:
+		tcpm_set_state(port, ERROR_RECOVERY, 0);
+		break;
+	case FR_SWAP_SNK_SRC_TRANSITION_TO_OFF:
+		tcpm_set_state(port, ERROR_RECOVERY, PD_T_PS_SOURCE_OFF);
+		break;
+	case FR_SWAP_SNK_SRC_NEW_SINK_READY:
+		if (port->vbus_source)
+			tcpm_set_state(port, FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED, 0);
+		else
+			tcpm_set_state(port, ERROR_RECOVERY, PD_T_RECEIVER_RESPONSE);
+		break;
+	case FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED:
+		tcpm_set_pwr_role(port, TYPEC_SOURCE);
+		if (tcpm_pd_send_control(port, PD_CTRL_PS_RDY)) {
+			tcpm_set_state(port, ERROR_RECOVERY, 0);
+			break;
+		}
+		tcpm_set_cc(port, tcpm_rp_cc(port));
+		tcpm_set_state(port, SRC_STARTUP, PD_T_SWAP_SRC_START);
+		break;
+
 	/* PR_Swap states */
 	case PR_SWAP_ACCEPT:
 		tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
@@ -3595,6 +3682,7 @@ static void run_state_machine(struct tcpm_port *port)
 	case PR_SWAP_CANCEL:
 	case VCONN_SWAP_CANCEL:
 		tcpm_swap_complete(port, port->swap_status);
+	case FR_SWAP_CANCEL:
 		if (port->pwr_role == TYPEC_SOURCE)
 			tcpm_set_state(port, SRC_READY, 0);
 		else
@@ -3634,6 +3722,14 @@ static void run_state_machine(struct tcpm_port *port)
 	case GET_PPS_STATUS_SEND_TIMEOUT:
 		tcpm_set_state(port, ready_state(port), 0);
 		break;
+	case GET_SINK_CAP:
+		tcpm_pd_send_control(port, PD_CTRL_GET_SINK_CAP);
+		tcpm_set_state(port, GET_SINK_CAP_TIMEOUT, PD_T_SENDER_RESPONSE);
+		break;
+	case GET_SINK_CAP_TIMEOUT:
+		port->sink_cap_done = true;
+		tcpm_set_state(port, ready_state(port), 0);
+		break;
 	case ERROR_RECOVERY:
 		tcpm_swap_complete(port, -EPROTO);
 		tcpm_pps_complete(port, -EPROTO);
@@ -3850,6 +3946,13 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,
 		 * Ignore it.
 		 */
 		break;
+	case FR_SWAP_SEND:
+	case FR_SWAP_SEND_TIMEOUT:
+	case FR_SWAP_SNK_SRC_TRANSITION_TO_OFF:
+	case FR_SWAP_SNK_SRC_NEW_SINK_READY:
+	case FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED:
+		/* Do nothing, CC change expected */
+		break;
 
 	case PORT_RESET:
 	case PORT_RESET_WAIT_OFF:
@@ -3920,6 +4023,9 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port)
 	case SRC_TRY_DEBOUNCE:
 		/* Do nothing, waiting for sink detection */
 		break;
+	case FR_SWAP_SNK_SRC_NEW_SINK_READY:
+		tcpm_set_state(port, FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED, 0);
+		break;
 
 	case PORT_RESET:
 	case PORT_RESET_WAIT_OFF:
@@ -3995,6 +4101,14 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port)
 		 */
 		break;
 
+	case FR_SWAP_SEND:
+	case FR_SWAP_SEND_TIMEOUT:
+	case FR_SWAP_SNK_SRC_TRANSITION_TO_OFF:
+	case FR_SWAP_SNK_SRC_NEW_SINK_READY:
+	case FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED:
+		/* Do nothing, vbus drop expected */
+		break;
+
 	default:
 		if (port->pwr_role == TYPEC_SINK &&
 		    port->attached)
@@ -4049,6 +4163,25 @@ static void tcpm_pd_event_handler(struct work_struct *work)
 			if (port->tcpc->get_cc(port->tcpc, &cc1, &cc2) == 0)
 				_tcpm_cc_change(port, cc1, cc2);
 		}
+		if (events & TCPM_FRS_EVENT) {
+			if (port->state == SNK_READY)
+				tcpm_set_state(port, FR_SWAP_SEND, 0);
+			else
+				tcpm_log(port, "Discarding FRS_SIGNAL! Not in sink ready");
+		}
+		if (events & TCPM_SOURCING_VBUS) {
+			tcpm_log(port, "sourcing vbus");
+			/*
+			 * In fast role swap case TCPC autonomously sources vbus. Set vbus_source
+			 * true as TCPM wouldn't have called tcpm_set_vbus.
+			 *
+			 * When vbus is sourced on the command on TCPM i.e. TCPM called
+			 * tcpm_set_vbus to source vbus, vbus_source would already be true.
+			 */
+			port->vbus_source = true;
+			_tcpm_pd_vbus_on(port);
+		}
+
 		spin_lock(&port->pd_event_lock);
 	}
 	spin_unlock(&port->pd_event_lock);
@@ -4082,6 +4215,50 @@ void tcpm_pd_hard_reset(struct tcpm_port *port)
 }
 EXPORT_SYMBOL_GPL(tcpm_pd_hard_reset);
 
+void tcpm_sink_frs(struct tcpm_port *port)
+{
+	spin_lock(&port->pd_event_lock);
+	port->pd_events = TCPM_FRS_EVENT;
+	spin_unlock(&port->pd_event_lock);
+	queue_work(port->wq, &port->event_work);
+}
+EXPORT_SYMBOL_GPL(tcpm_sink_frs);
+
+void tcpm_sourcing_vbus(struct tcpm_port *port)
+{
+	spin_lock(&port->pd_event_lock);
+	port->pd_events = TCPM_SOURCING_VBUS;
+	spin_unlock(&port->pd_event_lock);
+	queue_work(port->wq, &port->event_work);
+}
+EXPORT_SYMBOL_GPL(tcpm_sourcing_vbus);
+
+static void tcpm_enable_frs(struct work_struct *work)
+{
+	struct tcpm_port *port = container_of(work, struct tcpm_port, enable_frs.work);
+
+	mutex_lock(&port->lock);
+	/* Not FRS capable */
+	if (!port->connected || port->port_type != TYPEC_PORT_DRP ||
+	    port->pwr_opmode != TYPEC_PWR_MODE_PD ||
+	    !port->tcpc->enable_frs ||
+	    /* Sink caps queried */
+	    port->sink_cap_done || port->negotiated_rev < PD_REV30)
+		goto unlock;
+
+	/* Send when the state machine is idle */
+	if (port->state != SNK_READY || port->vdm_state != VDM_STATE_DONE || port->send_discover)
+		goto resched;
+
+	tcpm_set_state(port, GET_SINK_CAP, 0);
+	port->sink_cap_done = true;
+
+resched:
+	mod_delayed_work(port->wq, &port->enable_frs, msecs_to_jiffies(GET_SINK_CAP_RETRY_MS));
+unlock:
+	mutex_unlock(&port->lock);
+}
+
 static int tcpm_dr_set(struct typec_port *p, enum typec_data_role data)
 {
 	struct tcpm_port *port = typec_get_drvdata(p);
@@ -4489,7 +4666,7 @@ static int tcpm_fw_get_caps(struct tcpm_port *port,
 {
 	const char *cap_str;
 	int ret;
-	u32 mw;
+	u32 mw, frs_current;
 
 	if (!fwnode)
 		return -EINVAL;
@@ -4558,6 +4735,13 @@ static int tcpm_fw_get_caps(struct tcpm_port *port,
 
 	port->self_powered = fwnode_property_read_bool(fwnode, "self-powered");
 
+	/* FRS can only be supported byb DRP ports */
+	if (port->port_type == TYPEC_PORT_DRP) {
+		ret = fwnode_property_read_u32(fwnode, "frs-typec-current", &frs_current);
+		if (ret >= 0 && frs_current <= FRS_5V_3A)
+			port->typec_caps.frs_current = frs_current;
+	}
+
 	return 0;
 }
 
@@ -4813,6 +4997,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
 	INIT_DELAYED_WORK(&port->state_machine, tcpm_state_machine_work);
 	INIT_DELAYED_WORK(&port->vdm_state_machine, vdm_state_machine_work);
 	INIT_WORK(&port->event_work, tcpm_pd_event_handler);
+	INIT_DELAYED_WORK(&port->enable_frs, tcpm_enable_frs);
 
 	spin_lock_init(&port->pd_event_lock);
 
diff --git a/include/linux/usb/pd.h b/include/linux/usb/pd.h
index b6c233e79bd4..5d8a29c683a4 100644
--- a/include/linux/usb/pd.h
+++ b/include/linux/usb/pd.h
@@ -219,14 +219,16 @@ enum pd_pdo_type {
 #define PDO_CURR_MASK		0x3ff
 #define PDO_PWR_MASK		0x3ff
 
-#define PDO_FIXED_DUAL_ROLE	BIT(29)	/* Power role swap supported */
-#define PDO_FIXED_SUSPEND	BIT(28) /* USB Suspend supported (Source) */
-#define PDO_FIXED_HIGHER_CAP	BIT(28) /* Requires more than vSafe5V (Sink) */
-#define PDO_FIXED_EXTPOWER	BIT(27) /* Externally powered */
-#define PDO_FIXED_USB_COMM	BIT(26) /* USB communications capable */
-#define PDO_FIXED_DATA_SWAP	BIT(25) /* Data role swap supported */
-#define PDO_FIXED_VOLT_SHIFT	10	/* 50mV units */
-#define PDO_FIXED_CURR_SHIFT	0	/* 10mA units */
+#define PDO_FIXED_DUAL_ROLE		BIT(29)	/* Power role swap supported */
+#define PDO_FIXED_SUSPEND		BIT(28) /* USB Suspend supported (Source) */
+#define PDO_FIXED_HIGHER_CAP		BIT(28) /* Requires more than vSafe5V (Sink) */
+#define PDO_FIXED_EXTPOWER		BIT(27) /* Externally powered */
+#define PDO_FIXED_USB_COMM		BIT(26) /* USB communications capable */
+#define PDO_FIXED_DATA_SWAP		BIT(25) /* Data role swap supported */
+#define PDO_FIXED_FRS_CURR_MASK		(BIT(24) | BIT(23)) /* FR_Swap Current (Sink) */
+#define PDO_FIXED_FRS_CURR_SHIFT	23
+#define PDO_FIXED_VOLT_SHIFT		10	/* 50mV units */
+#define PDO_FIXED_CURR_SHIFT		0	/* 10mA units */
 
 #define PDO_FIXED_VOLT(mv)	((((mv) / 50) & PDO_VOLT_MASK) << PDO_FIXED_VOLT_SHIFT)
 #define PDO_FIXED_CURR(ma)	((((ma) / 10) & PDO_CURR_MASK) << PDO_FIXED_CURR_SHIFT)
@@ -454,6 +456,7 @@ static inline unsigned int rdo_max_power(u32 rdo)
 #define PD_T_DB_DETECT		10000	/* 10 - 15 seconds */
 #define PD_T_SEND_SOURCE_CAP	150	/* 100 - 200 ms */
 #define PD_T_SENDER_RESPONSE	60	/* 24 - 30 ms, relaxed */
+#define PD_T_RECEIVER_RESPONSE	15	/* 15ms max */
 #define PD_T_SOURCE_ACTIVITY	45
 #define PD_T_SINK_ACTIVITY	135
 #define PD_T_SINK_WAIT_CAP	240
@@ -473,6 +476,7 @@ static inline unsigned int rdo_max_power(u32 rdo)
 #define PD_T_ERROR_RECOVERY	100	/* minimum 25 is insufficient */
 #define PD_T_SRCSWAPSTDBY      625     /* Maximum of 650ms */
 #define PD_T_NEWSRC            250     /* Maximum of 275ms */
+#define PD_T_SWAP_SRC_START	20	/* Minimum of 20ms */
 
 #define PD_T_DRP_TRY		100	/* 75 - 150 ms */
 #define PD_T_DRP_TRYWAIT	600	/* 400 - 800 ms */
diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h
index 89f58760cf48..09762d26fa0c 100644
--- a/include/linux/usb/tcpm.h
+++ b/include/linux/usb/tcpm.h
@@ -78,8 +78,11 @@ enum tcpm_transmit_type {
  *		automatically if a connection is established.
  * @try_role:	Optional; called to set a preferred role
  * @pd_transmit:Called to transmit PD message
- * @mux:	Pointer to multiplexer data
  * @set_bist_data: Turn on/off bist data mode for compliance testing
+ * @enable_frs:
+ *		Optional; Called to enable/disable PD 3.0 fast role swap.
+ *		Enabling frs is accessory dependent as not all PD3.0
+ *		accessories support fast role swap.
  */
 struct tcpc_dev {
 	struct fwnode_handle *fwnode;
@@ -105,6 +108,7 @@ struct tcpc_dev {
 	int (*pd_transmit)(struct tcpc_dev *dev, enum tcpm_transmit_type type,
 			   const struct pd_message *msg);
 	int (*set_bist_data)(struct tcpc_dev *dev, bool on);
+	int (*enable_frs)(struct tcpc_dev *dev, bool enable);
 };
 
 struct tcpm_port;
@@ -114,6 +118,8 @@ void tcpm_unregister_port(struct tcpm_port *port);
 
 void tcpm_vbus_change(struct tcpm_port *port);
 void tcpm_cc_change(struct tcpm_port *port);
+void tcpm_sink_frs(struct tcpm_port *port);
+void tcpm_sourcing_vbus(struct tcpm_port *port);
 void tcpm_pd_receive(struct tcpm_port *port,
 		     const struct pd_message *msg);
 void tcpm_pd_transmit_complete(struct tcpm_port *port,
diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
index 9cb1bec94b71..2ec7451a14ab 100644
--- a/include/linux/usb/typec.h
+++ b/include/linux/usb/typec.h
@@ -204,6 +204,18 @@ struct typec_operations {
 			     enum typec_port_type type);
 };
 
+/*
+ * Initial current capability of the new source when vSafe5V is applied during PD3.0 Fast Role Swap.
+ * Based on "Table 6-14 Fixed Supply PDO - Sink" of "USB Power Delivery Specification Revision 3.0,
+ * Version 1.2"
+ */
+enum frs_typec_current {
+	FRS_NOT_SUPPORTED,
+	FRS_DEFAULT_POWER,
+	FRS_5V_1P5A,
+	FRS_5V_3A,
+};
+
 /*
  * struct typec_capability - USB Type-C Port Capabilities
  * @type: Supported power role of the port
@@ -226,6 +238,7 @@ struct typec_capability {
 	int			prefer_role;
 	enum typec_accessory	accessory[TYPEC_MAX_ACCESSORY];
 	unsigned int		orientation_aware:1;
+	enum frs_typec_current	frs_current;
 
 	struct fwnode_handle	*fwnode;
 	void			*driver_data;
-- 
2.28.0.297.g1956fa8f8d-goog


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

* [PATCH 10/14 v1] usb: typec: tcpci: Implement callbacks for FRS
  2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
                   ` (8 preceding siblings ...)
  2020-08-25  4:22 ` [PATCH 09/14 v1] usb: typec: tcpm: Add support for Sink Fast Role SWAP(FRS) Badhri Jagan Sridharan
@ 2020-08-25  4:22 ` Badhri Jagan Sridharan
  2020-08-25  4:22 ` [PATCH 11/14 v1] usb: typec: tcpci_maxim: Add support for Sink FRS Badhri Jagan Sridharan
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:22 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

Implement tcpc.enable_frs to enable TCPC to receive
Fast role swap signal.

Additionally set the sink disconnect threshold to 4v
to prevent disconnect during Fast Role swap.

Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
---
 drivers/usb/typec/tcpm/tcpci.c | 17 +++++++++++++++++
 drivers/usb/typec/tcpm/tcpci.h |  8 ++++++++
 2 files changed, 25 insertions(+)

diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
index 89d28e3fbee8..13d2e1c2ff20 100644
--- a/drivers/usb/typec/tcpm/tcpci.c
+++ b/drivers/usb/typec/tcpm/tcpci.c
@@ -268,6 +268,22 @@ static int tcpci_set_vconn(struct tcpc_dev *tcpc, bool enable)
 				enable ? TCPC_POWER_CTRL_VCONN_ENABLE : 0);
 }
 
+static int tcpci_enable_frs(struct tcpc_dev *dev, bool enable)
+{
+	struct tcpci *tcpci = tcpc_to_tcpci(dev);
+	int ret;
+
+	/* To prevent disconnect during FRS, set disconnect threshold to 3.5V */
+	ret = tcpci_write16(tcpci, TCPC_VBUS_SINK_DISCONNECT_THRESH, enable ? 0 : 0x8c);
+	if (ret < 0)
+		return ret;
+
+	ret = regmap_update_bits(tcpci->regmap, TCPC_POWER_CTRL, TCPC_FAST_ROLE_SWAP_EN, enable ?
+				 TCPC_FAST_ROLE_SWAP_EN : 0);
+
+	return ret;
+}
+
 static int tcpci_set_bist_data(struct tcpc_dev *tcpc, bool enable)
 {
 	struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
@@ -610,6 +626,7 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data)
 	tcpci->tcpc.set_roles = tcpci_set_roles;
 	tcpci->tcpc.pd_transmit = tcpci_pd_transmit;
 	tcpci->tcpc.set_bist_data = tcpci_set_bist_data;
+	tcpci->tcpc.enable_frs = tcpci_enable_frs;
 
 	err = tcpci_parse_config(tcpci);
 	if (err < 0)
diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h
index 82f021a82456..5ef07a56d67a 100644
--- a/drivers/usb/typec/tcpm/tcpci.h
+++ b/drivers/usb/typec/tcpm/tcpci.h
@@ -16,6 +16,7 @@
 #define TCPC_PD_INT_REV			0xa
 
 #define TCPC_ALERT			0x10
+#define TCPC_ALERT_EXTND		BIT(14)
 #define TCPC_ALERT_EXTENDED_STATUS	BIT(13)
 #define TCPC_ALERT_VBUS_DISCNCT		BIT(11)
 #define TCPC_ALERT_RX_BUF_OVF		BIT(10)
@@ -37,6 +38,9 @@
 #define TCPC_EXTENDED_STATUS_MASK		0x16
 #define TCPC_EXTENDED_STATUS_MASK_VSAFE0V	BIT(0)
 
+#define TCPC_ALERT_EXTENDED_MASK	0x17
+#define TCPC_SINK_FAST_ROLE_SWAP	BIT(0)
+
 #define TCPC_CONFIG_STD_OUTPUT		0x18
 
 #define TCPC_TCPC_CTRL			0x19
@@ -63,6 +67,7 @@
 
 #define TCPC_POWER_CTRL			0x1c
 #define TCPC_POWER_CTRL_VCONN_ENABLE	BIT(0)
+#define TCPC_FAST_ROLE_SWAP_EN		BIT(7)
 
 #define TCPC_CC_STATUS			0x1d
 #define TCPC_CC_STATUS_TOGGLING		BIT(5)
@@ -74,11 +79,14 @@
 
 #define TCPC_POWER_STATUS		0x1e
 #define TCPC_POWER_STATUS_UNINIT	BIT(6)
+#define TCPC_POWER_STATUS_SOURCING_VBUS	BIT(4)
 #define TCPC_POWER_STATUS_VBUS_DET	BIT(3)
 #define TCPC_POWER_STATUS_VBUS_PRES	BIT(2)
 
 #define TCPC_FAULT_STATUS		0x1f
 
+#define TCPC_ALERT_EXTENDED		0x21
+
 #define TCPC_COMMAND			0x23
 #define TCPC_CMD_WAKE_I2C		0x11
 #define TCPC_CMD_DISABLE_VBUS_DETECT	0x22
-- 
2.28.0.297.g1956fa8f8d-goog


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

* [PATCH 11/14 v1] usb: typec: tcpci_maxim: Add support for Sink FRS
  2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
                   ` (9 preceding siblings ...)
  2020-08-25  4:22 ` [PATCH 10/14 v1] usb: typec: tcpci: Implement callbacks for FRS Badhri Jagan Sridharan
@ 2020-08-25  4:22 ` Badhri Jagan Sridharan
  2020-08-25  4:22 ` [PATCH 12/14] usb: typec: tcpm: Implement enabling Auto Discharge disconnect support Badhri Jagan Sridharan
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:22 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

Upon receiving ALERT_EXTENDED.TCPC_SINK_FAST_ROLE_SWAP signal
tcpm to start Sink fast role swap signal.

Inform when TCPM is sourcing vbus.

Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
---
 drivers/usb/typec/tcpm/tcpci_maxim.c | 50 +++++++++++++++++++++++++---
 1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.c b/drivers/usb/typec/tcpm/tcpci_maxim.c
index b61f290a8f96..6ba808ad901a 100644
--- a/drivers/usb/typec/tcpm/tcpci_maxim.c
+++ b/drivers/usb/typec/tcpm/tcpci_maxim.c
@@ -106,13 +106,22 @@ static void max_tcpci_init_regs(struct max_tcpci_chip *chip)
 		return;
 	}
 
+	ret = max_tcpci_write8(chip, TCPC_ALERT_EXTENDED, 0xff);
+	if (ret < 0) {
+		dev_err(chip->dev, "Unable to clear TCPC_ALERT_EXTENDED ret:%d\n", ret);
+		return;
+	}
+
 	alert_mask = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_DISCARDED | TCPC_ALERT_TX_FAILED |
 		TCPC_ALERT_RX_HARD_RST | TCPC_ALERT_RX_STATUS | TCPC_ALERT_CC_STATUS |
-		TCPC_ALERT_VBUS_DISCNCT | TCPC_ALERT_RX_BUF_OVF | TCPC_ALERT_POWER_STATUS;
+		TCPC_ALERT_VBUS_DISCNCT | TCPC_ALERT_RX_BUF_OVF | TCPC_ALERT_POWER_STATUS |
+		/* Enable Extended alert for detecting Fast Role Swap Signal */
+		TCPC_ALERT_EXTND;
 
 	ret = max_tcpci_write16(chip, TCPC_ALERT_MASK, alert_mask);
 	if (ret < 0) {
-		dev_err(chip->dev, "Error writing to TCPC_ALERT_MASK ret:%d\n", ret);
+		dev_err(chip->dev,
+			"Error enabling TCPC_ALERT: TCPC_ALERT_MASK write failed ret:%d\n", ret);
 		return;
 	}
 
@@ -122,6 +131,10 @@ static void max_tcpci_init_regs(struct max_tcpci_chip *chip)
 		dev_err(chip->dev, "Error writing to TCPC_POWER_CTRL ret:%d\n", ret);
 		return;
 	}
+
+	ret = max_tcpci_write8(chip, TCPC_ALERT_EXTENDED_MASK, TCPC_SINK_FAST_ROLE_SWAP);
+	if (ret < 0)
+		return;
 }
 
 static void process_rx(struct max_tcpci_chip *chip, u16 status)
@@ -225,10 +238,23 @@ static void process_power_status(struct max_tcpci_chip *chip)
 	if (ret < 0)
 		return;
 
-	if (pwr_status == 0xff)
+	if (pwr_status == 0xff) {
 		max_tcpci_init_regs(chip);
-	else
+	} else if (pwr_status & TCPC_POWER_STATUS_SOURCING_VBUS) {
+		tcpm_sourcing_vbus(chip->port);
+		/*
+		 * Alawys re-enable boost here.
+		 * In normal case, when say an headset is attached, TCPM would
+		 * have instructed to TCPC to enable boost, so the call is a
+		 * no-op.
+		 * But for Fast Role Swap case, Boost turns on autonomously without
+		 * AP intervention, but, needs AP to enable source mode explicitly
+		 * for AP to regain control.
+		 */
+		max_tcpci_set_vbus(chip->tcpci, &chip->data, true, false);
+	} else {
 		tcpm_vbus_change(chip->port);
+	}
 }
 
 static void process_tx(struct max_tcpci_chip *chip, u16 status)
@@ -249,6 +275,7 @@ static irqreturn_t _max_tcpci_irq(struct max_tcpci_chip *chip, u16 status)
 {
 	u16 mask;
 	int ret;
+	u8 reg_status;
 
 	/*
 	 * Clear alert status for everything except RX_STATUS, which shouldn't
@@ -274,6 +301,21 @@ static irqreturn_t _max_tcpci_irq(struct max_tcpci_chip *chip, u16 status)
 		}
 	}
 
+	if (status & TCPC_ALERT_EXTND) {
+		ret = max_tcpci_read8(chip, TCPC_ALERT_EXTENDED, &reg_status);
+		if (ret < 0)
+			return ret;
+
+		ret = max_tcpci_write8(chip, TCPC_ALERT_EXTENDED, reg_status);
+		if (ret < 0)
+			return ret;
+
+		if (reg_status & TCPC_SINK_FAST_ROLE_SWAP) {
+			dev_info(chip->dev, "FRS Signal");
+			tcpm_sink_frs(chip->port);
+		}
+	}
+
 	if (status & TCPC_ALERT_RX_STATUS)
 		process_rx(chip, status);
 
-- 
2.28.0.297.g1956fa8f8d-goog


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

* [PATCH 12/14] usb: typec: tcpm: Implement enabling Auto Discharge disconnect support
  2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
                   ` (10 preceding siblings ...)
  2020-08-25  4:22 ` [PATCH 11/14 v1] usb: typec: tcpci_maxim: Add support for Sink FRS Badhri Jagan Sridharan
@ 2020-08-25  4:22 ` Badhri Jagan Sridharan
  2020-08-28 14:13   ` Heikki Krogerus
  2020-08-25  4:22 ` [PATCH 13/14 v1] usb: typec: tcpci: Implement Auto discharge disconnect callbacks Badhri Jagan Sridharan
  2020-08-25  4:22 ` [PATCH 14/14 v1] usb: typec: tcpci_maxim: Implemnent set_auto_vbus_discharge_threshold Badhri Jagan Sridharan
  13 siblings, 1 reply; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:22 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

TCPCI spec allows TCPC hardware to autonomously discharge the vbus
capacitance upon disconnect. The expectation is that the TCPM enables
AutoDischargeDisconnect while entering SNK/SRC_ATTACHED states. Hardware
then automously discharges vbus when the vbus falls below a certain
threshold i.e. VBUS_SINK_DISCONNECT_THRESHOLD.

Apart from enabling the vbus discharge circuit, AutoDischargeDisconnect
is also used a flag to move TCPCI based TCPC implementations into
Attached.Snk/Attached.Src state as mentioned in
Figure 4-15. TCPC State Diagram before a Connection of the
USB Type-C Port Controller Interface Specification.
In such TCPC implementations, setting AutoDischargeDisconnect would
prevent TCPC into entering "Connection_Invalid" state as well.

Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
Change-Id: I09c407eb228d69eb1259008eeb14c429b0fda765
---
 drivers/usb/typec/tcpm/tcpm.c | 80 +++++++++++++++++++++++++++++++++--
 include/linux/usb/tcpm.h      | 16 +++++++
 2 files changed, 92 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index 6ea4613af905..fe58cf908144 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -1660,6 +1660,25 @@ static void tcpm_handle_alert(struct tcpm_port *port, const __le32 *payload,
 	}
 }
 
+static int tcpm_set_auto_vbus_discharge_threshold(struct tcpm_port *port, enum typec_role port_role,
+						  enum typec_pwr_opmode mode, bool pps_active,
+						  u32 requested_vbus_voltage)
+{
+	int ret;
+
+	if (!port->tcpc->set_auto_vbus_discharge_threshold)
+		return 0;
+
+	ret = port->tcpc->set_auto_vbus_discharge_threshold(port->tcpc, port_role, mode, pps_active,
+							    requested_vbus_voltage);
+	tcpm_log_force(port,
+		       "set_auto_vbus_discharge_threshold pwr_role:%s mode:%d pps_active:%c vbus:%u ret:%d",
+		       port_role == TYPEC_SINK ? "sink" : "source", mode, pps_active ? 'y' : 'n',
+		       requested_vbus_voltage, ret);
+
+	return ret;
+}
+
 static void tcpm_pd_data_request(struct tcpm_port *port,
 				 const struct pd_message *msg)
 {
@@ -1829,6 +1848,10 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
 						       port->current_limit,
 						       port->supply_voltage);
 				port->explicit_contract = true;
+				tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_SINK,
+								       TYPEC_PWR_MODE_PD,
+								       port->pps_data.active,
+								       port->supply_voltage);
 				tcpm_set_state(port, SNK_READY, 0);
 			} else {
 				/*
@@ -2743,8 +2766,14 @@ static int tcpm_src_attach(struct tcpm_port *port)
 	if (ret < 0)
 		return ret;
 
-	ret = tcpm_set_roles(port, true, TYPEC_SOURCE,
-			     tcpm_data_role_for_source(port));
+	if (port->tcpc->enable_auto_vbus_discharge) {
+		tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_SOURCE, TYPEC_PWR_MODE_USB,
+						       false, VSAFE5V);
+		ret = port->tcpc->enable_auto_vbus_discharge(port->tcpc, true);
+		tcpm_log_force(port, "enable vbus discharge ret:%d", ret);
+	}
+
+	ret = tcpm_set_roles(port, true, TYPEC_SOURCE, tcpm_data_role_for_sink(port));
 	if (ret < 0)
 		return ret;
 
@@ -2811,6 +2840,12 @@ static void tcpm_unregister_altmodes(struct tcpm_port *port)
 
 static void tcpm_reset_port(struct tcpm_port *port)
 {
+	int ret;
+
+	if (port->tcpc->enable_auto_vbus_discharge) {
+		ret = port->tcpc->enable_auto_vbus_discharge(port->tcpc, false);
+		tcpm_log_force(port, "Disable vbus discharge ret:%d", ret);
+	}
 	tcpm_unregister_altmodes(port);
 	tcpm_typec_disconnect(port);
 	port->attached = false;
@@ -2875,8 +2910,14 @@ static int tcpm_snk_attach(struct tcpm_port *port)
 	if (ret < 0)
 		return ret;
 
-	ret = tcpm_set_roles(port, true, TYPEC_SINK,
-			     tcpm_data_role_for_sink(port));
+	if (port->tcpc->enable_auto_vbus_discharge) {
+		tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_SINK, TYPEC_PWR_MODE_USB, false,
+						       VSAFE5V);
+		ret = port->tcpc->enable_auto_vbus_discharge(port->tcpc, true);
+		tcpm_log_force(port, "enable vbus discharge ret:%d", ret);
+	}
+
+	ret = tcpm_set_roles(port, true, TYPEC_SINK, tcpm_data_role_for_sink(port));
 	if (ret < 0)
 		return ret;
 
@@ -3430,6 +3471,14 @@ static void run_state_machine(struct tcpm_port *port)
 			tcpm_set_state(port, SNK_HARD_RESET_SINK_OFF, 0);
 		break;
 	case SRC_HARD_RESET_VBUS_OFF:
+		/*
+		 * 7.1.5 Response to Hard Resets
+		 * Hard Reset Signaling indicates a communication failure has occurred and the
+		 * Source Shall stop driving VCONN, Shall remove Rp from the VCONN pin and Shall
+		 * drive VBUS to vSafe0V as shown in Figure 7-9.
+		 */
+		tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_SOURCE, TYPEC_PWR_MODE_USB,
+						       false, 0);
 		tcpm_set_vconn(port, true);
 		tcpm_set_vbus(port, false);
 		tcpm_set_roles(port, port->self_powered, TYPEC_SOURCE,
@@ -3440,9 +3489,13 @@ static void run_state_machine(struct tcpm_port *port)
 		tcpm_set_vbus(port, true);
 		port->tcpc->set_pd_rx(port->tcpc, true);
 		tcpm_set_attached_state(port, true);
+		tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_SOURCE, TYPEC_PWR_MODE_USB,
+						       false, VSAFE5V);
 		tcpm_set_state(port, SRC_UNATTACHED, PD_T_PS_SOURCE_ON);
 		break;
 	case SNK_HARD_RESET_SINK_OFF:
+		tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_SINK, TYPEC_PWR_MODE_USB, false,
+						       0);
 		memset(&port->pps_data, 0, sizeof(port->pps_data));
 		tcpm_set_vconn(port, false);
 		if (port->pd_capable)
@@ -3485,6 +3538,8 @@ static void run_state_machine(struct tcpm_port *port)
 			tcpm_set_charge(port, true);
 		}
 		tcpm_set_attached_state(port, true);
+		tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_SINK, TYPEC_PWR_MODE_USB, false,
+						       VSAFE5V);
 		tcpm_set_state(port, SNK_STARTUP, 0);
 		break;
 
@@ -3586,6 +3641,12 @@ static void run_state_machine(struct tcpm_port *port)
 			tcpm_set_state(port, PR_SWAP_SNK_SRC_SINK_OFF, 0);
 		break;
 	case PR_SWAP_SRC_SNK_TRANSITION_OFF:
+		/*
+		 * Prevent vbus discharge circuit from turning on during PR_SWAP
+		 * as this is not a disconnect.
+		 */
+		tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_SOURCE, TYPEC_PWR_MODE_USB,
+						       port->pps_data.active, 0);
 		tcpm_set_vbus(port, false);
 		port->explicit_contract = false;
 		/* allow time for Vbus discharge, must be < tSrcSwapStdby */
@@ -3614,9 +3675,18 @@ static void run_state_machine(struct tcpm_port *port)
 		tcpm_set_state_cond(port, SNK_UNATTACHED, PD_T_PS_SOURCE_ON);
 		break;
 	case PR_SWAP_SRC_SNK_SINK_ON:
+		/* Set the vbus disconnect threshold for implicit contract */
+		tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_SINK, TYPEC_PWR_MODE_USB, false,
+						       VSAFE5V);
 		tcpm_set_state(port, SNK_STARTUP, 0);
 		break;
 	case PR_SWAP_SNK_SRC_SINK_OFF:
+		/*
+		 * Prevent vbus discharge circuit from turning on during PR_SWAP
+		 * as this is not a disconnect.
+		 */
+		tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_SINK, TYPEC_PWR_MODE_USB,
+						       port->pps_data.active, 0);
 		tcpm_set_charge(port, false);
 		tcpm_set_state(port, hard_reset_state(port),
 			       PD_T_PS_SOURCE_OFF);
@@ -3642,6 +3712,8 @@ static void run_state_machine(struct tcpm_port *port)
 		 */
 		tcpm_set_pwr_role(port, TYPEC_SOURCE);
 		tcpm_pd_send_control(port, PD_CTRL_PS_RDY);
+		tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_SOURCE, TYPEC_PWR_MODE_USB,
+						       false, VSAFE5V);
 		tcpm_set_state(port, SRC_STARTUP, 0);
 		break;
 
diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h
index 09762d26fa0c..a1707def51c3 100644
--- a/include/linux/usb/tcpm.h
+++ b/include/linux/usb/tcpm.h
@@ -83,6 +83,18 @@ enum tcpm_transmit_type {
  *		Optional; Called to enable/disable PD 3.0 fast role swap.
  *		Enabling frs is accessory dependent as not all PD3.0
  *		accessories support fast role swap.
+ * @enable_auto_vbus_discharge:
+ *		Optional; TCPCI spec based TCPC implementations can optionally
+ *		support hardware to autonomously dischrge vbus upon disconnecting
+ *		as sink or source. TCPM signals TCPC to enable the mechanism upon
+ *		entering connected state and signals disabling upon disconnect.
+ * @set_auto_vbus_discharge_threshold:
+ *		Mandatory when enable_auto_vbus_discharge is implemented. TCPM
+ *		calls this function to allow lower levels drivers to program the
+ *		vbus threshold voltage below which the vbus discharge circuit
+ *		will be turned on. requested_vbus_voltage is set to 0 when vbus
+ *		is going to disappear knowingly i.e. during PR_SWAP and
+ *		HARD_RESET etc.
  */
 struct tcpc_dev {
 	struct fwnode_handle *fwnode;
@@ -109,6 +121,10 @@ struct tcpc_dev {
 			   const struct pd_message *msg);
 	int (*set_bist_data)(struct tcpc_dev *dev, bool on);
 	int (*enable_frs)(struct tcpc_dev *dev, bool enable);
+	int (*enable_auto_vbus_discharge)(struct tcpc_dev *dev, bool enable);
+	int (*set_auto_vbus_discharge_threshold)(struct tcpc_dev *dev, enum typec_role port_role,
+						 enum typec_pwr_opmode mode, bool pps_active,
+						 u32 requested_vbus_voltage);
 };
 
 struct tcpm_port;
-- 
2.28.0.297.g1956fa8f8d-goog


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

* [PATCH 13/14 v1] usb: typec: tcpci: Implement Auto discharge disconnect callbacks
  2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
                   ` (11 preceding siblings ...)
  2020-08-25  4:22 ` [PATCH 12/14] usb: typec: tcpm: Implement enabling Auto Discharge disconnect support Badhri Jagan Sridharan
@ 2020-08-25  4:22 ` Badhri Jagan Sridharan
  2020-08-25  4:22 ` [PATCH 14/14 v1] usb: typec: tcpci_maxim: Implemnent set_auto_vbus_discharge_threshold Badhri Jagan Sridharan
  13 siblings, 0 replies; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:22 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

Implement callbacks for enabling/disabling
POWER_CONTROL.AutoDischargeDisconnect.

TCPCI spec allows TCPC hardware to autonomously discharge the vbus
capacitance upon disconnect. The expectation is that the TCPM enables
AutoDischargeDisconnect while entering SNK/SRC_ATTACHED states. Hardware
then automously discharges vbus when the vbus falls below a certain
threshold i.e. VBUS_SINK_DISCONNECT_THRESHOLD.

Apart from enabling the vbus discharge circuit, AutoDischargeDisconnect
is also used a flag to move TCPCI based TCPC implementations into
Attached.Snk/Attached.Src state as mentioned in
Figure 4-15. TCPC State Diagram before a Connection of the
USB Type-C Port Controller Interface Specification.
In such TCPC implementations, setting AutoDischargeDisconnect would
prevent TCPC into entering "Connection_Invalid" state as well.

Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
---
 drivers/usb/typec/tcpm/tcpci.c | 33 +++++++++++++++++++++++++++++++++
 drivers/usb/typec/tcpm/tcpci.h | 22 ++++++++++++++++++++--
 2 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
index 13d2e1c2ff20..e876f13ddf31 100644
--- a/drivers/usb/typec/tcpm/tcpci.c
+++ b/drivers/usb/typec/tcpm/tcpci.c
@@ -268,6 +268,33 @@ static int tcpci_set_vconn(struct tcpc_dev *tcpc, bool enable)
 				enable ? TCPC_POWER_CTRL_VCONN_ENABLE : 0);
 }
 
+static int tcpci_enable_auto_vbus_discharge(struct tcpc_dev *dev, bool enable)
+{
+	struct tcpci *tcpci = tcpc_to_tcpci(dev);
+	int ret;
+
+	ret = regmap_update_bits(tcpci->regmap, TCPC_POWER_CTRL, TCPC_POWER_CTRL_AUTO_DISCHARGE,
+				 enable ? TCPC_POWER_CTRL_AUTO_DISCHARGE : 0);
+	return ret;
+}
+
+static int tcpci_set_auto_vbus_discharge_threshold(struct tcpc_dev *dev, enum typec_role port_role,
+						   enum typec_pwr_opmode mode, bool pps_active,
+						   u32 requested_vbus_voltage)
+{
+	struct tcpci *tcpci = tcpc_to_tcpci(dev);
+	int (*set_auto_vbus_threshold)(struct tcpci *tcpci, struct tcpci_data *data,
+				       enum typec_role port_role, enum typec_pwr_opmode mode,
+				       bool pps_active, u32 requested_vbus_voltage);
+
+	set_auto_vbus_threshold = tcpci->data->set_auto_vbus_discharge_threshold;
+	if (set_auto_vbus_threshold)
+		return set_auto_vbus_threshold(tcpci, tcpci->data, port_role, mode, pps_active,
+					       requested_vbus_voltage);
+
+	return 0;
+}
+
 static int tcpci_enable_frs(struct tcpc_dev *dev, bool enable)
 {
 	struct tcpci *tcpci = tcpc_to_tcpci(dev);
@@ -628,6 +655,12 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data)
 	tcpci->tcpc.set_bist_data = tcpci_set_bist_data;
 	tcpci->tcpc.enable_frs = tcpci_enable_frs;
 
+	if (tcpci->data->auto_discharge_disconnect) {
+		tcpci->tcpc.enable_auto_vbus_discharge = tcpci_enable_auto_vbus_discharge;
+		tcpci->tcpc.set_auto_vbus_discharge_threshold =
+			tcpci_set_auto_vbus_discharge_threshold;
+	}
+
 	err = tcpci_parse_config(tcpci);
 	if (err < 0)
 		return ERR_PTR(err);
diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h
index 5ef07a56d67a..6a0aea34e544 100644
--- a/drivers/usb/typec/tcpm/tcpci.h
+++ b/drivers/usb/typec/tcpm/tcpci.h
@@ -8,6 +8,8 @@
 #ifndef __LINUX_USB_TCPCI_H
 #define __LINUX_USB_TCPCI_H
 
+#include <linux/usb/typec.h>
+
 #define TCPC_VENDOR_ID			0x0
 #define TCPC_PRODUCT_ID			0x2
 #define TCPC_BCD_DEV			0x4
@@ -67,6 +69,7 @@
 
 #define TCPC_POWER_CTRL			0x1c
 #define TCPC_POWER_CTRL_VCONN_ENABLE	BIT(0)
+#define TCPC_POWER_CTRL_AUTO_DISCHARGE	BIT(4)
 #define TCPC_FAST_ROLE_SWAP_EN		BIT(7)
 
 #define TCPC_CC_STATUS			0x1d
@@ -133,6 +136,8 @@
 
 #define TCPC_VBUS_VOLTAGE			0x70
 #define TCPC_VBUS_SINK_DISCONNECT_THRESH	0x72
+#define TCPC_VBUS_SINK_DISCONNECT_THRESH_LSB	25
+#define TCPC_VBUS_SINK_DISCONNECT_THRESH_MAX	1023
 #define TCPC_VBUS_STOP_DISCHARGE_THRESH		0x74
 #define TCPC_VBUS_VOLTAGE_ALARM_HI_CFG		0x76
 #define TCPC_VBUS_VOLTAGE_ALARM_LO_CFG		0x78
@@ -140,20 +145,33 @@
 /* I2C_WRITE_BYTE_COUNT + 1 when TX_BUF_BYTE_x is only accessible I2C_WRITE_BYTE_COUNT */
 #define TCPC_TRANSMIT_BUFFER_MAX_LEN		31
 
+struct tcpci;
+
 /*
- * @TX_BUF_BYTE_x_hidden
+ * @TX_BUF_BYTE_x_hidden:
  *		optional; Set when TX_BUF_BYTE_x can only be accessed through I2C_WRITE_BYTE_COUNT.
+ * @auto_discharge_disconnect:
+ *		Optional; Enables TCPC to autonously discharge vbus on disconnect.
+ * @set_auto_vbus_discharge_threshold:
+ *		Mandatory when @auto_discharge_disconnect is sets. Allows
+ *		programming the voltage threshold of vbus below which TCPC
+ *		enables the vbus discharge circuit.
  */
-struct tcpci;
 struct tcpci_data {
 	struct regmap *regmap;
 	unsigned char TX_BUF_BYTE_x_hidden:1;
+	unsigned char auto_discharge_disconnect:1;
+
 	int (*init)(struct tcpci *tcpci, struct tcpci_data *data);
 	int (*set_vconn)(struct tcpci *tcpci, struct tcpci_data *data,
 			 bool enable);
 	int (*start_drp_toggling)(struct tcpci *tcpci, struct tcpci_data *data,
 				  enum typec_cc_status cc);
 	int (*set_vbus)(struct tcpci *tcpci, struct tcpci_data *data, bool source, bool sink);
+	int (*set_auto_vbus_discharge_threshold)(struct tcpci *tcpci, struct tcpci_data *data,
+						 enum typec_role port_role,
+						 enum typec_pwr_opmode mode, bool pps_active,
+						 u32 requested_vbus_voltage);
 };
 
 struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data);
-- 
2.28.0.297.g1956fa8f8d-goog


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

* [PATCH 14/14 v1] usb: typec: tcpci_maxim: Implemnent set_auto_vbus_discharge_threshold
  2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
                   ` (12 preceding siblings ...)
  2020-08-25  4:22 ` [PATCH 13/14 v1] usb: typec: tcpci: Implement Auto discharge disconnect callbacks Badhri Jagan Sridharan
@ 2020-08-25  4:22 ` Badhri Jagan Sridharan
  13 siblings, 0 replies; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-25  4:22 UTC (permalink / raw)
  To: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, Badhri Jagan Sridharan

Programs VBUS_SINK_DISCONNECT_THRESHOLD based on the power_role,
voltage requested as sink, mode of operation.

The programmed threshold is based on vSinkDisconnect and
vSinkDisconnectPD values.

Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
---
 drivers/usb/typec/tcpm/tcpci_maxim.c | 48 ++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.c b/drivers/usb/typec/tcpm/tcpci_maxim.c
index 6ba808ad901a..e35bd995c037 100644
--- a/drivers/usb/typec/tcpm/tcpci_maxim.c
+++ b/drivers/usb/typec/tcpm/tcpci_maxim.c
@@ -137,6 +137,52 @@ static void max_tcpci_init_regs(struct max_tcpci_chip *chip)
 		return;
 }
 
+static int max_tcpci_set_auto_vbus_discharge_threshold(struct tcpci *tcpci, struct tcpci_data *data,
+						       enum typec_role port_role,
+						       enum typec_pwr_opmode mode, bool pps_active,
+						       u32 requested_vbus_voltage_mv)
+{
+	struct max_tcpci_chip *chip = tdata_to_max_tcpci(data);
+	u32 threshold = 0;
+	u8 pwr_ctrl;
+
+	/*
+	 * Indicates that vbus is going to go away due PR_SWAP, hard reset etc.
+	 * Do not discharge vbus here.
+	 */
+	if (requested_vbus_voltage_mv == 0)
+		goto write_thresh;
+
+	if (port_role == TYPEC_SINK) {
+		max_tcpci_read8(chip, TCPC_POWER_CTRL, &pwr_ctrl);
+		if (pwr_ctrl & TCPC_FAST_ROLE_SWAP_EN) {
+			/* To prevent disconnect when the source is fast role swap is capable. */
+			threshold = 3500;
+		} else if (mode == TYPEC_PWR_MODE_PD) {
+			if (pps_active)
+				threshold = (95 * requested_vbus_voltage_mv / 100) - 850;
+			else
+				threshold = (95 * requested_vbus_voltage_mv / 100) - 1250;
+		} else {
+			/* 3.5V for non-pd sink */
+			threshold = 3500;
+		}
+	} else {
+		/* 4V for source */
+		threshold = 4000;
+	}
+
+	threshold = threshold / TCPC_VBUS_SINK_DISCONNECT_THRESH_LSB;
+
+	if (threshold > TCPC_VBUS_SINK_DISCONNECT_THRESH_MAX) {
+		dev_err(chip->dev, "VBUS_SINK_DISCONNECT_THRESH out of range");
+		return -EINVAL;
+	}
+
+write_thresh:
+	return max_tcpci_write16(chip, TCPC_VBUS_SINK_DISCONNECT_THRESH, threshold);
+}
+
 static void process_rx(struct max_tcpci_chip *chip, u16 status)
 {
 	struct pd_message msg;
@@ -454,6 +500,8 @@ static int max_tcpci_probe(struct i2c_client *client, const struct i2c_device_id
 	chip->data.start_drp_toggling = max_tcpci_start_toggling;
 	chip->data.TX_BUF_BYTE_x_hidden = true;
 	chip->data.init = tcpci_init;
+	chip->data.set_auto_vbus_discharge_threshold = max_tcpci_set_auto_vbus_discharge_threshold;
+	chip->data.auto_discharge_disconnect = true;
 
 	max_tcpci_init_regs(chip);
 	chip->tcpci = tcpci_register_port(chip->dev, &chip->data);
-- 
2.28.0.297.g1956fa8f8d-goog


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

* Re: [PATCH 07/14 v1] usb: typec: tcpci_maxim: Chip level TCPC driver
  2020-08-25  4:22 ` [PATCH 07/14 v1] usb: typec: tcpci_maxim: Chip level TCPC driver Badhri Jagan Sridharan
@ 2020-08-25  5:16   ` Randy Dunlap
  2020-08-28 14:51     ` Badhri Jagan Sridharan
  0 siblings, 1 reply; 23+ messages in thread
From: Randy Dunlap @ 2020-08-25  5:16 UTC (permalink / raw)
  To: Badhri Jagan Sridharan, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel

On 8/24/20 9:22 PM, Badhri Jagan Sridharan wrote:
> diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
> index fa3f39336246..7c9722b02afe 100644
> --- a/drivers/usb/typec/tcpm/Kconfig
> +++ b/drivers/usb/typec/tcpm/Kconfig
> @@ -27,6 +27,12 @@ config TYPEC_RT1711H
>  	  Type-C Port Controller Manager to provide USB PD and USB
>  	  Type-C functionalities.
>  
> +config TYPEC_TCPCI_MAXIM
> +	tristate "Maxim TCPCI based Type-C chip driver"
> +	select USB_PSY

is that        USB_PHY
?

> +	help
> +	  MAXIM TCPCI based Type-C chip driver

end that with '.' please.

> +
>  endif # TYPEC_TCPCI
>  
>  config TYPEC_FUSB302


-- 
~Randy


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

* Re: [PATCH 09/14 v1] usb: typec: tcpm: Add support for Sink Fast Role SWAP(FRS)
  2020-08-25  4:22 ` [PATCH 09/14 v1] usb: typec: tcpm: Add support for Sink Fast Role SWAP(FRS) Badhri Jagan Sridharan
@ 2020-08-26 12:42   ` kernel test robot
  0 siblings, 0 replies; 23+ messages in thread
From: kernel test robot @ 2020-08-26 12:42 UTC (permalink / raw)
  To: Badhri Jagan Sridharan, Guenter Roeck, Heikki Krogerus,
	Greg Kroah-Hartman
  Cc: kbuild-all, linux-usb, linux-kernel, Badhri Jagan Sridharan

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

Hi Badhri,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on usb/usb-testing]
[also build test WARNING on robh/for-next v5.9-rc2 next-20200826]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Badhri-Jagan-Sridharan/TCPM-support-for-FRS-and-AutoDischarge-Disconnect/20200825-122527
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
config: arm-randconfig-r005-20200826 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/usb/typec/tcpm/tcpm.c: In function 'run_state_machine':
>> drivers/usb/typec/tcpm/tcpm.c:3684:3: warning: this statement may fall through [-Wimplicit-fallthrough=]
    3684 |   tcpm_swap_complete(port, port->swap_status);
         |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/usb/typec/tcpm/tcpm.c:3685:2: note: here
    3685 |  case FR_SWAP_CANCEL:
         |  ^~~~
   At top level:
   drivers/usb/typec/tcpm/tcpm.c:1618:39: warning: 'tcpm_altmode_ops' defined but not used [-Wunused-const-variable=]
    1618 | static const struct typec_altmode_ops tcpm_altmode_ops = {
         |                                       ^~~~~~~~~~~~~~~~

# https://github.com/0day-ci/linux/commit/a8727cbd1e6baa15662e368128ac96b196fe540f
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Badhri-Jagan-Sridharan/TCPM-support-for-FRS-and-AutoDischarge-Disconnect/20200825-122527
git checkout a8727cbd1e6baa15662e368128ac96b196fe540f
vim +3684 drivers/usb/typec/tcpm/tcpm.c

fce042f02ef03c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-15  2982  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  2983  static void run_state_machine(struct tcpm_port *port)
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  2984  {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  2985  	int ret;
fce042f02ef03c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-15  2986  	enum typec_pwr_opmode opmode;
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  2987  	unsigned int msecs;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  2988  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  2989  	port->enter_state = port->state;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  2990  	switch (port->state) {
7893f9e1c26d1f drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-04-16  2991  	case TOGGLING:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  2992  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  2993  	/* SRC states */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  2994  	case SRC_UNATTACHED:
b17dd57118fee7 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-08-10  2995  		if (!port->non_pd_role_swap)
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  2996  			tcpm_swap_complete(port, -ENOTCONN);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  2997  		tcpm_src_detach(port);
7893f9e1c26d1f drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-04-16  2998  		if (tcpm_start_toggling(port, tcpm_rp_cc(port))) {
7893f9e1c26d1f drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-04-16  2999  			tcpm_set_state(port, TOGGLING, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3000  			break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3001  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3002  		tcpm_set_cc(port, tcpm_rp_cc(port));
9b0ae69909c281 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3003  		if (port->port_type == TYPEC_PORT_DRP)
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3004  			tcpm_set_state(port, SNK_UNATTACHED, PD_T_DRP_SNK);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3005  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3006  	case SRC_ATTACH_WAIT:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3007  		if (tcpm_port_is_debug(port))
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3008  			tcpm_set_state(port, DEBUG_ACC_ATTACHED,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3009  				       PD_T_CC_DEBOUNCE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3010  		else if (tcpm_port_is_audio(port))
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3011  			tcpm_set_state(port, AUDIO_ACC_ATTACHED,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3012  				       PD_T_CC_DEBOUNCE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3013  		else if (tcpm_port_is_source(port))
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3014  			tcpm_set_state(port,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3015  				       tcpm_try_snk(port) ? SNK_TRY
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3016  							  : SRC_ATTACHED,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3017  				       PD_T_CC_DEBOUNCE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3018  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3019  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3020  	case SNK_TRY:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3021  		port->try_snk_count++;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3022  		/*
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3023  		 * Requirements:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3024  		 * - Do not drive vconn or vbus
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3025  		 * - Terminate CC pins (both) to Rd
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3026  		 * Action:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3027  		 * - Wait for tDRPTry (PD_T_DRP_TRY).
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3028  		 *   Until then, ignore any state changes.
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3029  		 */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3030  		tcpm_set_cc(port, TYPEC_CC_RD);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3031  		tcpm_set_state(port, SNK_TRY_WAIT, PD_T_DRP_TRY);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3032  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3033  	case SNK_TRY_WAIT:
a0a3e04e6b2c7c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3034  		if (tcpm_port_is_sink(port)) {
a0a3e04e6b2c7c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3035  			tcpm_set_state(port, SNK_TRY_WAIT_DEBOUNCE, 0);
a0a3e04e6b2c7c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3036  		} else {
a0a3e04e6b2c7c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3037  			tcpm_set_state(port, SRC_TRYWAIT, 0);
a0a3e04e6b2c7c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3038  			port->max_wait = 0;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3039  		}
a0a3e04e6b2c7c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3040  		break;
a0a3e04e6b2c7c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3041  	case SNK_TRY_WAIT_DEBOUNCE:
a0a3e04e6b2c7c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3042  		tcpm_set_state(port, SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3043  			       PD_T_PD_DEBOUNCE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3044  		break;
a0a3e04e6b2c7c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3045  	case SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS:
a0a3e04e6b2c7c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3046  		if (port->vbus_present && tcpm_port_is_sink(port)) {
a0a3e04e6b2c7c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3047  			tcpm_set_state(port, SNK_ATTACHED, 0);
a0a3e04e6b2c7c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3048  		} else {
a0a3e04e6b2c7c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3049  			tcpm_set_state(port, SRC_TRYWAIT, 0);
a0a3e04e6b2c7c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3050  			port->max_wait = 0;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3051  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3052  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3053  	case SRC_TRYWAIT:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3054  		tcpm_set_cc(port, tcpm_rp_cc(port));
02d5be466b68f6 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3055  		if (port->max_wait == 0) {
02d5be466b68f6 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3056  			port->max_wait = jiffies +
02d5be466b68f6 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3057  					 msecs_to_jiffies(PD_T_DRP_TRY);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3058  			tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3059  				       PD_T_DRP_TRY);
02d5be466b68f6 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3060  		} else {
02d5be466b68f6 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3061  			if (time_is_after_jiffies(port->max_wait))
02d5be466b68f6 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3062  				tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED,
02d5be466b68f6 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3063  					       jiffies_to_msecs(port->max_wait -
02d5be466b68f6 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3064  								jiffies));
02d5be466b68f6 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3065  			else
02d5be466b68f6 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3066  				tcpm_set_state(port, SNK_UNATTACHED, 0);
02d5be466b68f6 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3067  		}
02d5be466b68f6 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3068  		break;
02d5be466b68f6 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3069  	case SRC_TRYWAIT_DEBOUNCE:
02d5be466b68f6 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3070  		tcpm_set_state(port, SRC_ATTACHED, PD_T_CC_DEBOUNCE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3071  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3072  	case SRC_TRYWAIT_UNATTACHED:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3073  		tcpm_set_state(port, SNK_UNATTACHED, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3074  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3075  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3076  	case SRC_ATTACHED:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3077  		ret = tcpm_src_attach(port);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3078  		tcpm_set_state(port, SRC_UNATTACHED,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3079  			       ret < 0 ? 0 : PD_T_PS_SOURCE_ON);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3080  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3081  	case SRC_STARTUP:
fce042f02ef03c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-15  3082  		opmode =  tcpm_get_pwr_opmode(tcpm_rp_cc(port));
fce042f02ef03c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-15  3083  		typec_set_pwr_opmode(port->typec_port, opmode);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3084  		port->pwr_opmode = TYPEC_PWR_MODE_USB;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3085  		port->caps_count = 0;
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3086  		port->negotiated_rev = PD_MAX_REV;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3087  		port->message_id = 0;
5fec4b54d0bf6c drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3088  		port->rx_msgid = -1;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3089  		port->explicit_contract = false;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3090  		tcpm_set_state(port, SRC_SEND_CAPABILITIES, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3091  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3092  	case SRC_SEND_CAPABILITIES:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3093  		port->caps_count++;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3094  		if (port->caps_count > PD_N_CAPS_COUNT) {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3095  			tcpm_set_state(port, SRC_READY, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3096  			break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3097  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3098  		ret = tcpm_pd_send_source_caps(port);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3099  		if (ret < 0) {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3100  			tcpm_set_state(port, SRC_SEND_CAPABILITIES,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3101  				       PD_T_SEND_SOURCE_CAP);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3102  		} else {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3103  			/*
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3104  			 * Per standard, we should clear the reset counter here.
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3105  			 * However, that can result in state machine hang-ups.
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3106  			 * Reset it only in READY state to improve stability.
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3107  			 */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3108  			/* port->hard_reset_count = 0; */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3109  			port->caps_count = 0;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3110  			port->pd_capable = true;
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3111  			tcpm_set_state_cond(port, SRC_SEND_CAPABILITIES_TIMEOUT,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3112  					    PD_T_SEND_SOURCE_CAP);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3113  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3114  		break;
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3115  	case SRC_SEND_CAPABILITIES_TIMEOUT:
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3116  		/*
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3117  		 * Error recovery for a PD_DATA_SOURCE_CAP reply timeout.
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3118  		 *
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3119  		 * PD 2.0 sinks are supposed to accept src-capabilities with a
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3120  		 * 3.0 header and simply ignore any src PDOs which the sink does
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3121  		 * not understand such as PPS but some 2.0 sinks instead ignore
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3122  		 * the entire PD_DATA_SOURCE_CAP message, causing contract
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3123  		 * negotiation to fail.
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3124  		 *
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3125  		 * After PD_N_HARD_RESET_COUNT hard-reset attempts, we try
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3126  		 * sending src-capabilities with a lower PD revision to
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3127  		 * make these broken sinks work.
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3128  		 */
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3129  		if (port->hard_reset_count < PD_N_HARD_RESET_COUNT) {
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3130  			tcpm_set_state(port, HARD_RESET_SEND, 0);
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3131  		} else if (port->negotiated_rev > PD_REV20) {
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3132  			port->negotiated_rev--;
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3133  			port->hard_reset_count = 0;
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3134  			tcpm_set_state(port, SRC_SEND_CAPABILITIES, 0);
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3135  		} else {
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3136  			tcpm_set_state(port, hard_reset_state(port), 0);
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3137  		}
976daf9d119993 drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-03-16  3138  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3139  	case SRC_NEGOTIATE_CAPABILITIES:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3140  		ret = tcpm_pd_check_request(port);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3141  		if (ret < 0) {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3142  			tcpm_pd_send_control(port, PD_CTRL_REJECT);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3143  			if (!port->explicit_contract) {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3144  				tcpm_set_state(port,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3145  					       SRC_WAIT_NEW_CAPABILITIES, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3146  			} else {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3147  				tcpm_set_state(port, SRC_READY, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3148  			}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3149  		} else {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3150  			tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3151  			tcpm_set_state(port, SRC_TRANSITION_SUPPLY,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3152  				       PD_T_SRC_TRANSITION);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3153  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3154  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3155  	case SRC_TRANSITION_SUPPLY:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3156  		/* XXX: regulator_set_voltage(vbus, ...) */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3157  		tcpm_pd_send_control(port, PD_CTRL_PS_RDY);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3158  		port->explicit_contract = true;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3159  		typec_set_pwr_opmode(port->typec_port, TYPEC_PWR_MODE_PD);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3160  		port->pwr_opmode = TYPEC_PWR_MODE_PD;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3161  		tcpm_set_state_cond(port, SRC_READY, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3162  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3163  	case SRC_READY:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3164  #if 1
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3165  		port->hard_reset_count = 0;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3166  #endif
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3167  		port->try_src_count = 0;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3168  
3113bf1a5da35f drivers/staging/typec/tcpm.c  Guenter Roeck          2017-08-10  3169  		tcpm_swap_complete(port, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3170  		tcpm_typec_connect(port);
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3171  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3172  		tcpm_check_send_discover(port);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3173  		/*
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3174  		 * 6.3.5
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3175  		 * Sending ping messages is not necessary if
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3176  		 * - the source operates at vSafe5V
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3177  		 * or
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3178  		 * - The system is not operating in PD mode
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3179  		 * or
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3180  		 * - Both partners are connected using a Type-C connector
f451ac9e4c6dd2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3181  		 *
f451ac9e4c6dd2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3182  		 * There is no actual need to send PD messages since the local
f451ac9e4c6dd2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3183  		 * port type-c and the spec does not clearly say whether PD is
f451ac9e4c6dd2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3184  		 * possible when type-c is connected to Type-A/B
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3185  		 */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3186  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3187  	case SRC_WAIT_NEW_CAPABILITIES:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3188  		/* Nothing to do... */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3189  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3190  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3191  	/* SNK states */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3192  	case SNK_UNATTACHED:
b17dd57118fee7 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-08-10  3193  		if (!port->non_pd_role_swap)
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3194  			tcpm_swap_complete(port, -ENOTCONN);
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3195  		tcpm_pps_complete(port, -ENOTCONN);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3196  		tcpm_snk_detach(port);
7893f9e1c26d1f drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-04-16  3197  		if (tcpm_start_toggling(port, TYPEC_CC_RD)) {
7893f9e1c26d1f drivers/usb/typec/tcpm/tcpm.c Hans de Goede          2019-04-16  3198  			tcpm_set_state(port, TOGGLING, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3199  			break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3200  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3201  		tcpm_set_cc(port, TYPEC_CC_RD);
9b0ae69909c281 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3202  		if (port->port_type == TYPEC_PORT_DRP)
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3203  			tcpm_set_state(port, SRC_UNATTACHED, PD_T_DRP_SRC);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3204  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3205  	case SNK_ATTACH_WAIT:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3206  		if ((port->cc1 == TYPEC_CC_OPEN &&
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3207  		     port->cc2 != TYPEC_CC_OPEN) ||
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3208  		    (port->cc1 != TYPEC_CC_OPEN &&
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3209  		     port->cc2 == TYPEC_CC_OPEN))
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3210  			tcpm_set_state(port, SNK_DEBOUNCED,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3211  				       PD_T_CC_DEBOUNCE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3212  		else if (tcpm_port_is_disconnected(port))
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3213  			tcpm_set_state(port, SNK_UNATTACHED,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3214  				       PD_T_PD_DEBOUNCE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3215  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3216  	case SNK_DEBOUNCED:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3217  		if (tcpm_port_is_disconnected(port))
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3218  			tcpm_set_state(port, SNK_UNATTACHED,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3219  				       PD_T_PD_DEBOUNCE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3220  		else if (port->vbus_present)
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3221  			tcpm_set_state(port,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3222  				       tcpm_try_src(port) ? SRC_TRY
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3223  							  : SNK_ATTACHED,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3224  				       0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3225  		else
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3226  			/* Wait for VBUS, but not forever */
56277035c294ec drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3227  			tcpm_set_state(port, PORT_RESET, PD_T_PS_SOURCE_ON);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3228  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3229  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3230  	case SRC_TRY:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3231  		port->try_src_count++;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3232  		tcpm_set_cc(port, tcpm_rp_cc(port));
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3233  		port->max_wait = 0;
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3234  		tcpm_set_state(port, SRC_TRY_WAIT, 0);
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3235  		break;
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3236  	case SRC_TRY_WAIT:
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3237  		if (port->max_wait == 0) {
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3238  			port->max_wait = jiffies +
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3239  					 msecs_to_jiffies(PD_T_DRP_TRY);
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3240  			msecs = PD_T_DRP_TRY;
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3241  		} else {
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3242  			if (time_is_after_jiffies(port->max_wait))
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3243  				msecs = jiffies_to_msecs(port->max_wait -
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3244  							 jiffies);
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3245  			else
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3246  				msecs = 0;
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3247  		}
131c7d12ef21e1 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3248  		tcpm_set_state(port, SNK_TRYWAIT, msecs);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3249  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3250  	case SRC_TRY_DEBOUNCE:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3251  		tcpm_set_state(port, SRC_ATTACHED, PD_T_PD_DEBOUNCE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3252  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3253  	case SNK_TRYWAIT:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3254  		tcpm_set_cc(port, TYPEC_CC_RD);
af450ebb500ad2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3255  		tcpm_set_state(port, SNK_TRYWAIT_VBUS, PD_T_CC_DEBOUNCE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3256  		break;
af450ebb500ad2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3257  	case SNK_TRYWAIT_VBUS:
af450ebb500ad2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3258  		/*
af450ebb500ad2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3259  		 * TCPM stays in this state indefinitely until VBUS
af450ebb500ad2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3260  		 * is detected as long as Rp is not detected for
af450ebb500ad2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3261  		 * more than a time period of tPDDebounce.
af450ebb500ad2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3262  		 */
af450ebb500ad2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3263  		if (port->vbus_present && tcpm_port_is_sink(port)) {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3264  			tcpm_set_state(port, SNK_ATTACHED, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3265  			break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3266  		}
af450ebb500ad2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3267  		if (!tcpm_port_is_sink(port))
af450ebb500ad2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3268  			tcpm_set_state(port, SNK_TRYWAIT_DEBOUNCE, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3269  		break;
af450ebb500ad2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3270  	case SNK_TRYWAIT_DEBOUNCE:
af450ebb500ad2 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3271  		tcpm_set_state(port, SNK_UNATTACHED, PD_T_PD_DEBOUNCE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3272  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3273  	case SNK_ATTACHED:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3274  		ret = tcpm_snk_attach(port);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3275  		if (ret < 0)
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3276  			tcpm_set_state(port, SNK_UNATTACHED, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3277  		else
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3278  			tcpm_set_state(port, SNK_STARTUP, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3279  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3280  	case SNK_STARTUP:
fce042f02ef03c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-15  3281  		opmode =  tcpm_get_pwr_opmode(port->polarity ?
fce042f02ef03c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-15  3282  					      port->cc2 : port->cc1);
fce042f02ef03c drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-15  3283  		typec_set_pwr_opmode(port->typec_port, opmode);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3284  		port->pwr_opmode = TYPEC_PWR_MODE_USB;
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3285  		port->negotiated_rev = PD_MAX_REV;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3286  		port->message_id = 0;
5fec4b54d0bf6c drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3287  		port->rx_msgid = -1;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3288  		port->explicit_contract = false;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3289  		tcpm_set_state(port, SNK_DISCOVERY, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3290  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3291  	case SNK_DISCOVERY:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3292  		if (port->vbus_present) {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3293  			tcpm_set_current_limit(port,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3294  					       tcpm_get_current_limit(port),
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3295  					       5000);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3296  			tcpm_set_charge(port, true);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3297  			tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3298  			break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3299  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3300  		/*
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3301  		 * For DRP, timeouts differ. Also, handling is supposed to be
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3302  		 * different and much more complex (dead battery detection;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3303  		 * see USB power delivery specification, section 8.3.3.6.1.5.1).
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3304  		 */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3305  		tcpm_set_state(port, hard_reset_state(port),
9b0ae69909c281 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3306  			       port->port_type == TYPEC_PORT_DRP ?
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3307  					PD_T_DB_DETECT : PD_T_NO_RESPONSE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3308  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3309  	case SNK_DISCOVERY_DEBOUNCE:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3310  		tcpm_set_state(port, SNK_DISCOVERY_DEBOUNCE_DONE,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3311  			       PD_T_CC_DEBOUNCE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3312  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3313  	case SNK_DISCOVERY_DEBOUNCE_DONE:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3314  		if (!tcpm_port_is_disconnected(port) &&
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3315  		    tcpm_port_is_sink(port) &&
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3316  		    time_is_after_jiffies(port->delayed_runtime)) {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3317  			tcpm_set_state(port, SNK_DISCOVERY,
9578bcd0bb487b drivers/usb/typec/tcpm.c      Dan Carpenter          2018-06-07  3318  				       jiffies_to_msecs(port->delayed_runtime -
9578bcd0bb487b drivers/usb/typec/tcpm.c      Dan Carpenter          2018-06-07  3319  							jiffies));
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3320  			break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3321  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3322  		tcpm_set_state(port, unattached_state(port), 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3323  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3324  	case SNK_WAIT_CAPABILITIES:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3325  		ret = port->tcpc->set_pd_rx(port->tcpc, true);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3326  		if (ret < 0) {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3327  			tcpm_set_state(port, SNK_READY, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3328  			break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3329  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3330  		/*
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3331  		 * If VBUS has never been low, and we time out waiting
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3332  		 * for source cap, try a soft reset first, in case we
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3333  		 * were already in a stable contract before this boot.
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3334  		 * Do this only once.
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3335  		 */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3336  		if (port->vbus_never_low) {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3337  			port->vbus_never_low = false;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3338  			tcpm_set_state(port, SOFT_RESET_SEND,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3339  				       PD_T_SINK_WAIT_CAP);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3340  		} else {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3341  			tcpm_set_state(port, hard_reset_state(port),
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3342  				       PD_T_SINK_WAIT_CAP);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3343  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3344  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3345  	case SNK_NEGOTIATE_CAPABILITIES:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3346  		port->pd_capable = true;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3347  		port->hard_reset_count = 0;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3348  		ret = tcpm_pd_send_request(port);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3349  		if (ret < 0) {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3350  			/* Let the Source send capabilities again. */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3351  			tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3352  		} else {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3353  			tcpm_set_state_cond(port, hard_reset_state(port),
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3354  					    PD_T_SENDER_RESPONSE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3355  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3356  		break;
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3357  	case SNK_NEGOTIATE_PPS_CAPABILITIES:
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3358  		ret = tcpm_pd_send_pps_request(port);
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3359  		if (ret < 0) {
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3360  			port->pps_status = ret;
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3361  			/*
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3362  			 * If this was called due to updates to sink
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3363  			 * capabilities, and pps is no longer valid, we should
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3364  			 * safely fall back to a standard PDO.
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3365  			 */
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3366  			if (port->update_sink_caps)
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3367  				tcpm_set_state(port, SNK_NEGOTIATE_CAPABILITIES, 0);
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3368  			else
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3369  				tcpm_set_state(port, SNK_READY, 0);
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3370  		} else {
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3371  			tcpm_set_state_cond(port, hard_reset_state(port),
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3372  					    PD_T_SENDER_RESPONSE);
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3373  		}
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3374  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3375  	case SNK_TRANSITION_SINK:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3376  	case SNK_TRANSITION_SINK_VBUS:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3377  		tcpm_set_state(port, hard_reset_state(port),
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3378  			       PD_T_PS_TRANSITION);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3379  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3380  	case SNK_READY:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3381  		port->try_snk_count = 0;
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3382  		port->update_sink_caps = false;
8bf05746cffa34 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-17  3383  		if (port->explicit_contract) {
8bf05746cffa34 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-17  3384  			typec_set_pwr_opmode(port->typec_port,
8bf05746cffa34 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-17  3385  					     TYPEC_PWR_MODE_PD);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3386  			port->pwr_opmode = TYPEC_PWR_MODE_PD;
8bf05746cffa34 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-17  3387  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3388  
3113bf1a5da35f drivers/staging/typec/tcpm.c  Guenter Roeck          2017-08-10  3389  		tcpm_swap_complete(port, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3390  		tcpm_typec_connect(port);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3391  		tcpm_check_send_discover(port);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3392  		mod_delayed_work(port->wq, &port->enable_frs, msecs_to_jiffies(0));
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3393  		tcpm_pps_complete(port, port->pps_status);
f2a8aa053c1761 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3394  		power_supply_changed(port->psy);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3395  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3396  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3397  	/* Accessory states */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3398  	case ACC_UNATTACHED:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3399  		tcpm_acc_detach(port);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3400  		tcpm_set_state(port, SRC_UNATTACHED, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3401  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3402  	case DEBUG_ACC_ATTACHED:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3403  	case AUDIO_ACC_ATTACHED:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3404  		ret = tcpm_acc_attach(port);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3405  		if (ret < 0)
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3406  			tcpm_set_state(port, ACC_UNATTACHED, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3407  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3408  	case AUDIO_ACC_DEBOUNCE:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3409  		tcpm_set_state(port, ACC_UNATTACHED, PD_T_CC_DEBOUNCE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3410  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3411  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3412  	/* Hard_Reset states */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3413  	case HARD_RESET_SEND:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3414  		tcpm_pd_transmit(port, TCPC_TX_HARD_RESET, NULL);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3415  		tcpm_set_state(port, HARD_RESET_START, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3416  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3417  	case HARD_RESET_START:
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3418  		port->sink_cap_done = false;
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3419  		if (port->tcpc->enable_frs)
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3420  			port->tcpc->enable_frs(port->tcpc, false);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3421  		port->hard_reset_count++;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3422  		port->tcpc->set_pd_rx(port->tcpc, false);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3423  		tcpm_unregister_altmodes(port);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3424  		port->nr_sink_caps = 0;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3425  		port->send_discover = true;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3426  		if (port->pwr_role == TYPEC_SOURCE)
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3427  			tcpm_set_state(port, SRC_HARD_RESET_VBUS_OFF,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3428  				       PD_T_PS_HARD_RESET);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3429  		else
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3430  			tcpm_set_state(port, SNK_HARD_RESET_SINK_OFF, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3431  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3432  	case SRC_HARD_RESET_VBUS_OFF:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3433  		tcpm_set_vconn(port, true);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3434  		tcpm_set_vbus(port, false);
23b5f73266e59a drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2018-10-01  3435  		tcpm_set_roles(port, port->self_powered, TYPEC_SOURCE,
6ecc632d4b35d2 drivers/usb/typec/tcpm/tcpm.c Li Jun                 2020-02-14  3436  			       tcpm_data_role_for_source(port));
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3437  		tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, PD_T_SRC_RECOVER);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3438  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3439  	case SRC_HARD_RESET_VBUS_ON:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3440  		tcpm_set_vbus(port, true);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3441  		port->tcpc->set_pd_rx(port->tcpc, true);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3442  		tcpm_set_attached_state(port, true);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3443  		tcpm_set_state(port, SRC_UNATTACHED, PD_T_PS_SOURCE_ON);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3444  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3445  	case SNK_HARD_RESET_SINK_OFF:
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3446  		memset(&port->pps_data, 0, sizeof(port->pps_data));
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3447  		tcpm_set_vconn(port, false);
157c0f2f641a99 drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2018-10-01  3448  		if (port->pd_capable)
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3449  			tcpm_set_charge(port, false);
23b5f73266e59a drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2018-10-01  3450  		tcpm_set_roles(port, port->self_powered, TYPEC_SINK,
6ecc632d4b35d2 drivers/usb/typec/tcpm/tcpm.c Li Jun                 2020-02-14  3451  			       tcpm_data_role_for_sink(port));
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3452  		/*
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3453  		 * VBUS may or may not toggle, depending on the adapter.
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3454  		 * If it doesn't toggle, transition to SNK_HARD_RESET_SINK_ON
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3455  		 * directly after timeout.
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3456  		 */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3457  		tcpm_set_state(port, SNK_HARD_RESET_SINK_ON, PD_T_SAFE_0V);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3458  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3459  	case SNK_HARD_RESET_WAIT_VBUS:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3460  		/* Assume we're disconnected if VBUS doesn't come back. */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3461  		tcpm_set_state(port, SNK_UNATTACHED,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3462  			       PD_T_SRC_RECOVER_MAX + PD_T_SRC_TURN_ON);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3463  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3464  	case SNK_HARD_RESET_SINK_ON:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3465  		/* Note: There is no guarantee that VBUS is on in this state */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3466  		/*
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3467  		 * XXX:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3468  		 * The specification suggests that dual mode ports in sink
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3469  		 * mode should transition to state PE_SRC_Transition_to_default.
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3470  		 * See USB power delivery specification chapter 8.3.3.6.1.3.
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3471  		 * This would mean to to
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3472  		 * - turn off VCONN, reset power supply
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3473  		 * - request hardware reset
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3474  		 * - turn on VCONN
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3475  		 * - Transition to state PE_Src_Startup
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3476  		 * SNK only ports shall transition to state Snk_Startup
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3477  		 * (see chapter 8.3.3.3.8).
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3478  		 * Similar, dual-mode ports in source mode should transition
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3479  		 * to PE_SNK_Transition_to_default.
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3480  		 */
157c0f2f641a99 drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2018-10-01  3481  		if (port->pd_capable) {
157c0f2f641a99 drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2018-10-01  3482  			tcpm_set_current_limit(port,
157c0f2f641a99 drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2018-10-01  3483  					       tcpm_get_current_limit(port),
157c0f2f641a99 drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2018-10-01  3484  					       5000);
157c0f2f641a99 drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2018-10-01  3485  			tcpm_set_charge(port, true);
157c0f2f641a99 drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2018-10-01  3486  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3487  		tcpm_set_attached_state(port, true);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3488  		tcpm_set_state(port, SNK_STARTUP, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3489  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3490  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3491  	/* Soft_Reset states */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3492  	case SOFT_RESET:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3493  		port->message_id = 0;
5fec4b54d0bf6c drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3494  		port->rx_msgid = -1;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3495  		tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3496  		if (port->pwr_role == TYPEC_SOURCE)
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3497  			tcpm_set_state(port, SRC_SEND_CAPABILITIES, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3498  		else
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3499  			tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3500  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3501  	case SOFT_RESET_SEND:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3502  		port->message_id = 0;
5fec4b54d0bf6c drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3503  		port->rx_msgid = -1;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3504  		if (tcpm_pd_send_control(port, PD_CTRL_SOFT_RESET))
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3505  			tcpm_set_state_cond(port, hard_reset_state(port), 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3506  		else
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3507  			tcpm_set_state_cond(port, hard_reset_state(port),
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3508  					    PD_T_SENDER_RESPONSE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3509  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3510  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3511  	/* DR_Swap states */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3512  	case DR_SWAP_SEND:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3513  		tcpm_pd_send_control(port, PD_CTRL_DR_SWAP);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3514  		tcpm_set_state_cond(port, DR_SWAP_SEND_TIMEOUT,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3515  				    PD_T_SENDER_RESPONSE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3516  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3517  	case DR_SWAP_ACCEPT:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3518  		tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3519  		tcpm_set_state_cond(port, DR_SWAP_CHANGE_DR, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3520  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3521  	case DR_SWAP_SEND_TIMEOUT:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3522  		tcpm_swap_complete(port, -ETIMEDOUT);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3523  		tcpm_set_state(port, ready_state(port), 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3524  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3525  	case DR_SWAP_CHANGE_DR:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3526  		if (port->data_role == TYPEC_HOST) {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3527  			tcpm_unregister_altmodes(port);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3528  			tcpm_set_roles(port, true, port->pwr_role,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3529  				       TYPEC_DEVICE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3530  		} else {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3531  			tcpm_set_roles(port, true, port->pwr_role,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3532  				       TYPEC_HOST);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3533  			port->send_discover = true;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3534  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3535  		tcpm_set_state(port, ready_state(port), 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3536  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3537  
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3538  	case FR_SWAP_SEND:
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3539  		if (tcpm_pd_send_control(port, PD_CTRL_FR_SWAP)) {
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3540  			tcpm_set_state(port, ERROR_RECOVERY, 0);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3541  			break;
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3542  		}
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3543  		tcpm_set_state_cond(port, FR_SWAP_SEND_TIMEOUT, PD_T_SENDER_RESPONSE);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3544  		break;
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3545  	case FR_SWAP_SEND_TIMEOUT:
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3546  		tcpm_set_state(port, ERROR_RECOVERY, 0);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3547  		break;
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3548  	case FR_SWAP_SNK_SRC_TRANSITION_TO_OFF:
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3549  		tcpm_set_state(port, ERROR_RECOVERY, PD_T_PS_SOURCE_OFF);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3550  		break;
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3551  	case FR_SWAP_SNK_SRC_NEW_SINK_READY:
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3552  		if (port->vbus_source)
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3553  			tcpm_set_state(port, FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED, 0);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3554  		else
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3555  			tcpm_set_state(port, ERROR_RECOVERY, PD_T_RECEIVER_RESPONSE);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3556  		break;
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3557  	case FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED:
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3558  		tcpm_set_pwr_role(port, TYPEC_SOURCE);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3559  		if (tcpm_pd_send_control(port, PD_CTRL_PS_RDY)) {
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3560  			tcpm_set_state(port, ERROR_RECOVERY, 0);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3561  			break;
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3562  		}
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3563  		tcpm_set_cc(port, tcpm_rp_cc(port));
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3564  		tcpm_set_state(port, SRC_STARTUP, PD_T_SWAP_SRC_START);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3565  		break;
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3566  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3567  	/* PR_Swap states */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3568  	case PR_SWAP_ACCEPT:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3569  		tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3570  		tcpm_set_state(port, PR_SWAP_START, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3571  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3572  	case PR_SWAP_SEND:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3573  		tcpm_pd_send_control(port, PD_CTRL_PR_SWAP);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3574  		tcpm_set_state_cond(port, PR_SWAP_SEND_TIMEOUT,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3575  				    PD_T_SENDER_RESPONSE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3576  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3577  	case PR_SWAP_SEND_TIMEOUT:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3578  		tcpm_swap_complete(port, -ETIMEDOUT);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3579  		tcpm_set_state(port, ready_state(port), 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3580  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3581  	case PR_SWAP_START:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3582  		if (port->pwr_role == TYPEC_SOURCE)
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3583  			tcpm_set_state(port, PR_SWAP_SRC_SNK_TRANSITION_OFF,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3584  				       PD_T_SRC_TRANSITION);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3585  		else
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3586  			tcpm_set_state(port, PR_SWAP_SNK_SRC_SINK_OFF, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3587  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3588  	case PR_SWAP_SRC_SNK_TRANSITION_OFF:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3589  		tcpm_set_vbus(port, false);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3590  		port->explicit_contract = false;
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3591  		/* allow time for Vbus discharge, must be < tSrcSwapStdby */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3592  		tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF,
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3593  			       PD_T_SRCSWAPSTDBY);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3594  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3595  	case PR_SWAP_SRC_SNK_SOURCE_OFF:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3596  		tcpm_set_cc(port, TYPEC_CC_RD);
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3597  		/* allow CC debounce */
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3598  		tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED,
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3599  			       PD_T_CC_DEBOUNCE);
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3600  		break;
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3601  	case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED:
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3602  		/*
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3603  		 * USB-PD standard, 6.2.1.4, Port Power Role:
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3604  		 * "During the Power Role Swap Sequence, for the initial Source
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3605  		 * Port, the Port Power Role field shall be set to Sink in the
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3606  		 * PS_RDY Message indicating that the initial Source’s power
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3607  		 * supply is turned off"
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3608  		 */
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3609  		tcpm_set_pwr_role(port, TYPEC_SINK);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3610  		if (tcpm_pd_send_control(port, PD_CTRL_PS_RDY)) {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3611  			tcpm_set_state(port, ERROR_RECOVERY, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3612  			break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3613  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3614  		tcpm_set_state_cond(port, SNK_UNATTACHED, PD_T_PS_SOURCE_ON);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3615  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3616  	case PR_SWAP_SRC_SNK_SINK_ON:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3617  		tcpm_set_state(port, SNK_STARTUP, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3618  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3619  	case PR_SWAP_SNK_SRC_SINK_OFF:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3620  		tcpm_set_charge(port, false);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3621  		tcpm_set_state(port, hard_reset_state(port),
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3622  			       PD_T_PS_SOURCE_OFF);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3623  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3624  	case PR_SWAP_SNK_SRC_SOURCE_ON:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3625  		tcpm_set_cc(port, tcpm_rp_cc(port));
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3626  		tcpm_set_vbus(port, true);
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3627  		/*
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3628  		 * allow time VBUS ramp-up, must be < tNewSrc
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3629  		 * Also, this window overlaps with CC debounce as well.
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3630  		 * So, Wait for the max of two which is PD_T_NEWSRC
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3631  		 */
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3632  		tcpm_set_state(port, PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP,
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3633  			       PD_T_NEWSRC);
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3634  		break;
b965b6317ff147 drivers/staging/typec/tcpm.c  Badhri Jagan Sridharan 2017-08-28  3635  	case PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP:
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3636  		/*
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3637  		 * USB PD standard, 6.2.1.4:
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3638  		 * "Subsequent Messages initiated by the Policy Engine,
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3639  		 * such as the PS_RDY Message sent to indicate that Vbus
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3640  		 * is ready, will have the Port Power Role field set to
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3641  		 * Source."
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3642  		 */
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3643  		tcpm_set_pwr_role(port, TYPEC_SOURCE);
050161ea3268ad drivers/staging/typec/tcpm.c  Guenter Roeck          2017-05-09  3644  		tcpm_pd_send_control(port, PD_CTRL_PS_RDY);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3645  		tcpm_set_state(port, SRC_STARTUP, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3646  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3647  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3648  	case VCONN_SWAP_ACCEPT:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3649  		tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3650  		tcpm_set_state(port, VCONN_SWAP_START, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3651  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3652  	case VCONN_SWAP_SEND:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3653  		tcpm_pd_send_control(port, PD_CTRL_VCONN_SWAP);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3654  		tcpm_set_state(port, VCONN_SWAP_SEND_TIMEOUT,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3655  			       PD_T_SENDER_RESPONSE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3656  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3657  	case VCONN_SWAP_SEND_TIMEOUT:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3658  		tcpm_swap_complete(port, -ETIMEDOUT);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3659  		tcpm_set_state(port, ready_state(port), 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3660  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3661  	case VCONN_SWAP_START:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3662  		if (port->vconn_role == TYPEC_SOURCE)
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3663  			tcpm_set_state(port, VCONN_SWAP_WAIT_FOR_VCONN, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3664  		else
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3665  			tcpm_set_state(port, VCONN_SWAP_TURN_ON_VCONN, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3666  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3667  	case VCONN_SWAP_WAIT_FOR_VCONN:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3668  		tcpm_set_state(port, hard_reset_state(port),
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3669  			       PD_T_VCONN_SOURCE_ON);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3670  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3671  	case VCONN_SWAP_TURN_ON_VCONN:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3672  		tcpm_set_vconn(port, true);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3673  		tcpm_pd_send_control(port, PD_CTRL_PS_RDY);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3674  		tcpm_set_state(port, ready_state(port), 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3675  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3676  	case VCONN_SWAP_TURN_OFF_VCONN:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3677  		tcpm_set_vconn(port, false);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3678  		tcpm_set_state(port, ready_state(port), 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3679  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3680  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3681  	case DR_SWAP_CANCEL:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3682  	case PR_SWAP_CANCEL:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3683  	case VCONN_SWAP_CANCEL:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27 @3684  		tcpm_swap_complete(port, port->swap_status);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3685  	case FR_SWAP_CANCEL:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3686  		if (port->pwr_role == TYPEC_SOURCE)
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3687  			tcpm_set_state(port, SRC_READY, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3688  		else
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3689  			tcpm_set_state(port, SNK_READY, 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3690  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3691  
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3692  	case BIST_RX:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3693  		switch (BDO_MODE_MASK(port->bist_request)) {
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3694  		case BDO_MODE_CARRIER2:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3695  			tcpm_pd_transmit(port, TCPC_TX_BIST_MODE_2, NULL);
6e1c2241f4cecf drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-07-15  3696  			tcpm_set_state(port, unattached_state(port),
6e1c2241f4cecf drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-07-15  3697  				       PD_T_BIST_CONT_MODE);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3698  			break;
b2dcfefc43f783 drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-07-15  3699  		case BDO_MODE_TESTDATA:
b2dcfefc43f783 drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-07-15  3700  			if (port->tcpc->set_bist_data) {
b2dcfefc43f783 drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-07-15  3701  				tcpm_log(port, "Enable BIST MODE TESTDATA");
b2dcfefc43f783 drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-07-15  3702  				port->tcpc->set_bist_data(port->tcpc, true);
b2dcfefc43f783 drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-07-15  3703  			}
b2dcfefc43f783 drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-07-15  3704  			break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3705  		default:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3706  			break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3707  		}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3708  		break;
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3709  	case GET_STATUS_SEND:
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3710  		tcpm_pd_send_control(port, PD_CTRL_GET_STATUS);
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3711  		tcpm_set_state(port, GET_STATUS_SEND_TIMEOUT,
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3712  			       PD_T_SENDER_RESPONSE);
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3713  		break;
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3714  	case GET_STATUS_SEND_TIMEOUT:
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3715  		tcpm_set_state(port, ready_state(port), 0);
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3716  		break;
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3717  	case GET_PPS_STATUS_SEND:
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3718  		tcpm_pd_send_control(port, PD_CTRL_GET_PPS_STATUS);
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3719  		tcpm_set_state(port, GET_PPS_STATUS_SEND_TIMEOUT,
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3720  			       PD_T_SENDER_RESPONSE);
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3721  		break;
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3722  	case GET_PPS_STATUS_SEND_TIMEOUT:
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3723  		tcpm_set_state(port, ready_state(port), 0);
64f7c494a3c02b drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3724  		break;
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3725  	case GET_SINK_CAP:
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3726  		tcpm_pd_send_control(port, PD_CTRL_GET_SINK_CAP);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3727  		tcpm_set_state(port, GET_SINK_CAP_TIMEOUT, PD_T_SENDER_RESPONSE);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3728  		break;
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3729  	case GET_SINK_CAP_TIMEOUT:
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3730  		port->sink_cap_done = true;
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3731  		tcpm_set_state(port, ready_state(port), 0);
a8727cbd1e6baa drivers/usb/typec/tcpm/tcpm.c Badhri Jagan Sridharan 2020-08-24  3732  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3733  	case ERROR_RECOVERY:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3734  		tcpm_swap_complete(port, -EPROTO);
2eadc33f40d4c5 drivers/usb/typec/tcpm.c      Adam Thomson           2018-04-23  3735  		tcpm_pps_complete(port, -EPROTO);
b17dd57118fee7 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-08-10  3736  		tcpm_set_state(port, PORT_RESET, 0);
b17dd57118fee7 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-08-10  3737  		break;
b17dd57118fee7 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-08-10  3738  	case PORT_RESET:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3739  		tcpm_reset_port(port);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3740  		tcpm_set_cc(port, TYPEC_CC_OPEN);
b17dd57118fee7 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-08-10  3741  		tcpm_set_state(port, PORT_RESET_WAIT_OFF,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3742  			       PD_T_ERROR_RECOVERY);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3743  		break;
b17dd57118fee7 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-08-10  3744  	case PORT_RESET_WAIT_OFF:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3745  		tcpm_set_state(port,
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3746  			       tcpm_default_state(port),
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3747  			       port->vbus_present ? PD_T_PS_SOURCE_OFF : 0);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3748  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3749  	default:
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3750  		WARN(1, "Unexpected port state %d\n", port->state);
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3751  		break;
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3752  	}
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3753  }
f0690a25a140b8 drivers/staging/typec/tcpm.c  Guenter Roeck          2017-04-27  3754  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 30680 bytes --]

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

* Re: [PATCH 05/14 v5] usb: typec: tcpci: Add set_vbus tcpci callback
  2020-08-25  4:22 ` [PATCH 05/14 v5] usb: typec: tcpci: Add set_vbus tcpci callback Badhri Jagan Sridharan
@ 2020-08-28  7:37   ` Greg Kroah-Hartman
  0 siblings, 0 replies; 23+ messages in thread
From: Greg Kroah-Hartman @ 2020-08-28  7:37 UTC (permalink / raw)
  To: Badhri Jagan Sridharan
  Cc: Guenter Roeck, Heikki Krogerus, linux-usb, linux-kernel

On Mon, Aug 24, 2020 at 09:22:01PM -0700, Badhri Jagan Sridharan wrote:
> set_vbus callback allows TCPC which are TCPCI based, however,
> does not support turning on sink and source mode through
> Command.SinkVbus and Command.SourceVbusDefaultVoltage.
> 
> Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
> ---
>  drivers/usb/typec/tcpm/tcpci.c | 7 +++++++
>  drivers/usb/typec/tcpm/tcpci.h | 1 +
>  2 files changed, 8 insertions(+)

Why is this patch "v5" and the others "v1" in this series?

That's totally confusing, please just version the whole series, not
individual patches, as you are not providing version information about
what changed in this patch, right?

Make it easy for reviewers please...

thanks,

greg k-h

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

* Re: [PATCH 02/14 v2] usb: typec: tcpci: Add support when hidden tx registers are inaccessible
  2020-08-25  4:21 ` [PATCH 02/14 v2] usb: typec: tcpci: Add support when hidden tx registers are inaccessible Badhri Jagan Sridharan
@ 2020-08-28 13:12   ` Heikki Krogerus
  2020-08-28 14:49     ` Badhri Jagan Sridharan
  0 siblings, 1 reply; 23+ messages in thread
From: Heikki Krogerus @ 2020-08-28 13:12 UTC (permalink / raw)
  To: Badhri Jagan Sridharan
  Cc: Guenter Roeck, Greg Kroah-Hartman, linux-usb, linux-kernel

Looks like you forgot v1 somewhere :-)

On Mon, Aug 24, 2020 at 09:21:58PM -0700, Badhri Jagan Sridharan wrote:
> TCPCI spec forbids direct access of TX_BUF_BYTE_x register.
> The existing version of tcpci driver assumes that those registers
> are directly addressible. Add support for tcpci chips which do
> not support direct access to TX_BUF_BYTE_x registers. TX_BUF_BYTE_x
> can only be accessed by I2C_WRITE_BYTE_COUNT.
> 
> Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
> ---
>  drivers/usb/typec/tcpm/tcpci.c | 49 +++++++++++++++++++++++++---------
>  drivers/usb/typec/tcpm/tcpci.h |  8 ++++++
>  2 files changed, 44 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
> index f57d91fd0e09..90d348caa6a8 100644
> --- a/drivers/usb/typec/tcpm/tcpci.c
> +++ b/drivers/usb/typec/tcpm/tcpci.c
> @@ -320,8 +320,7 @@ static int tcpci_set_vbus(struct tcpc_dev *tcpc, bool source, bool sink)
>  	return 0;
>  }
>  
> -static int tcpci_pd_transmit(struct tcpc_dev *tcpc,
> -			     enum tcpm_transmit_type type,
> +static int tcpci_pd_transmit(struct tcpc_dev *tcpc, enum tcpm_transmit_type type,
>  			     const struct pd_message *msg)

That does not look like a relevant change.

>  {
>  	struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
> @@ -330,23 +329,47 @@ static int tcpci_pd_transmit(struct tcpc_dev *tcpc,
>  	int ret;
>  
>  	cnt = msg ? pd_header_cnt(header) * 4 : 0;
> -	ret = regmap_write(tcpci->regmap, TCPC_TX_BYTE_CNT, cnt + 2);
> -	if (ret < 0)
> -		return ret;
> +	/**
> +	 * TCPCI spec forbids direct access of TCPC_TX_DATA.
> +	 * But, since some of the chipsets offer this capability,
> +	 * it's fair to support both.
> +	 */
> +	if (!tcpci->data->TX_BUF_BYTE_x_hidden) {

Couldn't check if the flag is set first?

        if (tcpci->data->TX_BUF_BYTE_x_hidden) {
                ...

> +		ret = regmap_write(tcpci->regmap, TCPC_TX_BYTE_CNT, cnt + 2);
> +		if (ret < 0)
> +			return ret;
>  
> -	ret = tcpci_write16(tcpci, TCPC_TX_HDR, header);
> -	if (ret < 0)
> -		return ret;
> +		ret = tcpci_write16(tcpci, TCPC_TX_HDR, header);
> +		if (ret < 0)
> +			return ret;
> +
> +		if (cnt > 0) {
> +			ret = regmap_raw_write(tcpci->regmap, TCPC_TX_DATA, &msg->payload, cnt);
> +			if (ret < 0)
> +				return ret;
> +		}
> +	} else {
> +		u8 buf[TCPC_TRANSMIT_BUFFER_MAX_LEN] = {0,};
> +		u8 pos = 0;
> +
> +		/* Payload + header + TCPC_TX_BYTE_CNT */
> +		buf[pos++] = cnt + 2;
> +
> +		if (msg)
> +			memcpy(&buf[pos], &msg->header, sizeof(msg->header));
> +
> +		pos += sizeof(header);
> +
> +		if (cnt > 0)
> +			memcpy(&buf[pos], msg->payload, cnt);
>  
> -	if (cnt > 0) {
> -		ret = regmap_raw_write(tcpci->regmap, TCPC_TX_DATA,
> -				       &msg->payload, cnt);
> +		pos += cnt;
> +		ret = regmap_raw_write(tcpci->regmap, TCPC_TX_BYTE_CNT, buf, pos);
>  		if (ret < 0)
>  			return ret;
>  	}
>  
> -	reg = (PD_RETRY_COUNT << TCPC_TRANSMIT_RETRY_SHIFT) |
> -		(type << TCPC_TRANSMIT_TYPE_SHIFT);
> +	reg = (PD_RETRY_COUNT << TCPC_TRANSMIT_RETRY_SHIFT) | (type << TCPC_TRANSMIT_TYPE_SHIFT);
>  	ret = regmap_write(tcpci->regmap, TCPC_TRANSMIT, reg);
>  	if (ret < 0)
>  		return ret;
> diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h
> index fd26ca35814c..cf9d8b63adcb 100644
> --- a/drivers/usb/typec/tcpm/tcpci.h
> +++ b/drivers/usb/typec/tcpm/tcpci.h
> @@ -128,9 +128,17 @@
>  #define TCPC_VBUS_VOLTAGE_ALARM_HI_CFG		0x76
>  #define TCPC_VBUS_VOLTAGE_ALARM_LO_CFG		0x78
>  
> +/* I2C_WRITE_BYTE_COUNT + 1 when TX_BUF_BYTE_x is only accessible I2C_WRITE_BYTE_COUNT */
> +#define TCPC_TRANSMIT_BUFFER_MAX_LEN		31
> +
> +/*
> + * @TX_BUF_BYTE_x_hidden
> + *		optional; Set when TX_BUF_BYTE_x can only be accessed through I2C_WRITE_BYTE_COUNT.
> + */
>  struct tcpci;
>  struct tcpci_data {
>  	struct regmap *regmap;
> +	unsigned char TX_BUF_BYTE_x_hidden:1;
>  	int (*init)(struct tcpci *tcpci, struct tcpci_data *data);
>  	int (*set_vconn)(struct tcpci *tcpci, struct tcpci_data *data,
>  			 bool enable);
> -- 
> 2.28.0.297.g1956fa8f8d-goog

thanks,

-- 
heikki

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

* Re: [PATCH 04/14 v1] usb: typec: tcpci: Add a getter method to retrieve tcpm_port reference
  2020-08-25  4:22 ` [PATCH 04/14 v1] usb: typec: tcpci: Add a getter method to retrieve tcpm_port reference Badhri Jagan Sridharan
@ 2020-08-28 14:11   ` Heikki Krogerus
  0 siblings, 0 replies; 23+ messages in thread
From: Heikki Krogerus @ 2020-08-28 14:11 UTC (permalink / raw)
  To: Badhri Jagan Sridharan, Guenter Roeck
  Cc: Greg Kroah-Hartman, linux-usb, linux-kernel

On Mon, Aug 24, 2020 at 09:22:00PM -0700, Badhri Jagan Sridharan wrote:
> Allow chip level drivers to retrieve reference to tcpm_port.
> 
> Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
> ---
>  drivers/usb/typec/tcpm/tcpci.c | 6 ++++++
>  drivers/usb/typec/tcpm/tcpci.h | 2 ++
>  2 files changed, 8 insertions(+)
> 
> diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
> index 9e814d454d14..7b7991c8ac87 100644
> --- a/drivers/usb/typec/tcpm/tcpci.c
> +++ b/drivers/usb/typec/tcpm/tcpci.c
> @@ -38,6 +38,12 @@ struct tcpci_chip {
>  	struct tcpci_data data;
>  };
>  
> +struct tcpm_port *tcpci_get_tcpm_port(struct tcpci *tcpci)
> +{
> +	return tcpci->port;
> +}
> +EXPORT_SYMBOL_GPL(tcpci_get_tcpm_port);

I wonder if it would be better if there were tpci callbacks, or
wrappers, for the tcpm functions that the glue drivers could then use
instead of directly calling the tcpm_*() functions?  That would allow
tcpci.c to keep tabs on what is going on.

That would somehow feel like a better approach to me, but maybe it
would only complicate things. Guenter, what do you think?


thanks,

-- 
heikki

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

* Re: [PATCH 12/14] usb: typec: tcpm: Implement enabling Auto Discharge disconnect support
  2020-08-25  4:22 ` [PATCH 12/14] usb: typec: tcpm: Implement enabling Auto Discharge disconnect support Badhri Jagan Sridharan
@ 2020-08-28 14:13   ` Heikki Krogerus
  0 siblings, 0 replies; 23+ messages in thread
From: Heikki Krogerus @ 2020-08-28 14:13 UTC (permalink / raw)
  To: Badhri Jagan Sridharan
  Cc: Guenter Roeck, Greg Kroah-Hartman, linux-usb, linux-kernel

On Mon, Aug 24, 2020 at 09:22:08PM -0700, Badhri Jagan Sridharan wrote:
> TCPCI spec allows TCPC hardware to autonomously discharge the vbus
> capacitance upon disconnect. The expectation is that the TCPM enables
> AutoDischargeDisconnect while entering SNK/SRC_ATTACHED states. Hardware
> then automously discharges vbus when the vbus falls below a certain
> threshold i.e. VBUS_SINK_DISCONNECT_THRESHOLD.
> 
> Apart from enabling the vbus discharge circuit, AutoDischargeDisconnect
> is also used a flag to move TCPCI based TCPC implementations into
> Attached.Snk/Attached.Src state as mentioned in
> Figure 4-15. TCPC State Diagram before a Connection of the
> USB Type-C Port Controller Interface Specification.
> In such TCPC implementations, setting AutoDischargeDisconnect would
> prevent TCPC into entering "Connection_Invalid" state as well.
> 
> Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
> Change-Id: I09c407eb228d69eb1259008eeb14c429b0fda765

It looks like this patch is also formated a bit differently compared
to the others.

thanks,

-- 
heikki

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

* Re: [PATCH 02/14 v2] usb: typec: tcpci: Add support when hidden tx registers are inaccessible
  2020-08-28 13:12   ` Heikki Krogerus
@ 2020-08-28 14:49     ` Badhri Jagan Sridharan
  0 siblings, 0 replies; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-28 14:49 UTC (permalink / raw)
  To: Heikki Krogerus; +Cc: Guenter Roeck, Greg Kroah-Hartman, USB, LKML

On Fri, Aug 28, 2020 at 6:12 AM Heikki Krogerus
<heikki.krogerus@linux.intel.com> wrote:
>
> Looks like you forgot v1 somewhere :-)


Dumb me :P Yeah I was doing the patch numbers manually causing the confusion.
Greg was complaining as well.
These are all v1. I will re-upload everything as v2. Just noticed that
I can use the -v option.

>
>
> On Mon, Aug 24, 2020 at 09:21:58PM -0700, Badhri Jagan Sridharan wrote:
> > TCPCI spec forbids direct access of TX_BUF_BYTE_x register.
> > The existing version of tcpci driver assumes that those registers
> > are directly addressible. Add support for tcpci chips which do
> > not support direct access to TX_BUF_BYTE_x registers. TX_BUF_BYTE_x
> > can only be accessed by I2C_WRITE_BYTE_COUNT.
> >
> > Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
> > ---
> >  drivers/usb/typec/tcpm/tcpci.c | 49 +++++++++++++++++++++++++---------
> >  drivers/usb/typec/tcpm/tcpci.h |  8 ++++++
> >  2 files changed, 44 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
> > index f57d91fd0e09..90d348caa6a8 100644
> > --- a/drivers/usb/typec/tcpm/tcpci.c
> > +++ b/drivers/usb/typec/tcpm/tcpci.c
> > @@ -320,8 +320,7 @@ static int tcpci_set_vbus(struct tcpc_dev *tcpc, bool source, bool sink)
> >       return 0;
> >  }
> >
> > -static int tcpci_pd_transmit(struct tcpc_dev *tcpc,
> > -                          enum tcpm_transmit_type type,
> > +static int tcpci_pd_transmit(struct tcpc_dev *tcpc, enum tcpm_transmit_type type,
> >                            const struct pd_message *msg)
>
> That does not look like a relevant change.
>
> >  {
> >       struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
> > @@ -330,23 +329,47 @@ static int tcpci_pd_transmit(struct tcpc_dev *tcpc,
> >       int ret;
> >
> >       cnt = msg ? pd_header_cnt(header) * 4 : 0;
> > -     ret = regmap_write(tcpci->regmap, TCPC_TX_BYTE_CNT, cnt + 2);
> > -     if (ret < 0)
> > -             return ret;
> > +     /**
> > +      * TCPCI spec forbids direct access of TCPC_TX_DATA.
> > +      * But, since some of the chipsets offer this capability,
> > +      * it's fair to support both.
> > +      */
> > +     if (!tcpci->data->TX_BUF_BYTE_x_hidden) {
>
> Couldn't check if the flag is set first?

Yes will do !

>
>         if (tcpci->data->TX_BUF_BYTE_x_hidden) {
>                 ...
>
> > +             ret = regmap_write(tcpci->regmap, TCPC_TX_BYTE_CNT, cnt + 2);
> > +             if (ret < 0)
> > +                     return ret;
> >
> > -     ret = tcpci_write16(tcpci, TCPC_TX_HDR, header);
> > -     if (ret < 0)
> > -             return ret;
> > +             ret = tcpci_write16(tcpci, TCPC_TX_HDR, header);
> > +             if (ret < 0)
> > +                     return ret;
> > +
> > +             if (cnt > 0) {
> > +                     ret = regmap_raw_write(tcpci->regmap, TCPC_TX_DATA, &msg->payload, cnt);
> > +                     if (ret < 0)
> > +                             return ret;
> > +             }
> > +     } else {
> > +             u8 buf[TCPC_TRANSMIT_BUFFER_MAX_LEN] = {0,};
> > +             u8 pos = 0;
> > +
> > +             /* Payload + header + TCPC_TX_BYTE_CNT */
> > +             buf[pos++] = cnt + 2;
> > +
> > +             if (msg)
> > +                     memcpy(&buf[pos], &msg->header, sizeof(msg->header));
> > +
> > +             pos += sizeof(header);
> > +
> > +             if (cnt > 0)
> > +                     memcpy(&buf[pos], msg->payload, cnt);
> >
> > -     if (cnt > 0) {
> > -             ret = regmap_raw_write(tcpci->regmap, TCPC_TX_DATA,
> > -                                    &msg->payload, cnt);
> > +             pos += cnt;
> > +             ret = regmap_raw_write(tcpci->regmap, TCPC_TX_BYTE_CNT, buf, pos);
> >               if (ret < 0)
> >                       return ret;
> >       }
> >
> > -     reg = (PD_RETRY_COUNT << TCPC_TRANSMIT_RETRY_SHIFT) |
> > -             (type << TCPC_TRANSMIT_TYPE_SHIFT);
> > +     reg = (PD_RETRY_COUNT << TCPC_TRANSMIT_RETRY_SHIFT) | (type << TCPC_TRANSMIT_TYPE_SHIFT);
> >       ret = regmap_write(tcpci->regmap, TCPC_TRANSMIT, reg);
> >       if (ret < 0)
> >               return ret;
> > diff --git a/drivers/usb/typec/tcpm/tcpci.h b/drivers/usb/typec/tcpm/tcpci.h
> > index fd26ca35814c..cf9d8b63adcb 100644
> > --- a/drivers/usb/typec/tcpm/tcpci.h
> > +++ b/drivers/usb/typec/tcpm/tcpci.h
> > @@ -128,9 +128,17 @@
> >  #define TCPC_VBUS_VOLTAGE_ALARM_HI_CFG               0x76
> >  #define TCPC_VBUS_VOLTAGE_ALARM_LO_CFG               0x78
> >
> > +/* I2C_WRITE_BYTE_COUNT + 1 when TX_BUF_BYTE_x is only accessible I2C_WRITE_BYTE_COUNT */
> > +#define TCPC_TRANSMIT_BUFFER_MAX_LEN         31
> > +
> > +/*
> > + * @TX_BUF_BYTE_x_hidden
> > + *           optional; Set when TX_BUF_BYTE_x can only be accessed through I2C_WRITE_BYTE_COUNT.
> > + */
> >  struct tcpci;
> >  struct tcpci_data {
> >       struct regmap *regmap;
> > +     unsigned char TX_BUF_BYTE_x_hidden:1;
> >       int (*init)(struct tcpci *tcpci, struct tcpci_data *data);
> >       int (*set_vconn)(struct tcpci *tcpci, struct tcpci_data *data,
> >                        bool enable);
> > --
> > 2.28.0.297.g1956fa8f8d-goog
>
> thanks,
>
> --
> heikki

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

* Re: [PATCH 07/14 v1] usb: typec: tcpci_maxim: Chip level TCPC driver
  2020-08-25  5:16   ` Randy Dunlap
@ 2020-08-28 14:51     ` Badhri Jagan Sridharan
  0 siblings, 0 replies; 23+ messages in thread
From: Badhri Jagan Sridharan @ 2020-08-28 14:51 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: Guenter Roeck, Heikki Krogerus, Greg Kroah-Hartman, USB, LKML

On Mon, Aug 24, 2020 at 10:16 PM Randy Dunlap <rdunlap@infradead.org> wrote:
>
> On 8/24/20 9:22 PM, Badhri Jagan Sridharan wrote:
> > diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
> > index fa3f39336246..7c9722b02afe 100644
> > --- a/drivers/usb/typec/tcpm/Kconfig
> > +++ b/drivers/usb/typec/tcpm/Kconfig
> > @@ -27,6 +27,12 @@ config TYPEC_RT1711H
> >         Type-C Port Controller Manager to provide USB PD and USB
> >         Type-C functionalities.
> >
> > +config TYPEC_TCPCI_MAXIM
> > +     tristate "Maxim TCPCI based Type-C chip driver"
> > +     select USB_PSY
>
> is that        USB_PHY
> ?
Yes and not a dependency here. Will remove. Thanks for catching this !

>
> > +     help
> > +       MAXIM TCPCI based Type-C chip driver
>
> end that with '.' please.
Ack ! will fix it in the next version.

>
> > +
> >  endif # TYPEC_TCPCI
> >
> >  config TYPEC_FUSB302
>
>
> --
> ~Randy
>

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

end of thread, other threads:[~2020-08-28 14:52 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-25  4:21 [PATCH 00/14] TCPM support for FRS and AutoDischarge Disconnect Badhri Jagan Sridharan
2020-08-25  4:21 ` [PATCH 01/14 v1] usb: typec: tcpci: Add register definitions to tcpci Badhri Jagan Sridharan
2020-08-25  4:21 ` [PATCH 02/14 v2] usb: typec: tcpci: Add support when hidden tx registers are inaccessible Badhri Jagan Sridharan
2020-08-28 13:12   ` Heikki Krogerus
2020-08-28 14:49     ` Badhri Jagan Sridharan
2020-08-25  4:21 ` [PATCH 03/14 v1] usb: typec: tcpci: update ROLE_CONTROL for DRP Badhri Jagan Sridharan
2020-08-25  4:22 ` [PATCH 04/14 v1] usb: typec: tcpci: Add a getter method to retrieve tcpm_port reference Badhri Jagan Sridharan
2020-08-28 14:11   ` Heikki Krogerus
2020-08-25  4:22 ` [PATCH 05/14 v5] usb: typec: tcpci: Add set_vbus tcpci callback Badhri Jagan Sridharan
2020-08-28  7:37   ` Greg Kroah-Hartman
2020-08-25  4:22 ` [PATCH 06/14 v1] dt-bindings: usb: Maxim type-c controller device tree binding document Badhri Jagan Sridharan
2020-08-25  4:22 ` [PATCH 07/14 v1] usb: typec: tcpci_maxim: Chip level TCPC driver Badhri Jagan Sridharan
2020-08-25  5:16   ` Randy Dunlap
2020-08-28 14:51     ` Badhri Jagan Sridharan
2020-08-25  4:22 ` [PATCH 08/14 v1] dt-bindings: connector: Add property to set initial current cap for FRS Badhri Jagan Sridharan
2020-08-25  4:22 ` [PATCH 09/14 v1] usb: typec: tcpm: Add support for Sink Fast Role SWAP(FRS) Badhri Jagan Sridharan
2020-08-26 12:42   ` kernel test robot
2020-08-25  4:22 ` [PATCH 10/14 v1] usb: typec: tcpci: Implement callbacks for FRS Badhri Jagan Sridharan
2020-08-25  4:22 ` [PATCH 11/14 v1] usb: typec: tcpci_maxim: Add support for Sink FRS Badhri Jagan Sridharan
2020-08-25  4:22 ` [PATCH 12/14] usb: typec: tcpm: Implement enabling Auto Discharge disconnect support Badhri Jagan Sridharan
2020-08-28 14:13   ` Heikki Krogerus
2020-08-25  4:22 ` [PATCH 13/14 v1] usb: typec: tcpci: Implement Auto discharge disconnect callbacks Badhri Jagan Sridharan
2020-08-25  4:22 ` [PATCH 14/14 v1] usb: typec: tcpci_maxim: Implemnent set_auto_vbus_discharge_threshold Badhri Jagan Sridharan

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).