/* 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