in extcon-intel-cht-wc.c [126:180]
static int cht_wc_extcon_get_charger(struct cht_wc_extcon_data *ext,
bool ignore_errors)
{
int ret, usbsrc, status;
unsigned long timeout;
/* Charger detection can take upto 600ms, wait 800ms max. */
timeout = jiffies + msecs_to_jiffies(800);
do {
ret = regmap_read(ext->regmap, CHT_WC_USBSRC, &usbsrc);
if (ret) {
dev_err(ext->dev, "Error reading usbsrc: %d\n", ret);
return ret;
}
status = usbsrc & CHT_WC_USBSRC_STS_MASK;
if (status == CHT_WC_USBSRC_STS_SUCCESS ||
status == CHT_WC_USBSRC_STS_FAIL)
break;
msleep(50); /* Wait a bit before retrying */
} while (time_before(jiffies, timeout));
if (status != CHT_WC_USBSRC_STS_SUCCESS) {
if (ignore_errors)
return EXTCON_CHG_USB_SDP; /* Save fallback */
if (status == CHT_WC_USBSRC_STS_FAIL)
dev_warn(ext->dev, "Could not detect charger type\n");
else
dev_warn(ext->dev, "Timeout detecting charger type\n");
return EXTCON_CHG_USB_SDP; /* Save fallback */
}
usbsrc = (usbsrc & CHT_WC_USBSRC_TYPE_MASK) >> CHT_WC_USBSRC_TYPE_SHIFT;
switch (usbsrc) {
default:
dev_warn(ext->dev,
"Unhandled charger type %d, defaulting to SDP\n",
ret);
return EXTCON_CHG_USB_SDP;
case CHT_WC_USBSRC_TYPE_SDP:
case CHT_WC_USBSRC_TYPE_FLOATING:
case CHT_WC_USBSRC_TYPE_OTHER:
return EXTCON_CHG_USB_SDP;
case CHT_WC_USBSRC_TYPE_CDP:
return EXTCON_CHG_USB_CDP;
case CHT_WC_USBSRC_TYPE_DCP:
case CHT_WC_USBSRC_TYPE_DCP_EXTPHY:
case CHT_WC_USBSRC_TYPE_MHL: /* MHL2+ delivers upto 2A, treat as DCP */
return EXTCON_CHG_USB_DCP;
case CHT_WC_USBSRC_TYPE_ACA:
return EXTCON_CHG_USB_ACA;
}
}