@@ -106,13 +106,22 @@ static void max_tcpci_init_regs(struct max_tcpci_chip *chip)
106
106
return ;
107
107
}
108
108
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
+
109
115
alert_mask = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_DISCARDED | TCPC_ALERT_TX_FAILED |
110
116
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 ;
112
120
113
121
ret = max_tcpci_write16 (chip , TCPC_ALERT_MASK , alert_mask );
114
122
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 );
116
125
return ;
117
126
}
118
127
@@ -122,6 +131,10 @@ static void max_tcpci_init_regs(struct max_tcpci_chip *chip)
122
131
dev_err (chip -> dev , "Error writing to TCPC_POWER_CTRL ret:%d\n" , ret );
123
132
return ;
124
133
}
134
+
135
+ ret = max_tcpci_write8 (chip , TCPC_ALERT_EXTENDED_MASK , TCPC_SINK_FAST_ROLE_SWAP );
136
+ if (ret < 0 )
137
+ return ;
125
138
}
126
139
127
140
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)
225
238
if (ret < 0 )
226
239
return ;
227
240
228
- if (pwr_status == 0xff )
241
+ if (pwr_status == 0xff ) {
229
242
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 {
231
256
tcpm_vbus_change (chip -> port );
257
+ }
232
258
}
233
259
234
260
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)
249
275
{
250
276
u16 mask ;
251
277
int ret ;
278
+ u8 reg_status ;
252
279
253
280
/*
254
281
* 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)
274
301
}
275
302
}
276
303
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
+
277
319
if (status & TCPC_ALERT_RX_STATUS )
278
320
process_rx (chip , status );
279
321
0 commit comments