/* BC module vbus control and status register */ #define VBUS_CNTL_DPDM_PD_EN BIT(4) #define VBUS_CNTL_DPDM_FD_EN BIT(5) #define VBUS_CNTL_FIRST_PO_STAT BIT(6)
/* Power up/down reason string array */ staticconstchar * const axp288_pwr_up_down_info[] = { "Last wake caused by user pressing the power button", "Last wake caused by a charger insertion", "Last wake caused by a battery insertion", "Last wake caused by SOC initiated global reset", "Last wake caused by cold reset", "Last shutdown caused by PMIC UVLO threshold", "Last shutdown caused by SOC initiated cold off", "Last shutdown caused by user pressing the power button",
};
/* *Decodeandlogthegiven"resetsourceindicator"(rsi) *registerandthenclearit.
*/ staticvoid axp288_extcon_log_rsi(struct axp288_extcon_info *info)
{ unsignedint val, i, clear_mask = 0; unsignedlong bits; int ret;
ret = regmap_read(info->regmap, AXP288_PS_BOOT_REASON_REG, &val); if (ret < 0) {
dev_err(info->dev, "failed to read reset source indicator\n"); return;
}
switch (chrg_type) { case DET_STAT_SDP:
dev_dbg(info->dev, "sdp cable is connected\n");
cable = EXTCON_CHG_USB_SDP; break; case DET_STAT_CDP:
dev_dbg(info->dev, "cdp cable is connected\n");
cable = EXTCON_CHG_USB_CDP; break; case DET_STAT_DCP:
dev_dbg(info->dev, "dcp cable is connected\n");
cable = EXTCON_CHG_USB_DCP; break; default:
dev_warn(info->dev, "unknown (reserved) bc detect result\n");
cable = EXTCON_CHG_USB_SDP;
}
no_vbus:
iosf_mbi_unblock_punit_i2c_access();
extcon_set_state_sync(info->edev, info->previous_cable, false); if (info->previous_cable == EXTCON_CHG_USB_SDP)
extcon_set_state_sync(info->edev, EXTCON_USB, false);
if (vbus_attach) {
extcon_set_state_sync(info->edev, cable, vbus_attach); if (cable == EXTCON_CHG_USB_SDP)
extcon_set_state_sync(info->edev, EXTCON_USB,
vbus_attach);
info->previous_cable = cable;
}
if (info->role_sw && info->vbus_attach != vbus_attach) {
info->vbus_attach = vbus_attach; /* Setting the role can take a while */
queue_work(system_long_wq, &info->role_work);
}
return0;
dev_det_ret:
iosf_mbi_unblock_punit_i2c_access();
if (ret < 0)
dev_err(info->dev, "failed to detect BC Mod\n");
ret = axp288_extcon_find_role_sw(info); if (ret) return ret;
if (info->role_sw) {
ret = devm_add_action_or_reset(dev, axp288_put_role_sw, info); if (ret) return ret;
adev = acpi_dev_get_first_match_dev("INT3496", NULL, -1); if (adev) {
info->id_extcon = extcon_get_extcon_dev(acpi_dev_name(adev));
acpi_dev_put(adev); if (IS_ERR(info->id_extcon)) return PTR_ERR(info->id_extcon);
dev_info(dev, "controlling USB role\n");
} else {
dev_info(dev, "controlling USB role based on Vbus presence\n");
}
}
ret = iosf_mbi_block_punit_i2c_access(); if (ret < 0) return ret;
info->vbus_attach = axp288_get_vbus_attach(info);
axp288_extcon_log_rsi(info);
iosf_mbi_unblock_punit_i2c_access();
/* Initialize extcon device */
info->edev = devm_extcon_dev_allocate(&pdev->dev,
axp288_extcon_cables); if (IS_ERR(info->edev)) {
dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); return PTR_ERR(info->edev);
}
/* Register extcon device */
ret = devm_extcon_dev_register(&pdev->dev, info->edev); if (ret) {
dev_err(&pdev->dev, "failed to register extcon device\n"); return ret;
}
for (i = 0; i < EXTCON_IRQ_END; i++) {
pirq = platform_get_irq(pdev, i); if (pirq < 0) return pirq;
info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq); if (info->irq[i] < 0) {
dev_err(&pdev->dev, "failed to get virtual interrupt=%d\n", pirq);
ret = info->irq[i]; return ret;
}
ret = devm_request_threaded_irq(&pdev->dev, info->irq[i],
NULL, axp288_extcon_isr,
IRQF_ONESHOT | IRQF_NO_SUSPEND,
pdev->name, info); if (ret) {
dev_err(&pdev->dev, "failed to request interrupt=%d\n",
info->irq[i]); return ret;
}
}
if (info->id_extcon) {
ret = devm_extcon_register_notifier_all(dev, info->id_extcon,
&info->id_nb); if (ret) return ret;
}
/* Make sure the role-sw is set correctly before doing BC detection */ if (info->role_sw) {
queue_work(system_long_wq, &info->role_work);
flush_work(&info->role_work);
}
/* Start charger cable type detection */
ret = axp288_extcon_enable(info); if (ret < 0) return ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.