static int calc_next_state(int state) { struct batt_params batt; int alarm; battery_get_params_and_save_a_copy(&batt); switch (state) { case ST_IDLE0: case ST_BAD_COND: case ST_IDLE: /* Check AC and chiset state */ if (!extpower_is_present()) { if (chipset_in_state(CHIPSET_STATE_ON)) return ST_DISCHARGING; return ST_IDLE; } /* Stay in idle mode if charger overtemp */ if (pmu_is_charger_alarm()) return ST_BAD_COND; /* Enable charging when battery doesn't respond */ if (!(batt.flags & BATT_FLAG_RESPONSIVE)) return ST_PRE_CHARGING; /* Turn off charger when battery temperature is out * of the start charging range. */ if (!battery_start_charging_range(batt.temperature)) return ST_BAD_COND; /* Turn off charger on battery over temperature alarm */ if (battery_status(&alarm) || (alarm & ALARM_OVER_TEMP)) return ST_BAD_COND; /* Stop charging if the battery says it's charged */ if (alarm & ALARM_CHARGED) return ST_IDLE; /* Start charging only when battery charge lower than 100% */ if (!(batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE)) { if (batt.state_of_charge < 100) return ST_CHARGING; } return ST_IDLE; case ST_PRE_CHARGING: if (!extpower_is_present()) return ST_IDLE0; /* * If the battery goes online after enabling the charger, go * into charging state. */ if (batt.flags & BATT_FLAG_RESPONSIVE) { if (!battery_start_charging_range(batt.temperature)) return ST_IDLE0; if (!(batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE)) { if (batt.state_of_charge >= 100) return ST_IDLE0; } return ST_CHARGING; } return ST_PRE_CHARGING; case ST_CHARGING: /* Go back to idle state when AC is unplugged */ if (!extpower_is_present()) return ST_IDLE0; /* * Disable charging on battery access error, or charging * temperature out of range. */ if (!(batt.flags & BATT_FLAG_RESPONSIVE)) { CPRINTS("pmu charging: unable to get battery " "temperature"); return ST_IDLE0; } else if (!battery_charging_range(batt.temperature)) { CPRINTS("pmu charging: temperature out of range " "%dC", DECI_KELVIN_TO_CELSIUS(batt.temperature)); return ST_CHARGING_ERROR; } /* * Disable charging on battery alarm events or access error: * - over temperature * - over current */ if (battery_status(&alarm)) return ST_IDLE0; if (alarm & ALARM_OVER_TEMP) { CPRINTS("pmu charging: battery over temp"); return ST_CHARGING_ERROR; } /* Go to idle state if battery is fully charged */ if (alarm & ALARM_CHARGED) return ST_IDLE; /* * Disable charging on charger alarm events: * - charger over current * - charger over temperature */ if (pmu_is_charger_alarm()) { CPRINTS("pmu charging: charger alarm"); return ST_IDLE0; } return ST_CHARGING; case ST_CHARGING_ERROR: /* * This state indicates AC is plugged but the battery is not * charging. The conditions to exit this state: * - battery detected * - battery temperature is in start charging range * - no battery alarm */ if (extpower_is_present()) { if (battery_status(&alarm)) return ST_CHARGING_ERROR; if (alarm & ALARM_OVER_TEMP) return ST_CHARGING_ERROR; if (!(batt.flags & BATT_FLAG_RESPONSIVE)) return ST_CHARGING_ERROR; if (!battery_charging_range(batt.temperature)) return ST_CHARGING_ERROR; return ST_CHARGING; } return ST_IDLE0; case ST_DISCHARGING: /* Go back to idle state when AC is plugged */ if (extpower_is_present()) return ST_IDLE0; /* Prepare EC sleep after system stopped discharging */ if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) return ST_IDLE0; /* Check battery discharging temperature range */ if (batt.flags & BATT_FLAG_RESPONSIVE) { if (!battery_discharging_range(batt.temperature)) { CPRINTS("pmu discharging: temperature out of " "range %dC", DECI_KELVIN_TO_CELSIUS( batt.temperature)); return system_off(); } } /* Check discharging alarm */ if (!battery_status(&alarm) && (alarm & ALARM_DISCHARGING)) { CPRINTS("pmu discharging: battery alarm %016b", alarm); return system_off(); } /* Check remaining charge % */ if (!(batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE)) { /* * Shutdown AP when state of charge < 1.5%. * Moving average is rounded to integer. */ if (rsoc_moving_average(batt.state_of_charge) < 2) return system_off(); else if (batt.state_of_charge < 4) notify_battery_low(); } return ST_DISCHARGING; } return ST_IDLE0; }
static void button_long_push() { if(system_off) system_off(); }