Skip to content

Commit a381c6d

Browse files
amitsd2gregkh
authored andcommitted
usb: typec: maxim_contaminant: re-enable cc toggle if cc is open and port is clean
Presently in `max_contaminant_is_contaminant()` if there's no contaminant detected previously, CC is open & stopped toggling and no contaminant is currently present, TCPC.RC would be programmed to do DRP toggling. However, it didn't actively look for a connection. This would lead to Type-C not detect *any* new connections. Hence, in the above situation, re-enable toggling & program TCPC to look for a new connection. Also, return early if TCPC was looking for connection as this indicates TCPC has neither detected a potential connection nor a change in contaminant state. In addition, once dry detection is complete (port is dry), restart toggling. Fixes: 02b332a ("usb: typec: maxim_contaminant: Implement check_contaminant callback") Cc: stable <[email protected]> Signed-off-by: Amit Sunil Dhamne <[email protected]> Reviewed-by: Badhri Jagan Sridharan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent cabb6c5 commit a381c6d

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

drivers/usb/typec/tcpm/maxim_contaminant.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,39 @@ static int max_contaminant_enable_dry_detection(struct max_tcpci_chip *chip)
329329
return 0;
330330
}
331331

332+
static int max_contaminant_enable_toggling(struct max_tcpci_chip *chip)
333+
{
334+
struct regmap *regmap = chip->data.regmap;
335+
int ret;
336+
337+
/* Disable dry detection if enabled. */
338+
ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL,
339+
FIELD_PREP(CCLPMODESEL,
340+
LOW_POWER_MODE_DISABLE));
341+
if (ret)
342+
return ret;
343+
344+
ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL1, CCCONNDRY, 0);
345+
if (ret)
346+
return ret;
347+
348+
ret = max_tcpci_write8(chip, TCPC_ROLE_CTRL, TCPC_ROLE_CTRL_DRP |
349+
FIELD_PREP(TCPC_ROLE_CTRL_CC1,
350+
TCPC_ROLE_CTRL_CC_RD) |
351+
FIELD_PREP(TCPC_ROLE_CTRL_CC2,
352+
TCPC_ROLE_CTRL_CC_RD));
353+
if (ret)
354+
return ret;
355+
356+
ret = regmap_update_bits(regmap, TCPC_TCPC_CTRL,
357+
TCPC_TCPC_CTRL_EN_LK4CONN_ALRT,
358+
TCPC_TCPC_CTRL_EN_LK4CONN_ALRT);
359+
if (ret)
360+
return ret;
361+
362+
return max_tcpci_write8(chip, TCPC_COMMAND, TCPC_CMD_LOOK4CONNECTION);
363+
}
364+
332365
bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect_while_debounce,
333366
bool *cc_handled)
334367
{
@@ -345,6 +378,12 @@ bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect
345378
if (ret < 0)
346379
return false;
347380

381+
if (cc_status & TCPC_CC_STATUS_TOGGLING) {
382+
if (chip->contaminant_state == DETECTED)
383+
return true;
384+
return false;
385+
}
386+
348387
if (chip->contaminant_state == NOT_DETECTED || chip->contaminant_state == SINK) {
349388
if (!disconnect_while_debounce)
350389
msleep(100);
@@ -377,13 +416,27 @@ bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect
377416
max_contaminant_enable_dry_detection(chip);
378417
return true;
379418
}
419+
420+
ret = max_contaminant_enable_toggling(chip);
421+
if (ret)
422+
dev_err(chip->dev,
423+
"Failed to enable toggling, ret=%d",
424+
ret);
380425
}
381426
} else if (chip->contaminant_state == DETECTED) {
382427
if (!(cc_status & TCPC_CC_STATUS_TOGGLING)) {
383428
chip->contaminant_state = max_contaminant_detect_contaminant(chip);
384429
if (chip->contaminant_state == DETECTED) {
385430
max_contaminant_enable_dry_detection(chip);
386431
return true;
432+
} else {
433+
ret = max_contaminant_enable_toggling(chip);
434+
if (ret) {
435+
dev_err(chip->dev,
436+
"Failed to enable toggling, ret=%d",
437+
ret);
438+
return true;
439+
}
387440
}
388441
}
389442
}

0 commit comments

Comments
 (0)