Skip to content

Commit afb487a

Browse files
Badhri Jagan Sridharangregkh
authored andcommitted
usb: typec: tcpci_maxim: Add support for Sink FRS
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 <[email protected]> Reviewed-by: Heikki Krogerus <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 11121c2 commit afb487a

File tree

1 file changed

+46
-4
lines changed

1 file changed

+46
-4
lines changed

drivers/usb/typec/tcpm/tcpci_maxim.c

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,22 @@ static void max_tcpci_init_regs(struct max_tcpci_chip *chip)
106106
return;
107107
}
108108

109+
ret = max_tcpci_write8(chip, TCPC_ALERT_EXTENDED, 0xff);
110+
if (ret < 0) {
111+
dev_err(chip->dev, "Unable to clear TCPC_ALERT_EXTENDED ret:%d\n", ret);
112+
return;
113+
}
114+
109115
alert_mask = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_DISCARDED | TCPC_ALERT_TX_FAILED |
110116
TCPC_ALERT_RX_HARD_RST | TCPC_ALERT_RX_STATUS | TCPC_ALERT_CC_STATUS |
111-
TCPC_ALERT_VBUS_DISCNCT | TCPC_ALERT_RX_BUF_OVF | TCPC_ALERT_POWER_STATUS;
117+
TCPC_ALERT_VBUS_DISCNCT | TCPC_ALERT_RX_BUF_OVF | TCPC_ALERT_POWER_STATUS |
118+
/* Enable Extended alert for detecting Fast Role Swap Signal */
119+
TCPC_ALERT_EXTND;
112120

113121
ret = max_tcpci_write16(chip, TCPC_ALERT_MASK, alert_mask);
114122
if (ret < 0) {
115-
dev_err(chip->dev, "Error writing to TCPC_ALERT_MASK ret:%d\n", ret);
123+
dev_err(chip->dev,
124+
"Error enabling TCPC_ALERT: TCPC_ALERT_MASK write failed ret:%d\n", ret);
116125
return;
117126
}
118127

@@ -122,6 +131,10 @@ static void max_tcpci_init_regs(struct max_tcpci_chip *chip)
122131
dev_err(chip->dev, "Error writing to TCPC_POWER_CTRL ret:%d\n", ret);
123132
return;
124133
}
134+
135+
ret = max_tcpci_write8(chip, TCPC_ALERT_EXTENDED_MASK, TCPC_SINK_FAST_ROLE_SWAP);
136+
if (ret < 0)
137+
return;
125138
}
126139

127140
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)
225238
if (ret < 0)
226239
return;
227240

228-
if (pwr_status == 0xff)
241+
if (pwr_status == 0xff) {
229242
max_tcpci_init_regs(chip);
230-
else
243+
} else if (pwr_status & TCPC_POWER_STATUS_SOURCING_VBUS) {
244+
tcpm_sourcing_vbus(chip->port);
245+
/*
246+
* Alawys re-enable boost here.
247+
* In normal case, when say an headset is attached, TCPM would
248+
* have instructed to TCPC to enable boost, so the call is a
249+
* no-op.
250+
* But for Fast Role Swap case, Boost turns on autonomously without
251+
* AP intervention, but, needs AP to enable source mode explicitly
252+
* for AP to regain control.
253+
*/
254+
max_tcpci_set_vbus(chip->tcpci, &chip->data, true, false);
255+
} else {
231256
tcpm_vbus_change(chip->port);
257+
}
232258
}
233259

234260
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)
249275
{
250276
u16 mask;
251277
int ret;
278+
u8 reg_status;
252279

253280
/*
254281
* 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)
274301
}
275302
}
276303

304+
if (status & TCPC_ALERT_EXTND) {
305+
ret = max_tcpci_read8(chip, TCPC_ALERT_EXTENDED, &reg_status);
306+
if (ret < 0)
307+
return ret;
308+
309+
ret = max_tcpci_write8(chip, TCPC_ALERT_EXTENDED, reg_status);
310+
if (ret < 0)
311+
return ret;
312+
313+
if (reg_status & TCPC_SINK_FAST_ROLE_SWAP) {
314+
dev_info(chip->dev, "FRS Signal");
315+
tcpm_sink_frs(chip->port);
316+
}
317+
}
318+
277319
if (status & TCPC_ALERT_RX_STATUS)
278320
process_rx(chip, status);
279321

0 commit comments

Comments
 (0)