void pm8x41_reg_write_mask(uint32_t addr, uint8_t mask, uint8_t val) { uint8_t tmp; tmp = pm8x41_reg_read(addr); tmp &= mask; tmp |= (val & ~mask); pm8x41_reg_write(addr, tmp); tmp = pm8x41_reg_read(addr); }
/* API to check for borken battery */ int pm8xxx_is_battery_broken() { uint8_t trkl_default = 0; uint8_t vbat_det_default = 0; int batt_is_broken = 0; /* Store original trickle charging current setting */ trkl_default = pm8x41_reg_read(PM8XXX_IBAT_ATC_A); /* Store original VBAT_DET_LO setting */ vbat_det_default = pm8x41_reg_read(PM8XXX_VBAT_DET); /*Set trickle charge current to 50mA (IBAT_ATC_A = 0x00) */ pm8x41_reg_write(PM8XXX_IBAT_ATC_A, 0x00); /* Set VBAT_DET_LO to 4.3V so that VBAT_DET_HI = 4.52V (VBAT_DET_LO = 0x35) */ pm8x41_reg_write(PM8XXX_VBAT_DET, VBAT_DET_LO_4_30V); /* Unlock SMBBP Secured Register */ pm8x41_reg_write(PM8XXX_SEC_ACCESS, SEC_ACCESS); /* Disable VTRKL_FAULT comp (SMBBP_CHGR_COMP_OVR0 = 0x08) */ pm8x41_reg_write(PM8XXX_COMP_OVR0, OVR0_DIS_VTRKL_FAULT); /* Disable VCP (SMBB_BAT_IF_VCP = 0x00) */ pm8x41_reg_write(PM8XXX_VCP, 0x00); /* Unlock SMBBP Secured Register */ pm8x41_reg_write(PM8XXX_SEC_ACCESS, SEC_ACCESS); /* Force trickle charging (SMBB_CHGR_TRKL_CHG_TEST = 0x01) */ pm8x41_reg_write(PM8XXX_TRKL_CHG_TEST, CHG_TRICKLE_FORCED_ON); /* Wait for vbat to rise */ mdelay(12); /* Check Above VBAT_DET_HIGH status */ if (pm8x41_reg_read(PM8XXX_VBAT_IN_TSTS) & VBAT_DET_HI_RT_STS) batt_is_broken = 1; else batt_is_broken = 0; /* Unlock SMBBP Secured Register */ pm8x41_reg_write(PM8XXX_SEC_ACCESS, SEC_ACCESS); /* Disable force trickle charging */ pm8x41_reg_write(PM8XXX_TRKL_CHG_TEST, 0x00); /* re-enable VCP */ pm8x41_reg_write(PM8XXX_VCP, VCP_ENABLE); /* restore trickle charging default current */ pm8x41_reg_write(PM8XXX_IBAT_ATC_A, trkl_default); /* restore VBAT_DET_LO setting to original value */ pm8x41_reg_write(PM8XXX_VBAT_DET, vbat_det_default); return batt_is_broken; }
unsigned check_hard_reboot_mode(void) { uint8_t hard_restart_reason = 0; uint8_t value = 0; /* Read reboot reason and scrub it * Bit-5, bit-6 and bit-7 of SOFT_RB_SPARE for hard reset reason */ value = pm8x41_reg_read(PON_SOFT_RB_SPARE); hard_restart_reason = value >> 5; pm8x41_reg_write(PON_SOFT_RB_SPARE, value & 0x1f); return hard_restart_reason; }
unsigned target_pause_for_battery_charge(void) { uint8_t pon_reason = pm8x41_get_pon_reason(); uint8_t is_cold_boot = pm8x41_get_is_cold_boot(); bool usb_present_sts = !(USBIN_UV_RT_STS & pm8x41_reg_read(SMBCHG_USB_RT_STS)); dprintf(INFO, "%s : pon_reason is:0x%x cold_boot:%d usb_sts:%d\n", __func__, pon_reason, is_cold_boot, usb_present_sts); /* In case of fastboot reboot,adb reboot or if we see the power key * pressed we do not want go into charger mode. * fastboot reboot is warm boot with PON hard reset bit not set * adb reboot is a cold boot with PON hard reset bit set */ if (is_cold_boot && (!(pon_reason & HARD_RST)) && (!(pon_reason & KPDPWR_N)) && usb_present_sts) return 1; else return 0; }
void bootmode_set_cable_port(void) { uint8_t port_type = 0; port_type = pm8x41_reg_read(PM_MISC_IDEV_STS); if (port_type & PM_CHGR_PORT_CDP) bootmode_port = CHARGER_PORT_CDP; else if (port_type & PM_CHGR_PORT_DCP) bootmode_port = CHARGER_PORT_DCP; else if (port_type & PM_CHGR_PORT_SDP) bootmode_port = CHARGER_PORT_SDP; else if (port_type & PM_CHGR_PORT_OTHER) bootmode_port = CHARGER_PORT_UNKNOWN; else bootmode_port = CHARGER_PORT_INVALID; dprintf(INFO, "%s: chg port type is 0x%x : %s\n", __func__, port_type, port_type_string[bootmode_port]); return; }