Fix multiple charging issues on snow

This change fixes mutiple snow charging issues. Including:
  - disable i2c host auto selection
  - i2c_read8 got wrong output value
  - pmu CHARGE_EN control workaround

Signed-off-by: Rong Chang <rongchang@chromium.org>
BUG=chrome-os-partner:11010
TEST=Only test on snow dvt with AP turned off
  plug/unplug ac adapter and check charging led
  check console command 'battery'

Change-Id: I29d554b3daa4cfc538bd5bf5ba5233976d381861
Reviewed-on: https://gerrit.chromium.org/gerrit/26529
Tested-by: Rong Chang <rongchang@chromium.org>
Commit-Ready: Rong Chang <rongchang@chromium.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Rong Chang
2012-06-30 17:47:30 +08:00
committed by Gerrit
parent 6900449d0c
commit f429744005
5 changed files with 97 additions and 25 deletions

View File

@@ -44,8 +44,9 @@
/* Charging */
#define CONFIG_SMART_BATTERY
#define CONFIG_PMU_TPS65090
#define CONFIG_I2C_HOST_AUTO
#define I2C_PORT_HOST board_i2c_host_port()
/* #define CONFIG_I2C_HOST_AUTO */
/* #define I2C_PORT_HOST board_i2c_host_port() */
#define I2C_PORT_HOST 1
#define I2C_PORT_BATTERY I2C_PORT_HOST
#define I2C_PORT_CHARGER I2C_PORT_HOST
#define I2C_PORT_SLAVE 1

View File

@@ -621,13 +621,13 @@ int i2c_write16(int port, int slave_addr, int offset, int data)
int i2c_read8(int port, int slave_addr, int offset, int *data)
{
uint8_t reg, buf[2];
uint8_t reg, buf[1];
int rv;
reg = offset & 0xff;
rv = i2c_xfer(port, slave_addr, &reg, 1, buf, 2);
rv = i2c_xfer(port, slave_addr, &reg, 1, buf, 1);
*data = buf[1];
*data = buf[0];
return rv;
}

View File

@@ -29,6 +29,9 @@
#define CG_STATUS1 0x0a
#define CG_STATUS2 0x0b
/* Charger control */
#define CG_CTRL0_EN 1
/* IRQ events */
#define EVENT_VACG (1 << 1)
#define EVENT_VBATG (1 << 3)
@@ -108,6 +111,22 @@ int pmu_get_power_source(int *ac_good, int *battery_good)
return EC_SUCCESS;
}
int pmu_enable_charger(int enable)
{
int rv;
int reg;
rv = pmu_read(CG_CTRL0, &reg);
if (rv)
return rv;
if (reg & CG_CTRL0_EN)
return EC_SUCCESS;
return pmu_write(CG_CTRL0, enable ? (reg | CG_CTRL0_EN) :
(reg & ~CG_CTRL0));
}
void pmu_init(void)
{
/* Init configuration

View File

@@ -55,6 +55,8 @@ static void enable_charging(int enable)
enable = enable ? 1 : 0;
if (gpio_get_level(GPIO_CHARGER_EN) != enable)
gpio_set_level(GPIO_CHARGER_EN, enable);
pmu_enable_charger(enable);
}
@@ -168,45 +170,57 @@ static int notify_battery_low(void)
static int calc_next_state(int state)
{
int batt_temp, alarm, capacity;
int batt_temp, alarm, capacity, charge;
switch (state) {
case ST_IDLE:
/* Turn off charger */
enable_charging(0);
/* Check AC and chiset state */
if (!get_ac()) {
if (chipset_in_state(CHIPSET_STATE_ON))
return ST_DISCHARGING;
return ST_IDLE;
/* Enable charging and wait ac on */
enable_charging(1);
return wait_t1_idle();
}
/* Enable charging when battery doesn't respond */
if (battery_temperature(&batt_temp))
if (battery_temperature(&batt_temp)) {
enable_charging(1);
wait_t1_idle();
return ST_PRE_CHARGING;
}
if (!battery_start_charging_range(batt_temp))
return wait_t1_idle();
if (battery_status(&alarm) || (alarm & ALARM_CHARGING)) {
if (!(alarm & ALARM_TERMINATE_CHARGE))
CPRINTF("[pmu] idle %016b\n", alarm);
/* Turn off charger when battery temperature is out
* of the start charging range.
*/
if (!battery_start_charging_range(batt_temp)) {
enable_charging(0);
return wait_t1_idle();
}
enable_charging(1);
return ST_CHARGING;
/* Turn off charger on battery charging alarm */
if (battery_status(&alarm) || (alarm & ALARM_CHARGING)) {
if (!(alarm & ALARM_TERMINATE_CHARGE))
CPRINTF("[pmu] idle %016b\n", alarm);
enable_charging(0);
return wait_t1_idle();
}
/* Start charging only when battery charge lower than 100% */
if (!battery_state_of_charge(&charge) && charge < 100) {
enable_charging(1);
wait_t1_idle();
return ST_CHARGING;
}
return wait_t1_idle();
case ST_PRE_CHARGING:
if (!get_ac())
return wait_t1_idle();
if (!gpio_get_level(GPIO_CHARGER_EN)) {
CPUTS("[pmu] try charging\n");
enable_charging(1);
}
/* If the battery goes online after enable the charger,
* go into charging state.
*/
@@ -237,7 +251,7 @@ static int calc_next_state(int state)
case ST_DISCHARGING:
if (get_ac())
return ST_IDLE;
return wait_t1_idle();
/* Check battery discharging temperature range */
if (battery_temperature(&batt_temp) == 0) {
@@ -259,7 +273,7 @@ static int calc_next_state(int state)
return wait_t3_discharging();
}
return ST_IDLE;
return wait_t1_idle();
}
void pmu_charger_task(void)

View File

@@ -8,9 +8,47 @@
#ifndef __CROS_EC_TPSCHROME_H
#define __CROS_EC_TPSCHROME_H
#define FET_BACKLIGHT 1
#define FET_LCD_PANEL 6
/**
* Check pmu charger alarm
*
* @return 0 if there's no charging alarm or pmu access failed
* @return 1 if charger over current or over heat
*/
int pmu_is_charger_alarm(void);
/**
* Get pmu power source
*
* @param ac_good pointer to output value of ac voltage good
* @param battery_good pointer to output value of battery voltage good
* @return EC_SUCCESS if ac_good and battery_good are set
*/
int pmu_get_power_source(int *ac_good, int *battery_good);
/**
* Enable/disable pmu fet
*
* @param fet_id the fet to control
* @param enable 0 to disable the fet, 1 to enable
* @param power_good pointer to value of fet power good
* @return EC_SUCCESS if the communication to pmu succeeded
*/
int pmu_enable_fet(int fet_id, int enable, int *power_good);
/**
* Enable/disable pmu internal charger
*
* @param enable 0 to disable the charger, 1 to enable
* @return EC_SUCCESS if no I2C communication error
*/
int pmu_enable_charger(int enable);
/**
* * Initialize pmu
* */
void pmu_init(void);
#endif /* __CROS_EC_TPSCHROME_H */