Files
OpenCellular/board/samus/extpower.c
Alec Berg ee5dbe94a0 samus: fix tap for battery doesn't work in G3 with AC
Fix bug causing tap for battery not to work in G3 when AC
is attached. Problem was that the lightbar was being held
in reset and would not light up.

BUG=chrome-os-partner:34722
BRANCH=samus
TEST=tested on samus with AC attached and unattached in S3
and in G3, tap for battery lights up the lightbar. Also
verified that plugging and unpluggin AC in S3 and G3 causes
lightbar to light up.

Change-Id: I0fbd989399d372d287467200512bbdf2551884d3
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/236560
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
2014-12-18 21:40:50 +00:00

113 lines
2.7 KiB
C

/* 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.
*/
/*
* Pure GPIO-based external power detection, buffered to PCH.
* Drive high in S5-S0 when AC_PRESENT is high, otherwise drive low.
*/
#include "charger.h"
#include "chipset.h"
#include "common.h"
#include "extpower.h"
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
#include "task.h"
int extpower_is_present(void)
{
return gpio_get_level(GPIO_AC_PRESENT);
}
static void extpower_buffer_to_pch(void)
{
if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) {
/* Drive low in G3 state */
gpio_set_level(GPIO_PCH_ACOK, 0);
} else {
/* Buffer from extpower in S5+ (where 3.3DSW enabled) */
gpio_set_level(GPIO_PCH_ACOK, extpower_is_present());
}
}
DECLARE_HOOK(HOOK_CHIPSET_PRE_INIT, extpower_buffer_to_pch, HOOK_PRIO_DEFAULT);
static void extpower_shutdown(void)
{
/* Drive ACOK buffer to PCH low when shutting down */
gpio_set_level(GPIO_PCH_ACOK, 0);
}
DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, extpower_shutdown, HOOK_PRIO_DEFAULT);
void extpower_interrupt(enum gpio_signal signal)
{
extpower_buffer_to_pch();
/* Trigger notification of external power change */
task_wake(TASK_ID_EXTPOWER);
}
static void extpower_init(void)
{
extpower_buffer_to_pch();
/* Enable interrupts, now that we've initialized */
gpio_enable_interrupt(GPIO_AC_PRESENT);
}
DECLARE_HOOK(HOOK_INIT, extpower_init, HOOK_PRIO_DEFAULT);
static void extpower_board_hacks(int extpower)
{
static int extpower_prev;
/*
* Use discharge_on_ac() to workaround hardware backboosting
* charge circuit problems.
*
* When in G3, PP5000 needs to be enabled to accurately sense
* CC voltage when AC is attached. When AC is disconnceted
* it needs to be off to save power.
*/
if (extpower && !extpower_prev) {
charger_discharge_on_ac(0);
set_pp5000_in_g3(PP5000_IN_G3_AC, 1);
} else if (extpower && extpower_prev) {
/* Glitch on AC_PRESENT, attempt to recover from backboost */
charger_discharge_on_ac(1);
charger_discharge_on_ac(0);
} else {
charger_discharge_on_ac(1);
set_pp5000_in_g3(PP5000_IN_G3_AC, 0);
}
extpower_prev = extpower;
}
/**
* Task to handle external power change
*/
void extpower_task(void)
{
int extpower = extpower_is_present();
extpower_board_hacks(extpower);
while (1) {
/* Wait until next extpower interrupt */
task_wait_event(-1);
extpower = extpower_is_present();
/* Various board hacks to run on extpower change */
extpower_board_hacks(extpower);
hook_notify(HOOK_AC_CHANGE);
/* Forward notification to host */
if (extpower)
host_set_single_event(EC_HOST_EVENT_AC_CONNECTED);
else
host_set_single_event(EC_HOST_EVENT_AC_DISCONNECTED);
}
}