static int command_chgstate(int argc, char **argv) { int rv; int val; if (argc > 1) { if (!strcasecmp(argv[1], "idle")) { if (argc <= 2) return EC_ERROR_PARAM_COUNT; if (!parse_bool(argv[2], &val)) return EC_ERROR_PARAM2; rv = set_chg_ctrl_mode(val ? CHARGE_CONTROL_IDLE : CHARGE_CONTROL_NORMAL); if (rv) return rv; #ifdef CONFIG_CHARGER_DISCHARGE_ON_AC } else if (!strcasecmp(argv[1], "discharge")) { if (argc <= 2) return EC_ERROR_PARAM_COUNT; if (!parse_bool(argv[2], &val)) return EC_ERROR_PARAM2; rv = set_chg_ctrl_mode(val ? CHARGE_CONTROL_DISCHARGE : CHARGE_CONTROL_NORMAL); if (rv) return rv; #ifdef CONFIG_CHARGER_DISCHARGE_ON_AC_CUSTOM rv = board_discharge_on_ac(val); #else rv = charger_discharge_on_ac(val); #endif /* CONFIG_CHARGER_DISCHARGE_ON_AC_CUSTOM */ if (rv) return rv; #endif /* CONFIG_CHARGER_DISCHARGE_ON_AC */ } else if (!strcasecmp(argv[1], "debug")) { if (argc <= 2) return EC_ERROR_PARAM_COUNT; if (!parse_bool(argv[2], &debugging)) return EC_ERROR_PARAM2; } else { return EC_ERROR_PARAM1; } } dump_charge_state(); return EC_SUCCESS; }
static int charge_command_charge_control(struct host_cmd_handler_args *args) { const struct ec_params_charge_control *p = args->params; int rv; if (system_is_locked()) return EC_RES_ACCESS_DENIED; rv = set_chg_ctrl_mode(p->mode); if (rv != EC_SUCCESS) return EC_RES_ERROR; #ifdef CONFIG_CHARGER_DISCHARGE_ON_AC #ifdef CONFIG_CHARGER_DISCHARGE_ON_AC_CUSTOM rv = board_discharge_on_ac(p->mode == CHARGE_CONTROL_DISCHARGE); #else rv = charger_discharge_on_ac(p->mode == CHARGE_CONTROL_DISCHARGE); #endif if (rv != EC_SUCCESS) return EC_RES_ERROR; #endif return EC_RES_SUCCESS; }
/** * Discharge battery when on AC power for factory test. */ int board_discharge_on_ac(int enable) { return charger_discharge_on_ac(enable); }
int charger_profile_override(struct charge_state_data *curr) { /* temp in 0.1 deg C */ int temp_c = curr->batt.temperature - 2731; /* keep track of last temperature range for hysteresis */ static enum { TEMP_RANGE_1, TEMP_RANGE_2, TEMP_RANGE_3, TEMP_RANGE_4, TEMP_RANGE_5, } temp_range = TEMP_RANGE_3; /* keep track of last voltage range for hysteresis */ static enum { VOLTAGE_RANGE_LOW, VOLTAGE_RANGE_HIGH, } voltage_range = VOLTAGE_RANGE_LOW; /* Current and previous battery voltage */ int batt_voltage; static int prev_batt_voltage; charger_discharge_on_ac(!(curr->batt.flags & BATT_FLAG_WANT_CHARGE)); /* * Determine temperature range. The five ranges are: * < 0C * 0C>= <=15C * 15C> <=20C * 20C> <=45C * > 45C * * If temp reading was bad, use last range. */ if (!(curr->batt.flags & BATT_FLAG_BAD_TEMPERATURE)) { if (temp_c < 0) temp_range = TEMP_RANGE_1; else if (temp_c <= 150) temp_range = TEMP_RANGE_2; else if (temp_c <= 200) temp_range = TEMP_RANGE_3; else if (temp_c <= 450) temp_range = TEMP_RANGE_4; else temp_range = TEMP_RANGE_5; } /* * If battery voltage reading is bad, use the last reading. */ if (curr->batt.flags & BATT_FLAG_BAD_VOLTAGE) { batt_voltage = prev_batt_voltage; } else { batt_voltage = prev_batt_voltage = curr->batt.voltage; if (batt_voltage <= 8000) voltage_range = VOLTAGE_RANGE_LOW; else if (batt_voltage > 8000) voltage_range = VOLTAGE_RANGE_HIGH; } /* * If we are not charging or we aren't using fast charging profiles, * then do not override desired current and voltage. */ if (curr->state != ST_CHARGE || !fast_charging_allowed) return 0; /* * Okay, impose our custom will: * * When battery is < 0C: * CC at 0mA @ 0V * CV at 0V * * When battery is 0-15C: * CC at 944mA until 8.0V @ 8.7V * CC at 472mA @ 8.7V * CV at 8.7V * * When battery is 15-20C: * CC at 1416mA @ 8.7V * CV at 8.7V * * When battery is 20-45C: * CC at 3300mA @ 8.7V * CV at 8.7V * * When battery is > 45C: * CC at 0mA @ 0V * CV at 0V */ switch (temp_range) { case TEMP_RANGE_2: if (voltage_range == VOLTAGE_RANGE_HIGH) curr->requested_current = 472; else curr->requested_current = 944; curr->requested_voltage = 8700; break; case TEMP_RANGE_3: curr->requested_current = 1416; curr->requested_voltage = 8700; break; case TEMP_RANGE_4: curr->requested_current = 3300; curr->requested_voltage = 8700; break; case TEMP_RANGE_1: case TEMP_RANGE_5: default: curr->requested_current = 0; curr->requested_voltage = 0; break; } return 0; }