mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-28 10:45:22 +00:00
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 <wfrichar@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/58466
This commit is contained in:
@@ -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) */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) \
|
||||
|
||||
52
common/battery_falco.c
Normal file
52
common/battery_falco.c
Normal file
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
180
common/charger_bq24738.c
Normal file
180
common/charger_bq24738.c
Normal file
@@ -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);
|
||||
}
|
||||
58
include/charger_bq24738.h
Normal file
58
include/charger_bq24738.h
Normal file
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user