From dcbaa1c80d6aa61da1b526c4cc366fa3ade2e74f Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 12 Jun 2013 16:03:42 -0700 Subject: Falco: Add support for bq24738 charger (and guess at battery). This adds the BQ24738 smart battery charger, and a placeholder for the Falco battery pack. I don't have either documentation or a battery to use to test, so the battery pack stuff is just a guess (see crosbug.com/p/20142). BUG=chrome-os-partner:20098 BRANCH=none TEST=none Well, if you like, from the EC console, run "charger". It should say something like this: > charger Name : bq24738 Option: 1111100100010010 (0xf912) Man id: 0x0040 Dev id: 0x000f V_batt: 0 (1024 - 19200, 16) I_batt: 0 ( 128 - 8128, 64) I_in : 3968 ( 128 - 8064, 128) > But since I don't have either a battery or a spec, I had to guess at the battery configuration. To test the charger, we kind of need a battery. Change-Id: I6e63d6b5aa8be4ba15e2c427d2e86364ef6251b3 Signed-off-by: Bill Richardson Reviewed-on: https://gerrit.chromium.org/gerrit/58466 --- board/falco/board.c | 10 +-- board/falco/board.h | 17 ++++- board/falco/ec.tasklist | 2 +- common/battery_falco.c | 52 ++++++++++++++ common/build.mk | 2 + common/charger_bq24738.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++ include/charger_bq24738.h | 58 +++++++++++++++ 7 files changed, 313 insertions(+), 8 deletions(-) create mode 100644 common/battery_falco.c create mode 100644 common/charger_bq24738.c create mode 100644 include/charger_bq24738.h diff --git a/board/falco/board.c b/board/falco/board.c index 3aa5719915..828e7965a7 100644 --- a/board/falco/board.c +++ b/board/falco/board.c @@ -127,11 +127,13 @@ const struct adc_t adc_channels[ADC_CH_COUNT] = { {"ECTemp", LM4_ADC_SEQ0, -225, ADC_READ_MAX, 420, LM4_AIN_NONE, 0x0e /* TS0 | IE0 | END0 */, 0, 0}, - /* HEY: need different equation for Falco */ - /* Charger current is mapped from 0~4000mA to 0~1.6V. - * And ADC maps 0~3.3V to ADC_READ_MAX. + /* IOUT == ICMNT is on PE3/AIN0 */ + /* We have 0.01-ohm resistors, and IOUT is 20X the differential + * voltage, so 1000mA ==> 200mV. + * ADC returns 0x000-0xFFF, which maps to 0.0-3.3V (as configured). + * mA = 1000 * ADC_VALUE / ADC_READ_MAX * 3300 / 200 */ - {"ChargerCurrent", LM4_ADC_SEQ1, 33 * 4000, ADC_READ_MAX * 16, 0, + {"ChargerCurrent", LM4_ADC_SEQ1, 33000, ADC_READ_MAX * 2, 0, LM4_AIN(0), 0x06 /* IE0 | END0 */, LM4_GPIO_E, (1<<3)}, /* AC Adapter ID voltage (mv) */ diff --git a/board/falco/board.h b/board/falco/board.h index 8ab0fae962..213b965b7e 100644 --- a/board/falco/board.h +++ b/board/falco/board.h @@ -15,9 +15,10 @@ #define CONFIG_TASK_PROFILING /* Optional features */ -/*HEY #define CONFIG_SMART_BATTERY */ -/*HEY #define CONFIG_BATTERY_LINK */ -/*HEY #define CONFIG_CHARGER_BQ24725 */ +#define CONFIG_SMART_BATTERY +#define CONFIG_BATTERY_FALCO +#define CONFIG_CHARGER +#define CONFIG_CHARGER_BQ24738 #ifdef HAS_TASK_CHIPSET #define CONFIG_CHIPSET_X86_HASWELL #endif @@ -141,6 +142,16 @@ enum gpio_signal { GPIO_COUNT }; +/* Charger module */ +/* Set charger input current limit + * Note - this value should depend on external power adapter, + * designed charging voltage, and the maximum power of + * a running system. + */ +#define CONFIG_BQ24738_R_SNS 10 /* 10 mOhm charge sense resistor */ +#define CONFIG_BQ24738_R_AC 10 /* 10 mOhm input current sense resistor */ +#define CONFIG_CHARGER_INPUT_CURRENT 4032 /* mA, about half max */ + enum adc_channel { /* EC internal die temperature in degrees K. */ ADC_CH_EC_TEMP = 0, diff --git a/board/falco/ec.tasklist b/board/falco/ec.tasklist index fa89bc836b..091e8b340e 100644 --- a/board/falco/ec.tasklist +++ b/board/falco/ec.tasklist @@ -19,7 +19,7 @@ #define CONFIG_TASK_LIST \ TASK_ALWAYS(HOOKS, hook_task, NULL, TASK_STACK_SIZE) \ TASK_NOTEST(VBOOTHASH, vboot_hash_task, NULL, LARGER_TASK_STACK_SIZE) \ - /*HEY TASK_ALWAYS(CHARGER, charger_task, NULL, TASK_STACK_SIZE) */ \ + TASK_ALWAYS(CHARGER, charger_task, NULL, TASK_STACK_SIZE) \ TASK_NOTEST(THERMAL, thermal_task, NULL, TASK_STACK_SIZE) \ TASK_NOTEST(CHIPSET, chipset_task, NULL, TASK_STACK_SIZE) \ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, TASK_STACK_SIZE) \ diff --git a/common/battery_falco.c b/common/battery_falco.c new file mode 100644 index 0000000000..a0bf62bf8c --- /dev/null +++ b/common/battery_falco.c @@ -0,0 +1,52 @@ +/* Copyright (c) 2013 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. + * + * Battery pack vendor provided charging profile + */ + +#include "battery_pack.h" + +/* FIXME: We need REAL values for all this stuff */ +static const struct battery_info info = { + + .voltage_max = 8400, + .voltage_normal = 7400, + .voltage_min = 6000, + + /* + * Operational temperature range + * 0 <= T_charge <= 50 deg C + * -20 <= T_discharge <= 60 deg C + */ + .temp_charge_min = CELSIUS_TO_DECI_KELVIN(0), + .temp_charge_max = CELSIUS_TO_DECI_KELVIN(50), + .temp_discharge_min = CELSIUS_TO_DECI_KELVIN(-20), + .temp_discharge_max = CELSIUS_TO_DECI_KELVIN(60), + + /* Pre-charge values. */ + .precharge_current = 256, /* mA */ +}; + +const struct battery_info *battery_get_info(void) +{ + return &info; +} + +/* FIXME: The smart battery should do the right thing - that's why it's + * called "smart". Do we really want to second-guess it? For now, let's not. */ +void battery_vendor_params(struct batt_params *batt) +{ +#if 0 + /* Limit charging voltage */ + if (batt->desired_voltage > info.voltage_max) + batt->desired_voltage = info.voltage_max; + + /* Don't charge if outside of allowable temperature range */ + if (batt->temperature >= info.temp_charge_max || + batt->temperature <= info.temp_charge_min) { + batt->desired_voltage = 0; + batt->desired_current = 0; + } +#endif +} diff --git a/common/build.mk b/common/build.mk index 5981790e4c..d62826dd49 100644 --- a/common/build.mk +++ b/common/build.mk @@ -12,10 +12,12 @@ common-y+=gpio_common.o version.o printf.o queue.o common-$(CONFIG_BATTERY_BQ20Z453)+=battery_bq20z453.o common-$(CONFIG_BATTERY_LINK)+=battery_link.o common-$(CONFIG_BATTERY_SLIPPY)+=battery_slippy.o +common-$(CONFIG_BATTERY_FALCO)+=battery_slippy.o common-$(CONFIG_BATTERY_SPRING)+=battery_spring.o common-$(CONFIG_CHARGER)+=charge_state.o battery_precharge.o charger_common.o common-$(CONFIG_CHARGER_BQ24725)+=charger_bq24725.o common-$(CONFIG_CHARGER_BQ24707A)+=charger_bq24707a.o +common-$(CONFIG_CHARGER_BQ24738)+=charger_bq24738.o common-$(CONFIG_CHARGER_TPS65090)+=pmu_tps65090_charger.o common-$(CONFIG_CHIPSET_GAIA)+=gaia_power.o common-$(CONFIG_CHIPSET_X86_IVYBRIDGE)+=x86_power_ivybridge.o diff --git a/common/charger_bq24738.c b/common/charger_bq24738.c new file mode 100644 index 0000000000..601826f22a --- /dev/null +++ b/common/charger_bq24738.c @@ -0,0 +1,180 @@ +/* Copyright (c) 2013 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. + * + * TI bq24738 battery charger driver. + */ + +#include "charger.h" +#include "charger_bq24738.h" +#include "console.h" +#include "common.h" +#include "i2c.h" +#include "smart_battery.h" +#include "util.h" + +/* Sense resistor configurations and macros */ +#define DEFAULT_SENSE_RESISTOR 10 +#define R_SNS CONFIG_BQ24738_R_SNS +#define R_AC CONFIG_BQ24738_R_AC +#define REG_TO_CURRENT(REG, RS) ((REG) * DEFAULT_SENSE_RESISTOR / (RS)) +#define CURRENT_TO_REG(CUR, RS) ((CUR) * (RS) / DEFAULT_SENSE_RESISTOR) + +/* Charger infomation + * charge voltage bitmask: 0111 1111 1111 0000 + * charge current bitmask: 0001 1111 1100 0000 + * input current bitmask : 0000 0000 1000 0000 + */ +static const struct charger_info bq24738_charger_info = { + .name = "bq24738", + .voltage_max = 19200, + .voltage_min = 1024, + .voltage_step = 16, + .current_max = REG_TO_CURRENT(8128, R_SNS), + .current_min = REG_TO_CURRENT(128, R_SNS), + .current_step = REG_TO_CURRENT(64, R_SNS), + .input_current_max = REG_TO_CURRENT(8064, R_AC), + .input_current_min = REG_TO_CURRENT(128, R_AC), + .input_current_step = REG_TO_CURRENT(128, R_AC), +}; + +/* bq24738 specific interfaces */ + +int charger_set_input_current(int input_current) +{ + return sbc_write(BQ24738_INPUT_CURRENT, + CURRENT_TO_REG(input_current, R_AC)); +} + +int charger_get_input_current(int *input_current) +{ + int rv; + int reg; + + rv = sbc_read(BQ24738_INPUT_CURRENT, ®); + if (rv) + return rv; + + *input_current = REG_TO_CURRENT(reg, R_AC); + + return EC_SUCCESS; +} + +int charger_manufacturer_id(int *id) +{ + return sbc_read(BQ24738_MANUFACTURE_ID, id); +} + +int charger_device_id(int *id) +{ + return sbc_read(BQ24738_DEVICE_ID, id); +} + +int charger_get_option(int *option) +{ + return sbc_read(BQ24738_CHARGE_OPTION, option); +} + +int charger_set_option(int option) +{ + return sbc_write(BQ24738_CHARGE_OPTION, option); +} + +/* Charger interfaces */ + +const struct charger_info *charger_get_info(void) +{ + return &bq24738_charger_info; +} + +int charger_get_status(int *status) +{ + int rv; + int option; + + rv = charger_get_option(&option); + if (rv) + return rv; + + /* Default status */ + *status = CHARGER_LEVEL_2; + + if (option & OPTION_CHARGE_INHIBIT) + *status |= CHARGER_CHARGE_INHIBITED; + + return EC_SUCCESS; +} + +int charger_set_mode(int mode) +{ + int rv; + int option; + + rv = charger_get_option(&option); + if (rv) + return rv; + + if (mode & CHARGE_FLAG_INHIBIT_CHARGE) + option |= OPTION_CHARGE_INHIBIT; + else + option &= ~OPTION_CHARGE_INHIBIT; + return charger_set_option(option); +} + +int charger_get_current(int *current) +{ + int rv; + int reg; + + rv = sbc_read(SB_CHARGING_CURRENT, ®); + if (rv) + return rv; + + *current = REG_TO_CURRENT(reg, R_SNS); + return EC_SUCCESS; +} + +int charger_closest_current(int current) +{ + const struct charger_info * const info = charger_get_info(); + + /* + * If the requested current is non-zero but below our minimum, + * return the minimum. See crosbug.com/p/8662. + */ + if (current > 0 && current < info->current_min) + return info->current_min; + + /* Clip to max */ + if (current > info->current_max) + return info->current_max; + + /* Otherwise round down to nearest current step */ + return current - (current % info->current_step); +} + +int charger_set_current(int current) +{ + current = charger_closest_current(current); + + return sbc_write(SB_CHARGING_CURRENT, CURRENT_TO_REG(current, R_SNS)); +} + +int charger_get_voltage(int *voltage) +{ + return sbc_read(SB_CHARGING_VOLTAGE, voltage); +} + +int charger_set_voltage(int voltage) +{ + return sbc_write(SB_CHARGING_VOLTAGE, voltage); +} + +/* Charging power state initialization */ +int charger_post_init(void) +{ + /* Accept POR defaults, plus... */ + + /* Set charger input current limit */ + return charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT); +} diff --git a/include/charger_bq24738.h b/include/charger_bq24738.h new file mode 100644 index 0000000000..09336c9cb3 --- /dev/null +++ b/include/charger_bq24738.h @@ -0,0 +1,58 @@ +/* Copyright (c) 2013 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. + * + * TI bq24738 battery charger driver. + */ + +#ifndef __CROS_EC_CHARGER_BQ24738_H +#define __CROS_EC_CHARGER_BQ24738_H + +/* Chip specific commands */ +#define BQ24738_CHARGE_OPTION 0x12 +#define BQ24738_INPUT_CURRENT 0x3f +#define BQ24738_MANUFACTURE_ID 0xfe +#define BQ24738_DEVICE_ID 0xff + +/* ChargeOption 0x12 */ +#define OPTION_CHARGE_INHIBIT (1 << 0) +#define OPTION_ACOC_THRESHOLD (1 << 1) +#define OPTION_BOOST_MODE_STATE (1 << 2) +#define OPTION_BOOST_MODE_ENABLE (1 << 3) +#define OPTION_ACDET_STATE (1 << 4) +#define OPTION_IOUT_SELECTION (1 << 5) +#define OPTION_LEARN_ENABLE (1 << 6) +#define OPTION_IFAULT_LOW_THRESHOLD (1 << 7) +#define OPTION_IFAULT_HI_ENABLE (1 << 8) +#define OPTION_EMI_FREQ_ENABLE (1 << 9) +#define OPTION_EMI_FREQ_ADJ (1 << 10) +#define OPTION_BAT_DEPLETION_THRESHOLD (3 << 11) +#define OPTION_WATCHDOG_TIMER (3 << 13) +#define OPTION_ACPRES_DEGLITCH_TIME (1 << 15) + +/* OPTION_ACOC_THRESHOLD */ +#define ACOC_THRESHOLD_DISABLE (0 << 1) +#define ACOC_THRESHOLD_133X (1 << 1) + +/* OPTION_IFAULT_LOW_THRESHOLD */ +#define IFAULT_LOW_135MV_DEFAULT (0 << 7) +#define IFAULT_LOW_230MV (1 << 7) + +/* OPTION_BAT_DEPLETION_THRESHOLD */ +#define FALLING_THRESHOLD_5919 (0 << 11) +#define FALLING_THRESHOLD_6265 (1 << 11) +#define FALLING_THRESHOLD_6655 (2 << 11) +#define FALLING_THRESHOLD_7097_DEFAULT (3 << 11) + +/* OPTION_WATCHDOG_TIMER */ +#define CHARGE_WATCHDOG_DISABLE (0 << 13) +#define CHARGE_WATCHDOG_44SEC (1 << 13) +#define CHARGE_WATCHDOG_88SEC (2 << 13) +#define CHARGE_WATCHDOG_175SEC_DEFAULT (3 << 13) + +/* OPTION_ACPRES_DEGLITCH_TIME */ +#define ACPRES_DEGLITCH_150MS (0 << 15) +#define ACPRES_DEGLITCH_1300MS_DEFAULT (1 << 15) + +#endif /* __CROS_EC_CHARGER_BQ24738_H */ + -- cgit v1.2.1