Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
/**
 * Discharge battery when on AC power for factory test.
 */
int board_discharge_on_ac(int enable)
{
	return charger_discharge_on_ac(enable);
}
Exemple #4
0
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;
}