202 lines
5.1 KiB
C
202 lines
5.1 KiB
C
|
/* Copyright 2016 The Chromium OS Authors. All rights reserved.
|
||
|
* Use of this source code is governed by a BSD-style license that can be
|
||
|
* found in the LICENSE file.
|
||
|
*
|
||
|
* Charger profile override for fast charging
|
||
|
*/
|
||
|
|
||
|
#include "charger_profile_override.h"
|
||
|
#include "console.h"
|
||
|
#include "ec_commands.h"
|
||
|
#include "util.h"
|
||
|
|
||
|
#ifdef CONFIG_CMD_CHARGER_PROFILE_OVERRIDE_TEST
|
||
|
static int fast_charge_test_on;
|
||
|
static int test_flag_temp;
|
||
|
static int test_flag_vtg;
|
||
|
static int test_temp_c;
|
||
|
static int test_vtg_mV = -1;
|
||
|
#endif
|
||
|
|
||
|
static int fast_charging_allowed = 1;
|
||
|
|
||
|
int charger_profile_override_common(struct charge_state_data *curr,
|
||
|
const struct fast_charge_params *fast_chg_params,
|
||
|
const struct fast_charge_profile **prev_chg_prof_info,
|
||
|
int batt_vtg_max)
|
||
|
{
|
||
|
int i, voltage_range;
|
||
|
/* temp in 0.1 deg C */
|
||
|
int temp_c = curr->batt.temperature - 2731;
|
||
|
int temp_ranges = fast_chg_params->total_temp_ranges;
|
||
|
const struct fast_charge_profile *chg_profile_info =
|
||
|
fast_chg_params->chg_profile_info;
|
||
|
|
||
|
#ifdef CONFIG_CMD_CHARGER_PROFILE_OVERRIDE_TEST
|
||
|
if (fast_charge_test_on && test_vtg_mV != -1) {
|
||
|
temp_c = TEMPC_TENTHS_OF_DEG(test_temp_c);
|
||
|
curr->batt.voltage = test_vtg_mV;
|
||
|
|
||
|
if (test_flag_temp)
|
||
|
curr->batt.flags |= BATT_FLAG_BAD_TEMPERATURE;
|
||
|
else
|
||
|
curr->batt.flags &= BATT_FLAG_BAD_TEMPERATURE;
|
||
|
|
||
|
if (test_flag_vtg)
|
||
|
curr->batt.flags |= BATT_FLAG_BAD_VOLTAGE;
|
||
|
else
|
||
|
curr->batt.flags &= BATT_FLAG_BAD_VOLTAGE;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* Determine temperature range.
|
||
|
* If temp reading was bad, use last range.
|
||
|
*/
|
||
|
if (!(curr->batt.flags & BATT_FLAG_BAD_TEMPERATURE)) {
|
||
|
while (chg_profile_info && temp_ranges) {
|
||
|
if (temp_c <= chg_profile_info->temp_c) {
|
||
|
*prev_chg_prof_info = chg_profile_info;
|
||
|
break;
|
||
|
}
|
||
|
chg_profile_info++;
|
||
|
temp_ranges--;
|
||
|
}
|
||
|
|
||
|
/* Invalid charge profile selected */
|
||
|
if (!chg_profile_info || !temp_ranges)
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* If the battery voltage reading is bad or the battery voltage is
|
||
|
* greater than or equal to the lower limit or the battery voltage is
|
||
|
* not in the charger profile voltage range, consider battery has high
|
||
|
* voltage range so that we charge at lower current limit.
|
||
|
*/
|
||
|
voltage_range = CONFIG_CHARGER_PROFILE_VOLTAGE_RANGES - 1;
|
||
|
|
||
|
if (!(curr->batt.flags & BATT_FLAG_BAD_VOLTAGE)) {
|
||
|
for (i = 0; i < CONFIG_CHARGER_PROFILE_VOLTAGE_RANGES - 1;
|
||
|
i++) {
|
||
|
if (curr->batt.voltage <
|
||
|
fast_chg_params->voltage_mV[i]) {
|
||
|
voltage_range = i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* 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:
|
||
|
*/
|
||
|
curr->requested_current =
|
||
|
(*prev_chg_prof_info)->current_mA[voltage_range];
|
||
|
curr->requested_voltage = curr->requested_current ? batt_vtg_max : 0;
|
||
|
|
||
|
#ifdef CONFIG_CMD_CHARGER_PROFILE_OVERRIDE_TEST
|
||
|
if (fast_charge_test_on)
|
||
|
ccprintf("Fast charge profile i=%dmA, v=%dmV\n",
|
||
|
curr->requested_current, curr->requested_voltage);
|
||
|
#endif
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* Customs options controllable by host command. */
|
||
|
#define PARAM_FASTCHARGE (CS_PARAM_CUSTOM_PROFILE_MIN + 0)
|
||
|
|
||
|
enum ec_status charger_profile_override_get_param(uint32_t param,
|
||
|
uint32_t *value)
|
||
|
{
|
||
|
if (param == PARAM_FASTCHARGE) {
|
||
|
*value = fast_charging_allowed;
|
||
|
return EC_RES_SUCCESS;
|
||
|
}
|
||
|
return EC_RES_INVALID_PARAM;
|
||
|
}
|
||
|
|
||
|
enum ec_status charger_profile_override_set_param(uint32_t param,
|
||
|
uint32_t value)
|
||
|
{
|
||
|
if (param == PARAM_FASTCHARGE) {
|
||
|
fast_charging_allowed = value;
|
||
|
return EC_RES_SUCCESS;
|
||
|
}
|
||
|
return EC_RES_INVALID_PARAM;
|
||
|
}
|
||
|
|
||
|
#ifdef CONFIG_CMD_CHARGER_PROFILE_OVERRIDE
|
||
|
static int command_fastcharge(int argc, char **argv)
|
||
|
{
|
||
|
if (argc > 1 && !parse_bool(argv[1], &fast_charging_allowed))
|
||
|
return EC_ERROR_PARAM1;
|
||
|
|
||
|
ccprintf("fastcharge %s\n", fast_charging_allowed ? "on" : "off");
|
||
|
|
||
|
return EC_SUCCESS;
|
||
|
}
|
||
|
DECLARE_CONSOLE_COMMAND(fastcharge, command_fastcharge,
|
||
|
"[on|off]",
|
||
|
"Get or set fast charging profile");
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* Manipulate the temperature and voltage values and check if the correct
|
||
|
* fast charging profile is selected.
|
||
|
*/
|
||
|
#ifdef CONFIG_CMD_CHARGER_PROFILE_OVERRIDE_TEST
|
||
|
static int command_fastcharge_test(int argc, char **argv)
|
||
|
{
|
||
|
char *e;
|
||
|
int test_on;
|
||
|
|
||
|
if (argc > 1 && !parse_bool(argv[1], &test_on))
|
||
|
return EC_ERROR_PARAM2;
|
||
|
|
||
|
/* Check if only tuurn printf message on / off */
|
||
|
if (argc == 2) {
|
||
|
fast_charge_test_on = test_on;
|
||
|
test_vtg_mV = -1;
|
||
|
|
||
|
return EC_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* Validate the input parameters */
|
||
|
if ((test_on && argc != 6) || !test_on)
|
||
|
return EC_ERROR_PARAM_COUNT;
|
||
|
|
||
|
test_flag_temp = strtoi(argv[2], &e, 0);
|
||
|
if (*e || test_flag_temp > 1 || test_flag_temp < 0)
|
||
|
return EC_ERROR_PARAM3;
|
||
|
|
||
|
test_flag_vtg = strtoi(argv[3], &e, 0);
|
||
|
if (*e || test_flag_vtg > 1 || test_flag_vtg < 0)
|
||
|
return EC_ERROR_PARAM4;
|
||
|
|
||
|
test_temp_c = strtoi(argv[4], &e, 0);
|
||
|
if (*e)
|
||
|
return EC_ERROR_PARAM5;
|
||
|
|
||
|
test_vtg_mV = strtoi(argv[5], &e, 0);
|
||
|
if (*e || test_vtg_mV < 0) {
|
||
|
test_vtg_mV = -1;
|
||
|
return EC_ERROR_PARAM6;
|
||
|
}
|
||
|
|
||
|
fast_charge_test_on = 1;
|
||
|
|
||
|
return EC_SUCCESS;
|
||
|
}
|
||
|
DECLARE_CONSOLE_COMMAND(fastchgtest, command_fastcharge_test,
|
||
|
"off | on tempflag[1|0] vtgflag[1|0] temp_c vtg_mV",
|
||
|
"Check if fastcharge profile works");
|
||
|
#endif
|