cleanup: Remove big and pit boards
Remove big and pit boards along with several now-obsolete CONFIGs /
source files.
Conflicts:
board/big/board.h
board/pit/board.h
include/config.h
BUG=chromium:735109
TEST=`make buildall -j`
BRANCH=None
CQ-DEPEND=CL:544681
Change-Id: Ieb784bd36157fd1f6240cd19de6e6d12191a8097
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/540667
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
(cherry picked from commit b0dd82b39c
)
Reviewed-on: https://chromium-review.googlesource.com/660889
Commit-Queue: Vadim Bendebury <vbendeb@chromium.org>
Tested-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
This commit is contained in:
parent
56fac9fcd8
commit
3447ba9406
|
@ -1,216 +0,0 @@
|
|||
/* 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.h"
|
||||
#include "battery_smart.h"
|
||||
#include "gpio.h"
|
||||
#include "host_command.h"
|
||||
#include "util.h"
|
||||
#include "console.h"
|
||||
|
||||
/* Console output macros */
|
||||
#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args)
|
||||
|
||||
/* These 2 defines are for cut_off command for 3S battery */
|
||||
#define SB_SHIP_MODE_ADDR 0x3a
|
||||
#define SB_SHIP_MODE_DATA 0xc574
|
||||
|
||||
static struct battery_info *battery_info;
|
||||
static int support_cut_off;
|
||||
|
||||
struct battery_device {
|
||||
char manuf[9];
|
||||
char device[9];
|
||||
int design_mv;
|
||||
struct battery_info *battery_info;
|
||||
int support_cut_off;
|
||||
};
|
||||
|
||||
/*
|
||||
* Used for the case that battery cannot be detected, such as the pre-charge
|
||||
* case. In this case, we need to provide the battery with the enough voltage
|
||||
* (usually the highest voltage among batteries, but the smallest precharge
|
||||
* current). This should be as conservative as possible.
|
||||
*/
|
||||
static struct battery_info info_precharge = {
|
||||
|
||||
.voltage_max = 12900, /* the max voltage among batteries */
|
||||
.voltage_normal = 11400,
|
||||
.voltage_min = 9000,
|
||||
|
||||
/* Pre-charge values. */
|
||||
.precharge_current = 256, /* mA, the min current among batteries */
|
||||
|
||||
.start_charging_min_c = 0,
|
||||
.start_charging_max_c = 50,
|
||||
.charging_min_c = 0,
|
||||
.charging_max_c = 60,
|
||||
.discharging_min_c = 0,
|
||||
.discharging_max_c = 75,
|
||||
};
|
||||
|
||||
static struct battery_info info_2s = {
|
||||
/*
|
||||
* Design voltage
|
||||
* max = 8.4V
|
||||
* normal = 7.4V
|
||||
* min = 6.0V
|
||||
*/
|
||||
.voltage_max = 8400,
|
||||
.voltage_normal = 7400,
|
||||
.voltage_min = 6000,
|
||||
|
||||
/* Pre-charge current: I <= 0.01C */
|
||||
.precharge_current = 64, /* mA */
|
||||
|
||||
/*
|
||||
* Operational temperature range
|
||||
* 0 <= T_charge <= 50 deg C
|
||||
* -20 <= T_discharge <= 60 deg C
|
||||
*/
|
||||
.start_charging_min_c = 0,
|
||||
.start_charging_max_c = 50,
|
||||
.charging_min_c = 0,
|
||||
.charging_max_c = 50,
|
||||
.discharging_min_c = -20,
|
||||
.discharging_max_c = 60,
|
||||
};
|
||||
|
||||
static struct battery_info info_3s = {
|
||||
|
||||
.voltage_max = 12600,
|
||||
.voltage_normal = 11100, /* Average of max & min */
|
||||
.voltage_min = 9000,
|
||||
|
||||
/* Pre-charge values. */
|
||||
.precharge_current = 392, /* mA */
|
||||
|
||||
.start_charging_min_c = 0,
|
||||
.start_charging_max_c = 60,
|
||||
.charging_min_c = 0,
|
||||
.charging_max_c = 60,
|
||||
.discharging_min_c = 0,
|
||||
.discharging_max_c = 50,
|
||||
};
|
||||
|
||||
static struct battery_info info_3s_LGC = {
|
||||
|
||||
.voltage_max = 12900,
|
||||
.voltage_normal = 11400, /* Average of max & min */
|
||||
.voltage_min = 9000,
|
||||
|
||||
/* Pre-charge values. */
|
||||
.precharge_current = 256, /* mA */
|
||||
|
||||
.start_charging_min_c = 0,
|
||||
.start_charging_max_c = 50,
|
||||
.charging_min_c = 0,
|
||||
.charging_max_c = 60,
|
||||
.discharging_min_c = 0,
|
||||
.discharging_max_c = 75,
|
||||
};
|
||||
|
||||
static struct battery_info info_4s_LGC = {
|
||||
|
||||
.voltage_max = 17200,
|
||||
.voltage_normal = 15200, /* Average of max & min */
|
||||
.voltage_min = 12000,
|
||||
|
||||
/* Pre-charge values. */
|
||||
.precharge_current = 256, /* mA */
|
||||
|
||||
.start_charging_min_c = 0,
|
||||
.start_charging_max_c = 50,
|
||||
.charging_min_c = 0,
|
||||
.charging_max_c = 60,
|
||||
.discharging_min_c = 0,
|
||||
.discharging_max_c = 75,
|
||||
};
|
||||
|
||||
static struct battery_device support_batteries[] = {
|
||||
{
|
||||
.manuf = "NVT",
|
||||
.device = "ARROW",
|
||||
.design_mv = 7400,
|
||||
.battery_info = &info_2s,
|
||||
.support_cut_off = 0,
|
||||
},
|
||||
{
|
||||
.manuf = "SANYO",
|
||||
.device = "AP13J3K",
|
||||
.design_mv = 11250,
|
||||
.battery_info = &info_3s,
|
||||
.support_cut_off = 1,
|
||||
},
|
||||
{
|
||||
.manuf = "SONYCorp",
|
||||
.device = "AP13J4K",
|
||||
.design_mv = 11400,
|
||||
.battery_info = &info_3s,
|
||||
.support_cut_off = 1,
|
||||
},
|
||||
{
|
||||
.manuf = "LGC",
|
||||
.device = "AC14B8K",
|
||||
.design_mv = 15200,
|
||||
.battery_info = &info_4s_LGC,
|
||||
.support_cut_off = 1,
|
||||
},
|
||||
{
|
||||
.manuf = "LGC",
|
||||
.device = "AC14B18J",
|
||||
.design_mv = 11400,
|
||||
.battery_info = &info_3s_LGC,
|
||||
.support_cut_off = 1,
|
||||
},
|
||||
};
|
||||
|
||||
const struct battery_info *battery_get_info(void)
|
||||
{
|
||||
int i;
|
||||
char manuf[9];
|
||||
char device[9];
|
||||
int design_mv;
|
||||
|
||||
if (battery_manufacturer_name(manuf, sizeof(manuf))) {
|
||||
CPRINTS("Failed to get MANUF name");
|
||||
return &info_precharge;
|
||||
}
|
||||
|
||||
if (battery_device_name(device, sizeof(device))) {
|
||||
CPRINTS("Failed to get DEVICE name");
|
||||
return &info_precharge;
|
||||
}
|
||||
if (battery_design_voltage((int *)&design_mv)) {
|
||||
CPRINTS("Failed to get DESIGN_VOLTAGE");
|
||||
return &info_precharge;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(support_batteries); ++i) {
|
||||
if ((strcasecmp(support_batteries[i].manuf, manuf) == 0) &&
|
||||
(strcasecmp(support_batteries[i].device, device) == 0) &&
|
||||
(support_batteries[i].design_mv == design_mv)) {
|
||||
CPRINTS("battery Manuf:%s, Device=%s, design=%u",
|
||||
manuf, device, design_mv);
|
||||
support_cut_off = support_batteries[i].support_cut_off;
|
||||
battery_info = support_batteries[i].battery_info;
|
||||
return battery_info;
|
||||
}
|
||||
}
|
||||
|
||||
CPRINTS("un-recognized battery Manuf:%s, Device:%s",
|
||||
manuf, device);
|
||||
return &info_precharge;
|
||||
}
|
||||
|
||||
int board_cut_off_battery(void)
|
||||
{
|
||||
if (support_cut_off)
|
||||
return sb_write(SB_SHIP_MODE_ADDR, SB_SHIP_MODE_DATA);
|
||||
else
|
||||
return EC_RES_INVALID_COMMAND;
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/* Copyright (c) 2014 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.
|
||||
*/
|
||||
/* Big board-specific configuration */
|
||||
|
||||
#include "battery.h"
|
||||
#include "chipset.h"
|
||||
#include "common.h"
|
||||
#include "extpower.h"
|
||||
#include "gpio.h"
|
||||
#include "i2c.h"
|
||||
#include "keyboard_raw.h"
|
||||
#include "lid_switch.h"
|
||||
#include "power.h"
|
||||
#include "power_button.h"
|
||||
#include "power.h"
|
||||
#include "pwm.h"
|
||||
#include "pwm_chip.h"
|
||||
#include "registers.h"
|
||||
#include "spi.h"
|
||||
#include "task.h"
|
||||
#include "util.h"
|
||||
#include "timer.h"
|
||||
#include "charger.h"
|
||||
#include "gpio_list.h"
|
||||
|
||||
/* power signal list. Must match order of enum power_signal. */
|
||||
const struct power_signal_info power_signal_list[] = {
|
||||
{GPIO_SOC1V8_XPSHOLD, 1, "XPSHOLD"},
|
||||
{GPIO_SUSPEND_L, 0, "SUSPEND#_ASSERTED"},
|
||||
};
|
||||
BUILD_ASSERT(ARRAY_SIZE(power_signal_list) == POWER_SIGNAL_COUNT);
|
||||
|
||||
/* I2C ports */
|
||||
const struct i2c_port_t i2c_ports[] = {
|
||||
{"master", I2C_PORT_MASTER, 100},
|
||||
};
|
||||
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
|
||||
|
||||
/* PWM channels. Must be in the exactly same order as in enum pwm_channel. */
|
||||
const struct pwm_t pwm_channels[] = {
|
||||
{STM32_TIM(2), STM32_TIM_CH(3), PWM_CONFIG_ACTIVE_LOW},
|
||||
};
|
||||
BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
|
|
@ -1,79 +0,0 @@
|
|||
/* Copyright (c) 2014 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.
|
||||
*/
|
||||
|
||||
/* Big board configuration */
|
||||
|
||||
#ifndef __CROS_EC_BOARD_H
|
||||
#define __CROS_EC_BOARD_H
|
||||
|
||||
/* Optional features */
|
||||
#define CONFIG_AP_HANG_DETECT
|
||||
#define CONFIG_BATTERY_SMART
|
||||
#define CONFIG_BATTERY_CUT_OFF
|
||||
#define CONFIG_CHARGER
|
||||
#define CONFIG_CHARGER_V2
|
||||
#define CONFIG_CHARGER_BQ24735
|
||||
#define CONFIG_CHIPSET_TEGRA
|
||||
#define CONFIG_POWER_COMMON
|
||||
#define CONFIG_EXTPOWER_GPIO
|
||||
#define CONFIG_HOST_COMMAND_STATUS
|
||||
#define CONFIG_I2C
|
||||
#define CONFIG_I2C_MASTER
|
||||
#define CONFIG_KEYBOARD_PROTOCOL_MKBP
|
||||
#define CONFIG_SPI
|
||||
#define CONFIG_SPI_PROTOCOL_V2
|
||||
#define CONFIG_PWM
|
||||
#define CONFIG_POWER_BUTTON
|
||||
#define CONFIG_VBOOT_HASH
|
||||
#define CONFIG_LED_COMMON
|
||||
#define CONFIG_CHARGER_DISCHARGE_ON_AC
|
||||
#undef CONFIG_CONSOLE_CMDHELP
|
||||
#undef CONFIG_CMD_BATTFAKE
|
||||
#define CONFIG_LTO
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/* Keyboard output port list */
|
||||
#define KB_OUT_PORT_LIST GPIO_A, GPIO_B, GPIO_C
|
||||
|
||||
/* Single I2C port, where the EC is the master. */
|
||||
#define I2C_PORT_MASTER 0
|
||||
#define I2C_PORT_BATTERY I2C_PORT_MASTER
|
||||
#define I2C_PORT_CHARGER I2C_PORT_MASTER
|
||||
|
||||
/* Timer selection */
|
||||
#define TIM_CLOCK_MSB 3
|
||||
#define TIM_CLOCK_LSB 9
|
||||
#define TIM_POWER_LED 2
|
||||
#define TIM_WATCHDOG 4
|
||||
|
||||
#include "gpio_signal.h"
|
||||
|
||||
enum power_signal {
|
||||
TEGRA_XPSHOLD = 0,
|
||||
TEGRA_SUSPEND_ASSERTED,
|
||||
|
||||
/* Number of power signals */
|
||||
POWER_SIGNAL_COUNT
|
||||
};
|
||||
|
||||
enum pwm_channel {
|
||||
PWM_CH_POWER_LED = 0,
|
||||
/* Number of PWM channels */
|
||||
PWM_CH_COUNT
|
||||
};
|
||||
|
||||
/* Charger module */
|
||||
#define CONFIG_CHARGER_SENSE_RESISTOR 10 /* Charge sense resistor, mOhm */
|
||||
#define CONFIG_CHARGER_SENSE_RESISTOR_AC 20 /* Input sensor resistor, mOhm */
|
||||
/* Input current limit for 45W AC adapter:
|
||||
* 45W/19V*85%=2013mA, choose the closest charger setting = 2048mA
|
||||
*/
|
||||
#define CONFIG_CHARGER_INPUT_CURRENT 2048 /* mA, based on Link HW design */
|
||||
#define CONFIG_CHARGER_CURRENT_LIMIT 3000 /* PL102 inductor 3.0A(3.8A) */
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
#endif /* __CROS_EC_BOARD_H */
|
|
@ -1,13 +0,0 @@
|
|||
# -*- makefile -*-
|
||||
# Copyright (c) 2014 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.
|
||||
#
|
||||
# Board specific files build
|
||||
|
||||
# the IC is STmicro STM32L100RBT6
|
||||
CHIP:=stm32
|
||||
CHIP_FAMILY:=stm32l
|
||||
CHIP_VARIANT:=stm32l100
|
||||
|
||||
board-y=board.o battery.o led.o
|
|
@ -1,23 +0,0 @@
|
|||
/* Copyright (c) 2014 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* List of enabled tasks in the priority order
|
||||
*
|
||||
* The first one has the lowest priority.
|
||||
*
|
||||
* For each task, use the macro TASK(n, r, d, s) where :
|
||||
* 'n' in the name of the task
|
||||
* 'r' in the main routine of the task
|
||||
* 'd' in an opaque parameter passed to the routine at startup
|
||||
* 's' is the stack size in bytes; must be a multiple of 8
|
||||
*/
|
||||
#define CONFIG_TASK_LIST \
|
||||
TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \
|
||||
TASK_ALWAYS(CHARGER, charger_task, NULL, LARGER_TASK_STACK_SIZE) \
|
||||
TASK_NOTEST(CHIPSET, chipset_task, NULL, LARGER_TASK_STACK_SIZE) \
|
||||
TASK_ALWAYS(HOSTCMD, host_command_task, NULL, TASK_STACK_SIZE) \
|
||||
TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE) \
|
||||
TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, TASK_STACK_SIZE)
|
|
@ -1,68 +0,0 @@
|
|||
/* -*- mode:c -*-
|
||||
*
|
||||
* Copyright (c) 2014 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.
|
||||
*/
|
||||
|
||||
/* Declare symbolic names for all the GPIOs that we care about.
|
||||
* Note: Those with interrupt handlers must be declared first. */
|
||||
|
||||
#define GPIO_KB_INPUT (GPIO_INPUT | GPIO_PULL_UP | GPIO_INT_BOTH)
|
||||
#define GPIO_KB_OUTPUT GPIO_ODR_HIGH
|
||||
|
||||
GPIO_INT(POWER_BUTTON_L, PIN(B, 5), GPIO_INT_BOTH, power_button_interrupt)
|
||||
GPIO_INT(SOC1V8_XPSHOLD, PIN(A, 3), GPIO_INT_BOTH, power_signal_interrupt)
|
||||
GPIO_INT(LID_OPEN, PIN(C, 13), GPIO_INT_BOTH, lid_interrupt)
|
||||
GPIO_INT(SUSPEND_L, PIN(C, 7), GPIO_KB_INPUT, power_signal_interrupt)
|
||||
GPIO_INT(SPI1_NSS, PIN(A, 4), GPIO_INT_BOTH | GPIO_PULL_UP, spi_event)
|
||||
GPIO_INT(AC_PRESENT, PIN(A, 0), GPIO_INT_BOTH, extpower_interrupt)
|
||||
|
||||
/* Keyboard inputs */
|
||||
GPIO_INT(KB_IN00, PIN(C, 8), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
GPIO_INT(KB_IN01, PIN(C, 9), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
GPIO_INT(KB_IN02, PIN(C, 10), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
GPIO_INT(KB_IN03, PIN(C, 11), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
GPIO_INT(KB_IN04, PIN(C, 12), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
GPIO_INT(KB_IN05, PIN(C, 14), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
GPIO_INT(KB_IN06, PIN(C, 15), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
GPIO_INT(KB_IN07, PIN(D, 2), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
|
||||
/* Other inputs */
|
||||
GPIO(WP_L, PIN(B, 4), GPIO_INPUT)
|
||||
|
||||
/* Outputs */
|
||||
GPIO(AP_RESET_L, PIN(B, 3), GPIO_ODR_HIGH)
|
||||
GPIO(CHARGER_EN, PIN(B, 2), GPIO_OUT_LOW)
|
||||
GPIO(EC_INT_L, PIN(B, 9), GPIO_ODR_HIGH)
|
||||
GPIO(ENTERING_RW, PIN(H, 0), GPIO_OUT_LOW)
|
||||
GPIO(I2C1_SCL, PIN(B, 6), GPIO_ODR_HIGH)
|
||||
GPIO(I2C1_SDA, PIN(B, 7), GPIO_ODR_HIGH)
|
||||
GPIO(LED_POWER_L, PIN(A, 2), GPIO_OUT_HIGH) /* PWR_LED1 */
|
||||
GPIO(PMIC_PWRON_L, PIN(A, 12), GPIO_OUT_HIGH)
|
||||
GPIO(PMIC_RESET, PIN(A, 15), GPIO_OUT_LOW)
|
||||
GPIO(KB_OUT00, PIN(B, 0), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT01, PIN(B, 8), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT02, PIN(B, 12), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT03, PIN(B, 13), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT04, PIN(B, 14), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT05, PIN(B, 15), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT06, PIN(C, 0), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT07, PIN(C, 1), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT08, PIN(C, 2), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT09, PIN(B, 1), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT10, PIN(C, 5), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT11, PIN(C, 4), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT12, PIN(A, 13), GPIO_KB_OUTPUT)
|
||||
GPIO(PWR_LED0, PIN(B, 10), GPIO_OUT_LOW)
|
||||
GPIO(BAT_LED0, PIN(B, 11), GPIO_OUT_LOW)
|
||||
GPIO(BAT_LED1, PIN(A, 8), GPIO_OUT_LOW)
|
||||
GPIO(CHARGING, PIN(A, 11), GPIO_OUT_LOW)
|
||||
GPIO(EC_BL_OVERRIDE, PIN(H, 1), GPIO_ODR_HIGH)
|
||||
GPIO(PMIC_THERM_L, PIN(A, 1), GPIO_ODR_HIGH)
|
||||
GPIO(PMIC_WARM_RESET_L, PIN(C, 3), GPIO_ODR_HIGH)
|
||||
|
||||
ALTERNATE(PIN_MASK(A, 0x0004), GPIO_ALT_TIM2, MODULE_PWM, GPIO_DEFAULT)
|
||||
ALTERNATE(PIN_MASK(A, 0x00f0), GPIO_ALT_SPI, MODULE_SPI, GPIO_DEFAULT)
|
||||
ALTERNATE(PIN_MASK(A, 0x0600), GPIO_ALT_USART, MODULE_UART, GPIO_DEFAULT)
|
||||
ALTERNATE(PIN_MASK(B, 0x00c0), GPIO_ALT_I2C, MODULE_I2C, GPIO_DEFAULT)
|
179
board/big/led.c
179
board/big/led.c
|
@ -1,179 +0,0 @@
|
|||
/* Copyright (c) 2014 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 LED and Power LED control for Big
|
||||
*/
|
||||
|
||||
#include "gpio.h"
|
||||
#include "hooks.h"
|
||||
#include "battery.h"
|
||||
#include "charge_state.h"
|
||||
#include "chipset.h"
|
||||
#include "led_common.h"
|
||||
#include "util.h"
|
||||
|
||||
const enum ec_led_id supported_led_ids[] = {
|
||||
EC_LED_ID_BATTERY_LED, EC_LED_ID_POWER_LED};
|
||||
|
||||
const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
|
||||
|
||||
enum led_color {
|
||||
LED_OFF = 0,
|
||||
LED_BLUE,
|
||||
LED_ORANGE,
|
||||
LED_COLOR_COUNT /* Number of colors, not a color itself */
|
||||
};
|
||||
|
||||
static int bat_led_set_color(enum led_color color)
|
||||
{
|
||||
switch (color) {
|
||||
case LED_OFF:
|
||||
gpio_set_level(GPIO_CHARGING, 0);
|
||||
gpio_set_level(GPIO_BAT_LED1, 0);
|
||||
break;
|
||||
case LED_BLUE:
|
||||
gpio_set_level(GPIO_CHARGING, 0);
|
||||
gpio_set_level(GPIO_BAT_LED1, 1);
|
||||
break;
|
||||
case LED_ORANGE:
|
||||
gpio_set_level(GPIO_CHARGING, 1);
|
||||
gpio_set_level(GPIO_BAT_LED1, 0);
|
||||
break;
|
||||
default:
|
||||
return EC_ERROR_UNKNOWN;
|
||||
}
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
static int pwr_led_set_color(enum led_color color)
|
||||
{
|
||||
switch (color) {
|
||||
case LED_OFF:
|
||||
gpio_set_level(GPIO_LED_POWER_L, 0);
|
||||
gpio_set_level(GPIO_PWR_LED0, 0);
|
||||
break;
|
||||
case LED_BLUE:
|
||||
gpio_set_level(GPIO_LED_POWER_L, 1);
|
||||
gpio_set_level(GPIO_PWR_LED0, 0);
|
||||
break;
|
||||
case LED_ORANGE:
|
||||
gpio_set_level(GPIO_LED_POWER_L, 0);
|
||||
gpio_set_level(GPIO_PWR_LED0, 1);
|
||||
break;
|
||||
default:
|
||||
return EC_ERROR_UNKNOWN;
|
||||
}
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range)
|
||||
{
|
||||
/* Ignoring led_id as both leds support the same colors */
|
||||
brightness_range[EC_LED_COLOR_BLUE] = 1;
|
||||
brightness_range[EC_LED_COLOR_YELLOW] = 1;
|
||||
}
|
||||
|
||||
int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness)
|
||||
{
|
||||
switch (led_id) {
|
||||
case EC_LED_ID_BATTERY_LED:
|
||||
if (brightness[EC_LED_COLOR_BLUE] != 0)
|
||||
bat_led_set_color(LED_BLUE);
|
||||
else if (brightness[EC_LED_COLOR_YELLOW] != 0)
|
||||
bat_led_set_color(LED_ORANGE);
|
||||
else
|
||||
bat_led_set_color(LED_OFF);
|
||||
break;
|
||||
case EC_LED_ID_POWER_LED:
|
||||
if (brightness[EC_LED_COLOR_BLUE] != 0)
|
||||
pwr_led_set_color(LED_BLUE);
|
||||
else if (brightness[EC_LED_COLOR_YELLOW] != 0)
|
||||
pwr_led_set_color(LED_ORANGE);
|
||||
else
|
||||
pwr_led_set_color(LED_OFF);
|
||||
break;
|
||||
default:
|
||||
return EC_ERROR_UNKNOWN;
|
||||
}
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
static void big_led_set_power(void)
|
||||
{
|
||||
static int power_second;
|
||||
|
||||
power_second++;
|
||||
|
||||
/* PWR LED behavior:
|
||||
* Power on: Blue
|
||||
* Suspend: Orange in breeze mode ( 1 sec on/ 3 sec off)
|
||||
* Power off: OFF
|
||||
*/
|
||||
if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
|
||||
pwr_led_set_color(LED_OFF);
|
||||
else if (chipset_in_state(CHIPSET_STATE_ON))
|
||||
pwr_led_set_color(LED_BLUE);
|
||||
else if (chipset_in_state(CHIPSET_STATE_SUSPEND))
|
||||
pwr_led_set_color((power_second & 3) ? LED_OFF : LED_ORANGE);
|
||||
}
|
||||
|
||||
static void big_led_set_battery(void)
|
||||
{
|
||||
static int battery_second;
|
||||
uint32_t chflags = charge_get_flags();
|
||||
|
||||
battery_second++;
|
||||
|
||||
/* BAT LED behavior:
|
||||
* Fully charged / idle: Blue
|
||||
* Force idle (for factory): 2 secs of blue, 2 secs of yellow
|
||||
* Under charging: Orange
|
||||
* Battery low (10%): Orange in breeze mode (1 sec on, 3 sec off)
|
||||
* Battery critical low (less than 3%) or abnormal battery
|
||||
* situation: Orange in blinking mode (1 sec on, 1 sec off)
|
||||
* Using battery or not connected to AC power: OFF
|
||||
*/
|
||||
switch (charge_get_state()) {
|
||||
case PWR_STATE_CHARGE:
|
||||
bat_led_set_color(LED_ORANGE);
|
||||
break;
|
||||
case PWR_STATE_DISCHARGE:
|
||||
if (charge_get_percent() < 3)
|
||||
bat_led_set_color((battery_second & 1)
|
||||
? LED_OFF : LED_ORANGE);
|
||||
else if (charge_get_percent() < 10)
|
||||
bat_led_set_color((battery_second & 3)
|
||||
? LED_OFF : LED_ORANGE);
|
||||
else
|
||||
bat_led_set_color(LED_OFF);
|
||||
break;
|
||||
case PWR_STATE_ERROR:
|
||||
bat_led_set_color((battery_second & 1) ? LED_OFF : LED_ORANGE);
|
||||
break;
|
||||
case PWR_STATE_CHARGE_NEAR_FULL:
|
||||
bat_led_set_color(LED_BLUE);
|
||||
break;
|
||||
case PWR_STATE_IDLE: /* External power connected in IDLE. */
|
||||
if (chflags & CHARGE_FLAG_FORCE_IDLE)
|
||||
bat_led_set_color(
|
||||
(battery_second & 0x2) ? LED_BLUE : LED_ORANGE);
|
||||
else
|
||||
bat_led_set_color(LED_BLUE);
|
||||
break;
|
||||
default:
|
||||
/* Other states don't alter LED behavior */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** * Called by hook task every 1 sec */
|
||||
static void led_second(void)
|
||||
{
|
||||
if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
|
||||
big_led_set_power();
|
||||
if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED))
|
||||
big_led_set_battery();
|
||||
}
|
||||
DECLARE_HOOK(HOOK_SECOND, led_second, HOOK_PRIO_DEFAULT);
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
/* Pit board-specific configuration */
|
||||
|
||||
#include "battery.h"
|
||||
#include "chipset.h"
|
||||
#include "common.h"
|
||||
#include "extpower.h"
|
||||
#include "gpio.h"
|
||||
#include "i2c.h"
|
||||
#include "keyboard_scan.h"
|
||||
#include "keyboard_raw.h"
|
||||
#include "lid_switch.h"
|
||||
#include "pmu_tpschrome.h"
|
||||
#include "power.h"
|
||||
#include "registers.h"
|
||||
#include "spi.h"
|
||||
#include "timer.h"
|
||||
#include "task.h"
|
||||
#include "util.h"
|
||||
#include "gpio_list.h"
|
||||
|
||||
/* Battery temperature ranges in degrees C */
|
||||
static const struct battery_info info = {
|
||||
.start_charging_min_c = 0,
|
||||
.start_charging_max_c = 45,
|
||||
.charging_min_c = 0,
|
||||
.charging_max_c = 60,
|
||||
.discharging_min_c = -20,
|
||||
.discharging_max_c = 70,
|
||||
};
|
||||
|
||||
const struct battery_info *battery_get_info(void)
|
||||
{
|
||||
return &info;
|
||||
}
|
||||
|
||||
/* I2C ports */
|
||||
const struct i2c_port_t i2c_ports[] = {
|
||||
{"master", I2C_PORT_MASTER, 100, GPIO_I2C1_SCL, GPIO_I2C1_SDA},
|
||||
};
|
||||
const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports);
|
||||
|
||||
struct keyboard_scan_config keyscan_config = {
|
||||
.output_settle_us = 40,
|
||||
.debounce_down_us = 6 * MSEC,
|
||||
.debounce_up_us = 30 * MSEC,
|
||||
.scan_period_us = 1500,
|
||||
.min_post_scan_delay_us = 1000,
|
||||
.poll_timeout_us = SECOND,
|
||||
.actual_key_mask = {
|
||||
0x14, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff,
|
||||
0xa4, 0xff, 0xf6, 0x55, 0xfa, 0xc8 /* full set */
|
||||
},
|
||||
};
|
||||
|
||||
int pmu_board_init(void)
|
||||
{
|
||||
int ver, failure = 0;
|
||||
|
||||
/* Set fast charging timeout to 6 hours*/
|
||||
if (!failure)
|
||||
failure = pmu_set_fastcharge(TIMEOUT_6HRS);
|
||||
/* Enable external gpio CHARGER_EN control */
|
||||
if (!failure)
|
||||
failure = pmu_enable_ext_control(1);
|
||||
/* Disable force charging */
|
||||
if (!failure)
|
||||
failure = pmu_enable_charger(0);
|
||||
|
||||
/* Set NOITERM bit */
|
||||
if (!failure)
|
||||
failure = pmu_low_current_charging(1);
|
||||
|
||||
/*
|
||||
* High temperature charging
|
||||
* termination voltage: 2.1V
|
||||
* termination current: 100%
|
||||
*/
|
||||
if (!failure)
|
||||
failure = pmu_set_term_voltage(RANGE_T34, TERM_V2100);
|
||||
if (!failure)
|
||||
failure = pmu_set_term_current(RANGE_T34, TERM_I1000);
|
||||
/*
|
||||
* Standard temperature charging
|
||||
* termination voltage: 2.1V
|
||||
* termination current: 100%
|
||||
*/
|
||||
if (!failure)
|
||||
failure = pmu_set_term_voltage(RANGE_T23, TERM_V2100);
|
||||
if (!failure)
|
||||
failure = pmu_set_term_current(RANGE_T23, TERM_I1000);
|
||||
|
||||
/*
|
||||
* Ignore TPSCHROME NTC reading in T40. This is snow board specific
|
||||
* setting. Check:
|
||||
* http://crosbug.com/p/12221
|
||||
* http://crosbug.com/p/13171
|
||||
*/
|
||||
if (!failure)
|
||||
failure = pmu_set_term_voltage(RANGE_T40, TERM_V2100);
|
||||
if (!failure)
|
||||
failure = pmu_set_term_current(RANGE_T40, TERM_I1000);
|
||||
|
||||
/* Workaround init values before ES3 */
|
||||
if (pmu_version(&ver) || ver < 3) {
|
||||
/* Termination current: 75% */
|
||||
if (!failure)
|
||||
failure = pmu_set_term_current(RANGE_T34, TERM_I0750);
|
||||
if (!failure)
|
||||
failure = pmu_set_term_current(RANGE_T23, TERM_I0750);
|
||||
if (!failure)
|
||||
failure = pmu_set_term_current(RANGE_T40, TERM_I0750);
|
||||
}
|
||||
|
||||
return failure ? EC_ERROR_UNKNOWN : EC_SUCCESS;
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
/* Pit board configuration */
|
||||
|
||||
#ifndef __CROS_EC_BOARD_H
|
||||
#define __CROS_EC_BOARD_H
|
||||
|
||||
/* Optional features */
|
||||
#define CONFIG_BATTERY_BQ20Z453
|
||||
#define CONFIG_BATTERY_SMART
|
||||
#define CONFIG_CHARGER_TPS65090
|
||||
#define CONFIG_CHIPSET_GAIA
|
||||
#define CONFIG_CMD_PMU
|
||||
#define CONFIG_EXTPOWER_GPIO
|
||||
#define CONFIG_HOST_COMMAND_STATUS
|
||||
#define CONFIG_I2C
|
||||
#define CONFIG_I2C_MASTER
|
||||
#define CONFIG_KEYBOARD_BOARD_CONFIG
|
||||
#define CONFIG_KEYBOARD_PROTOCOL_MKBP
|
||||
#define CONFIG_PMU_HARD_RESET
|
||||
#define CONFIG_PMU_POWERINFO
|
||||
#define CONFIG_PMU_TPS65090
|
||||
#define CONFIG_PMU_TPS65090_CHARGING_LED
|
||||
#define CONFIG_SPI
|
||||
#define CONFIG_SPI_PROTOCOL_V2
|
||||
#define CONFIG_VBOOT_HASH
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/* Keyboard output port list */
|
||||
#define KB_OUT_PORT_LIST GPIO_A, GPIO_B, GPIO_C
|
||||
|
||||
/* Single I2C port, where the EC is the master. */
|
||||
#define I2C_PORT_MASTER 0
|
||||
#define I2C_PORT_BATTERY I2C_PORT_MASTER
|
||||
#define I2C_PORT_CHARGER I2C_PORT_MASTER
|
||||
|
||||
/* Charger sense resistors */
|
||||
#define CONFIG_CHARGER_SENSE_RESISTOR_AC 12
|
||||
#define CONFIG_CHARGER_SENSE_RESISTOR 16
|
||||
|
||||
/* Timer selection */
|
||||
#define TIM_CLOCK_MSB 3
|
||||
#define TIM_CLOCK_LSB 9
|
||||
#define TIM_POWER_LED 2
|
||||
#define TIM_WATCHDOG 4
|
||||
|
||||
#include "gpio_signal.h"
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
#endif /* __CROS_EC_BOARD_H */
|
|
@ -1,13 +0,0 @@
|
|||
# -*- makefile -*-
|
||||
# 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.
|
||||
#
|
||||
# Board specific files build
|
||||
|
||||
# the IC is STmicro STM32L151RBH6
|
||||
CHIP:=stm32
|
||||
CHIP_FAMILY:=stm32l
|
||||
CHIP_VARIANT:=stm32l15x
|
||||
|
||||
board-y=board.o
|
|
@ -1,23 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* List of enabled tasks in the priority order
|
||||
*
|
||||
* The first one has the lowest priority.
|
||||
*
|
||||
* For each task, use the macro TASK(n, r, d, s) where :
|
||||
* 'n' in the name of the task
|
||||
* 'r' in the main routine of the task
|
||||
* 'd' in an opaque parameter passed to the routine at startup
|
||||
* 's' is the stack size in bytes; must be a multiple of 8
|
||||
*/
|
||||
#define CONFIG_TASK_LIST \
|
||||
TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \
|
||||
TASK_ALWAYS(CHARGER, charger_task, NULL, TASK_STACK_SIZE) \
|
||||
TASK_NOTEST(CHIPSET, chipset_task, NULL, TASK_STACK_SIZE) \
|
||||
TASK_ALWAYS(HOSTCMD, host_command_task, NULL, TASK_STACK_SIZE) \
|
||||
TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE) \
|
||||
TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, TASK_STACK_SIZE)
|
|
@ -1,67 +0,0 @@
|
|||
/* -*- mode:c -*-
|
||||
*
|
||||
* Copyright (c) 2014 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.
|
||||
*/
|
||||
|
||||
/* Declare symbolic names for all the GPIOs that we care about.
|
||||
* Note: Those with interrupt handlers must be declared first. */
|
||||
|
||||
GPIO_INT(KB_PWR_ON_L, PIN(B, 5), GPIO_INT_BOTH, power_signal_interrupt)
|
||||
GPIO_INT(PP1800_LDO2, PIN(A, 1), GPIO_INT_BOTH, power_signal_interrupt)
|
||||
GPIO_INT(SOC1V8_XPSHOLD, PIN(A, 3), GPIO_INT_RISING, power_signal_interrupt)
|
||||
GPIO_INT(CHARGER_INT_L, PIN(C, 6), GPIO_INT_FALLING, pmu_irq_handler)
|
||||
GPIO_INT(LID_OPEN, PIN(C, 13), GPIO_INT_BOTH, lid_interrupt)
|
||||
GPIO_INT(SUSPEND_L, PIN(C, 7), GPIO_INT_BOTH, power_signal_interrupt)
|
||||
GPIO_INT(SPI1_NSS, PIN(A, 4), GPIO_INT_BOTH | GPIO_PULL_UP, spi_event)
|
||||
GPIO_INT(AC_PRESENT, PIN(A, 0), GPIO_INT_BOTH, extpower_interrupt)
|
||||
|
||||
/* Keyboard inputs */
|
||||
#define GPIO_KB_INPUT (GPIO_INPUT | GPIO_PULL_UP | GPIO_INT_BOTH)
|
||||
#define GPIO_KB_OUTPUT GPIO_ODR_HIGH
|
||||
|
||||
GPIO_INT(KB_IN00, PIN(C, 8), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
GPIO_INT(KB_IN01, PIN(C, 9), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
GPIO_INT(KB_IN02, PIN(C, 10), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
GPIO_INT(KB_IN03, PIN(C, 11), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
GPIO_INT(KB_IN04, PIN(C, 12), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
GPIO_INT(KB_IN05, PIN(C, 14), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
GPIO_INT(KB_IN06, PIN(C, 15), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
GPIO_INT(KB_IN07, PIN(D, 2), GPIO_KB_INPUT, keyboard_raw_gpio_interrupt)
|
||||
|
||||
/* Other inputs */
|
||||
GPIO(WP_L, PIN(B, 4), GPIO_INPUT)
|
||||
|
||||
/* Outputs */
|
||||
GPIO(AP_RESET_L, PIN(B, 3), GPIO_ODR_HIGH)
|
||||
GPIO(CHARGER_EN, PIN(B, 2), GPIO_OUT_LOW)
|
||||
GPIO(EC_INT_L, PIN(B, 9), GPIO_ODR_HIGH)
|
||||
GPIO(EN_PP1350, PIN(H, 1), GPIO_OUT_LOW)
|
||||
GPIO(EN_PP3300, PIN(A, 8), GPIO_OUT_LOW)
|
||||
GPIO(EN_PP5000, PIN(A, 11), GPIO_OUT_LOW)
|
||||
GPIO(ENTERING_RW, PIN(H, 0), GPIO_OUT_LOW)
|
||||
GPIO(I2C1_SCL, PIN(B, 6), GPIO_ODR_HIGH)
|
||||
GPIO(I2C1_SDA, PIN(B, 7), GPIO_ODR_HIGH)
|
||||
GPIO(I2C2_SCL, PIN(B, 10), GPIO_ODR_HIGH)
|
||||
GPIO(I2C2_SDA, PIN(B, 11), GPIO_ODR_HIGH)
|
||||
GPIO(CHARGING_LED,PIN(A, 2), GPIO_OUT_LOW)
|
||||
GPIO(PMIC_PWRON, PIN(A, 12), GPIO_OUT_LOW)
|
||||
GPIO(PMIC_RESET, PIN(A, 15), GPIO_OUT_LOW)
|
||||
GPIO(KB_OUT00, PIN(B, 0), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT01, PIN(B, 8), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT02, PIN(B, 12), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT03, PIN(B, 13), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT04, PIN(B, 14), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT05, PIN(B, 15), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT06, PIN(C, 0), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT07, PIN(C, 1), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT08, PIN(C, 2), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT09, PIN(B, 1), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT10, PIN(C, 5), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT11, PIN(C, 4), GPIO_KB_OUTPUT)
|
||||
GPIO(KB_OUT12, PIN(A, 13), GPIO_KB_OUTPUT)
|
||||
|
||||
ALTERNATE(PIN_MASK(A, 0x00f0), GPIO_ALT_SPI, MODULE_SPI, 0)
|
||||
ALTERNATE(PIN_MASK(A, 0x0600), GPIO_ALT_USART, MODULE_UART, 0)
|
||||
ALTERNATE(PIN_MASK(B, 0x0cc0), GPIO_ALT_I2C, MODULE_I2C, 0)
|
|
@ -766,8 +766,8 @@ static int host_command_get_features(struct host_cmd_handler_args *args)
|
|||
#ifdef CONFIG_AP_HANG_DETECT
|
||||
| EC_FEATURE_MASK_0(EC_FEATURE_HANG_DETECT)
|
||||
#endif
|
||||
#ifdef CONFIG_PMU_POWERINFO
|
||||
| EC_FEATURE_MASK_0(EC_FEATURE_PMU)
|
||||
#if 0
|
||||
| EC_FEATURE_MASK_0(EC_FEATURE_PMU) /* Obsolete */
|
||||
#endif
|
||||
#ifdef CONFIG_HOSTCMD_PD
|
||||
| EC_FEATURE_MASK_0(EC_FEATURE_SUB_MCU)
|
||||
|
|
|
@ -57,11 +57,6 @@ driver-$(CONFIG_IO_EXPANDER_PCA9534)+=ioexpander_pca9534.o
|
|||
# Current/Power monitor
|
||||
driver-$(CONFIG_INA219)$(CONFIG_INA231)+=ina2xx.o
|
||||
|
||||
# Power Management IC
|
||||
driver-$(CONFIG_PMU_TPS65090)+=pmu_tps65090.o
|
||||
driver-$(CONFIG_CHARGER_TPS65090)+=pmu_tps65090_charger.o
|
||||
driver-$(CONFIG_PMU_POWERINFO)+=pmu_tps65090_powerinfo.o
|
||||
|
||||
# LED drivers
|
||||
driver-$(CONFIG_LED_DRIVER_DS2413)+=led/ds2413.o
|
||||
driver-$(CONFIG_LED_DRIVER_LP5562)+=led/lp5562.o
|
||||
|
|
|
@ -1,743 +0,0 @@
|
|||
/* 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 TPS65090 PMU driver.
|
||||
*/
|
||||
|
||||
#include "clock.h"
|
||||
#include "console.h"
|
||||
#include "common.h"
|
||||
#include "extpower.h"
|
||||
#include "host_command.h"
|
||||
#include "hooks.h"
|
||||
#include "i2c.h"
|
||||
#include "pmu_tpschrome.h"
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
|
||||
#define CPUTS(outstr) cputs(CC_CHARGER, outstr)
|
||||
#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args)
|
||||
|
||||
#define TPS65090_I2C_ADDR 0x90
|
||||
|
||||
#define IRQ1_REG 0x00
|
||||
#define IRQ2_REG 0x01
|
||||
#define IRQ1MASK 0x02
|
||||
#define IRQ2MASK 0x03
|
||||
#define CG_CTRL0 0x04
|
||||
#define CG_CTRL1 0x05
|
||||
#define CG_CTRL2 0x06
|
||||
#define CG_CTRL3 0x07
|
||||
#define CG_CTRL4 0x08
|
||||
#define CG_CTRL5 0x09
|
||||
#define CG_STATUS1 0x0a
|
||||
#define CG_STATUS2 0x0b
|
||||
#define DCDC1_CTRL 0x0c
|
||||
#define DCDC2_CTRL 0x0d
|
||||
#define DCDC3_CTRL 0x0e
|
||||
#define FET1_CTRL 0x0f
|
||||
#define FET2_CTRL 0x10
|
||||
#define FET3_CTRL 0x11
|
||||
#define FET4_CTRL 0x12
|
||||
#define FET5_CTRL 0x13
|
||||
#define FET6_CTRL 0x14
|
||||
#define FET7_CTRL 0x15
|
||||
#define AD_CTRL 0x16
|
||||
#define AD_OUT1 0x17
|
||||
#define AD_OUT2 0x18
|
||||
#define TPSCHROME_VER 0x19
|
||||
|
||||
/* Charger control */
|
||||
#define CG_EN (1 << 0)
|
||||
#define CG_EXT_EN (1 << 1)
|
||||
#define CG_FASTCHARGE_SHIFT 2
|
||||
#define CG_FASTCHARGE_MASK (7 << CG_FASTCHARGE_SHIFT)
|
||||
|
||||
/* Charger termination voltage/current */
|
||||
#define CG_VSET_SHIFT 3
|
||||
#define CG_VSET_MASK (3 << CG_VSET_SHIFT)
|
||||
#define CG_ISET_SHIFT 0
|
||||
#define CG_ISET_MASK (7 << CG_ISET_SHIFT)
|
||||
#define CG_NOITERM (1 << 5)
|
||||
#define CG_TSET_SHIFT 5
|
||||
#define CG_TSET_MASK (7 << CG_TSET_SHIFT)
|
||||
|
||||
/* A temperature threshold to force charger hardware error */
|
||||
#define CG_TEMP_THRESHOLD_ERROR 0
|
||||
|
||||
/* Timeout indication */
|
||||
#define STATUS_TIMEOUT_MASK 0xc
|
||||
#define STATUS_PRECHARGE_TIMEOUT 0x4
|
||||
#define STATUS_FASTCHARGE_TIMEOUT 0x8
|
||||
|
||||
/* IRQ events */
|
||||
#define EVENT_VACG (1 << 1) /* AC voltage good */
|
||||
#define EVENT_VSYSG (1 << 2) /* System voltage good */
|
||||
#define EVENT_VBATG (1 << 3) /* Battery voltage good */
|
||||
#define EVENT_CGACT (1 << 4) /* Charging status */
|
||||
#define EVENT_CGCPL (1 << 5) /* Charging complete */
|
||||
|
||||
/* Charger alarm */
|
||||
#define CHARGER_ALARM 3
|
||||
|
||||
/* FET control register bits */
|
||||
#define FET_CTRL_ENFET (1 << 0)
|
||||
#define FET_CTRL_ADENFET (1 << 1)
|
||||
#define FET_CTRL_WAIT (3 << 2) /* Overcurrent timeout max : 3200 us */
|
||||
#define FET_CTRL_PGFET (1 << 4)
|
||||
|
||||
#define FET_CTRL_BASE (FET1_CTRL - 1)
|
||||
|
||||
#define POWER_GOOD_DELAY_US 3500
|
||||
|
||||
/* AD control register bits */
|
||||
#define AD_CTRL_ENADREF (1 << 4)
|
||||
#define AD_CTRL_ADEOC (1 << 5)
|
||||
#define AD_CTRL_ADSTART (1 << 6)
|
||||
|
||||
#define HARD_RESET_TIMEOUT_MS 5
|
||||
|
||||
/* Charger temperature threshold table */
|
||||
static const uint8_t const pmu_temp_threshold[] = {
|
||||
1, /* 0b001, 0 degree C */
|
||||
2, /* 0b010, 10 degree C */
|
||||
5, /* 0b101, 45 degree C */
|
||||
7, /* 0b111, 60 degree C */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PMU_HARD_RESET
|
||||
/**
|
||||
* Force the pmic to reset completely.
|
||||
*
|
||||
* This forces an entire system reset, and therefore should never return. The
|
||||
* implementation is rather hacky; it simply shorts out the 3.3V rail to force
|
||||
* the PMIC to panic. We need this unfortunate hack because it's the only way
|
||||
* to reset the I2C engine inside the PMU.
|
||||
*/
|
||||
static void pmu_hard_reset(void)
|
||||
{
|
||||
/* Short out the 3.3V rail to force a hard reset of tps Chrome */
|
||||
gpio_set_level(GPIO_PMIC_RESET, 1);
|
||||
|
||||
/* Delay while the power is cut */
|
||||
udelay(HARD_RESET_TIMEOUT_MS * 1000);
|
||||
|
||||
/* Shouldn't get here unless the board doesn't have this capability */
|
||||
panic_puts("pmu hard reset failed! (this board may not be capable)\n");
|
||||
}
|
||||
#else
|
||||
static void pmu_hard_reset(void)
|
||||
{
|
||||
panic_puts("pmu hard reset unsupported!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Read all tps65090 interrupt events */
|
||||
static int pmu_get_event(int *event)
|
||||
{
|
||||
static int prev_event;
|
||||
int rv;
|
||||
int irq1, irq2;
|
||||
|
||||
pmu_clear_irq();
|
||||
|
||||
rv = pmu_read(IRQ1_REG, &irq1);
|
||||
if (rv)
|
||||
return rv;
|
||||
rv = pmu_read(IRQ2_REG, &irq2);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
*event = irq1 | (irq2 << 8);
|
||||
|
||||
if (prev_event != *event) {
|
||||
CPRINTS("pmu event: %016b", *event);
|
||||
prev_event = *event;
|
||||
}
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
/* Clear tps65090 irq */
|
||||
int pmu_clear_irq(void)
|
||||
{
|
||||
return pmu_write(IRQ1_REG, 0);
|
||||
}
|
||||
|
||||
/* Read/write tps65090 register */
|
||||
int pmu_read(int reg, int *value)
|
||||
{
|
||||
return i2c_read8(I2C_PORT_CHARGER, TPS65090_I2C_ADDR, reg, value);
|
||||
}
|
||||
|
||||
int pmu_write(int reg, int value)
|
||||
{
|
||||
return i2c_write8(I2C_PORT_CHARGER, TPS65090_I2C_ADDR, reg, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read tpschrome version
|
||||
*
|
||||
* @param version output value of tpschrome version
|
||||
*/
|
||||
int pmu_version(int *version)
|
||||
{
|
||||
return pmu_read(TPSCHROME_VER, version);
|
||||
}
|
||||
|
||||
int pmu_is_charger_alarm(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
/**
|
||||
* if the I2C access to the PMU fails, we consider the failure as
|
||||
* non-critical and wait for the next read without send the alert.
|
||||
*/
|
||||
if (!pmu_read(CG_STATUS1, &status) && (status & CHARGER_ALARM))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pmu_is_charge_timeout(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (pmu_read(CG_STATUS1, &status))
|
||||
return 0;
|
||||
|
||||
status &= STATUS_TIMEOUT_MASK;
|
||||
return (status == STATUS_PRECHARGE_TIMEOUT) ||
|
||||
(status == STATUS_FASTCHARGE_TIMEOUT);
|
||||
}
|
||||
|
||||
int pmu_get_power_source(int *ac_good, int *battery_good)
|
||||
{
|
||||
int rv, event = 0;
|
||||
|
||||
rv = pmu_get_event(&event);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
if (ac_good)
|
||||
*ac_good = event & EVENT_VACG;
|
||||
if (battery_good)
|
||||
*battery_good = event & EVENT_VBATG;
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable charger's charging function
|
||||
*
|
||||
* When enable, charger ignores external control and charge the
|
||||
* battery directly. If EC wants to contorl charging, set the flag
|
||||
* to 0.
|
||||
*/
|
||||
int pmu_enable_charger(int enable)
|
||||
{
|
||||
int rv;
|
||||
int reg;
|
||||
|
||||
rv = pmu_read(CG_CTRL0, ®);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
if (enable)
|
||||
reg |= CG_EN;
|
||||
else
|
||||
reg &= ~CG_EN;
|
||||
|
||||
return pmu_write(CG_CTRL0, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set external charge enable pin
|
||||
*
|
||||
* @param enable boolean, set 1 to eanble external control
|
||||
*/
|
||||
int pmu_enable_ext_control(int enable)
|
||||
{
|
||||
int rv;
|
||||
int reg;
|
||||
|
||||
rv = pmu_read(CG_CTRL0, ®);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
if (enable)
|
||||
reg |= CG_EXT_EN;
|
||||
else
|
||||
reg &= ~CG_EXT_EN;
|
||||
|
||||
return pmu_write(CG_CTRL0, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set fast charge timeout
|
||||
*
|
||||
* @param timeout enum FASTCHARGE_TIMEOUT
|
||||
*/
|
||||
int pmu_set_fastcharge(enum FASTCHARGE_TIMEOUT timeout)
|
||||
{
|
||||
int rv;
|
||||
int reg;
|
||||
|
||||
rv = pmu_read(CG_CTRL0, ®);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
reg &= ~CG_FASTCHARGE_MASK;
|
||||
reg |= (timeout << CG_FASTCHARGE_SHIFT) & CG_FASTCHARGE_MASK;
|
||||
|
||||
return pmu_write(CG_CTRL0, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set termination current for temperature ranges
|
||||
*
|
||||
* @param range T01 T12 T23 T34 T40
|
||||
* @param current enum termination current, I0250 == 25.0%:
|
||||
* I0000 I0250 I0375 I0500 I0625 I0750 I0875 I1000
|
||||
*/
|
||||
int pmu_set_term_current(enum TPS_TEMPERATURE_RANGE range,
|
||||
enum TPS_TERMINATION_CURRENT current)
|
||||
{
|
||||
int rv;
|
||||
int reg_val;
|
||||
|
||||
rv = pmu_read(CG_CTRL1 + range, ®_val);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
reg_val &= ~CG_ISET_MASK;
|
||||
reg_val |= current << CG_ISET_SHIFT;
|
||||
|
||||
return pmu_write(CG_CTRL1 + range, reg_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set termination voltage for temperature ranges
|
||||
*
|
||||
* @param range T01 T12 T23 T34 T40
|
||||
* @param voltage enum termination voltage, V2050 == 2.05V:
|
||||
* V2000 V2050 V2075 V2100
|
||||
*/
|
||||
int pmu_set_term_voltage(enum TPS_TEMPERATURE_RANGE range,
|
||||
enum TPS_TERMINATION_VOLTAGE voltage)
|
||||
{
|
||||
int rv;
|
||||
int reg_val;
|
||||
|
||||
rv = pmu_read(CG_CTRL1 + range, ®_val);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
reg_val &= ~CG_VSET_MASK;
|
||||
reg_val |= voltage << CG_VSET_SHIFT;
|
||||
|
||||
return pmu_write(CG_CTRL1 + range, reg_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set temperature threshold
|
||||
*
|
||||
* @param temp_n TSET_T1 to TSET_T4
|
||||
* @param value 0b000 ~ 0b111, temperature threshold
|
||||
*/
|
||||
int pmu_set_temp_threshold(enum TPS_TEMPERATURE temp_n, uint8_t value)
|
||||
{
|
||||
int rv;
|
||||
int reg_val;
|
||||
|
||||
/*
|
||||
* Temperature threshold T1 to T4 are stored in TPSCHROME registers
|
||||
* CG_CTRL1 to CG_CTRL4.
|
||||
*/
|
||||
rv = pmu_read(CG_CTRL1 + temp_n, ®_val);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
reg_val &= ~CG_TSET_MASK;
|
||||
reg_val |= (value << CG_TSET_SHIFT) & CG_TSET_MASK;
|
||||
|
||||
return pmu_write(CG_CTRL1 + temp_n, reg_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force charger into error state, turn off charging and blinks charging LED
|
||||
*
|
||||
* @param enable true to turn off charging and blink LED
|
||||
* @return EC_SUCCESS for success
|
||||
*/
|
||||
int pmu_blink_led(int enable)
|
||||
{
|
||||
int rv;
|
||||
enum TPS_TEMPERATURE t;
|
||||
uint8_t threshold;
|
||||
|
||||
for (t = TSET_T1; t <= TSET_T4; t++) {
|
||||
if (enable)
|
||||
threshold = CG_TEMP_THRESHOLD_ERROR;
|
||||
else
|
||||
threshold = pmu_temp_threshold[t];
|
||||
|
||||
rv = pmu_set_temp_threshold(t, threshold);
|
||||
if (rv) {
|
||||
/* Retry */
|
||||
rv = pmu_set_temp_threshold(t, threshold);
|
||||
if (rv)
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable low current charging
|
||||
*
|
||||
* @param enable enable/disable low current charging
|
||||
*/
|
||||
int pmu_low_current_charging(int enable)
|
||||
{
|
||||
int rv;
|
||||
int reg_val;
|
||||
|
||||
rv = pmu_read(CG_CTRL5, ®_val);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
if (enable)
|
||||
reg_val |= CG_NOITERM;
|
||||
else
|
||||
reg_val &= ~CG_NOITERM;
|
||||
|
||||
return pmu_write(CG_CTRL5, reg_val);
|
||||
}
|
||||
|
||||
int pmu_enable_fet(int fet_id, int enable, int *power_good)
|
||||
{
|
||||
int rv, reg;
|
||||
int reg_offset;
|
||||
|
||||
reg_offset = FET_CTRL_BASE + fet_id;
|
||||
|
||||
rv = pmu_read(reg_offset, ®);
|
||||
if (rv)
|
||||
return rv;
|
||||
reg |= FET_CTRL_ADENFET | FET_CTRL_WAIT;
|
||||
if (enable)
|
||||
reg |= FET_CTRL_ENFET;
|
||||
else
|
||||
reg &= ~FET_CTRL_ENFET;
|
||||
|
||||
rv = pmu_write(reg_offset, reg);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
if (power_good) {
|
||||
usleep(POWER_GOOD_DELAY_US);
|
||||
rv = pmu_read(reg_offset, ®);
|
||||
if (rv)
|
||||
return rv;
|
||||
*power_good = reg & FET_CTRL_PGFET;
|
||||
}
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int pmu_adc_read(int adc_idx, int flags)
|
||||
{
|
||||
int ctrl;
|
||||
int val1, val2;
|
||||
int rv;
|
||||
|
||||
rv = pmu_read(AD_CTRL, &ctrl);
|
||||
if (rv)
|
||||
return rv;
|
||||
if (!(ctrl & AD_CTRL_ENADREF)) {
|
||||
ctrl |= AD_CTRL_ENADREF;
|
||||
rv = pmu_write(AD_CTRL, ctrl);
|
||||
if (rv)
|
||||
return rv;
|
||||
/* wait for reference voltage stabilization */
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
ctrl = (ctrl & ~0xf) | adc_idx;
|
||||
rv = pmu_write(AD_CTRL, ctrl);
|
||||
if (rv)
|
||||
return rv;
|
||||
udelay(150);
|
||||
|
||||
ctrl |= AD_CTRL_ADSTART;
|
||||
rv = pmu_write(AD_CTRL, ctrl);
|
||||
if (rv)
|
||||
return rv;
|
||||
udelay(200);
|
||||
|
||||
do {
|
||||
rv = pmu_read(AD_CTRL, &ctrl);
|
||||
if (rv)
|
||||
return rv;
|
||||
} while (!(ctrl & AD_CTRL_ADEOC));
|
||||
|
||||
rv = pmu_read(AD_OUT1, &val1) | pmu_read(AD_OUT2, &val2);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
if (!(flags & ADC_FLAG_KEEP_ON))
|
||||
rv = pmu_write(AD_CTRL, ctrl & ~AD_CTRL_ENADREF);
|
||||
|
||||
return (val2 << 8) | val1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt shutdown.
|
||||
*/
|
||||
static int pmu_try_shutdown(void)
|
||||
{
|
||||
int offset;
|
||||
|
||||
/* Disable each of the DCDCs */
|
||||
for (offset = DCDC1_CTRL; offset <= DCDC3_CTRL; offset++) {
|
||||
if (pmu_write(offset, 0x0e))
|
||||
return EC_ERROR_UNKNOWN;
|
||||
}
|
||||
/* Disable each of the FETs */
|
||||
for (offset = FET1_CTRL; offset <= FET7_CTRL; offset++) {
|
||||
if (pmu_write(offset, 0x02))
|
||||
return EC_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Clear AD controls/status */
|
||||
if (pmu_write(AD_CTRL, 0x00))
|
||||
return EC_ERROR_UNKNOWN;
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int pmu_shutdown(void)
|
||||
{
|
||||
int pmu_shutdown_retries = 3;
|
||||
|
||||
/* Attempt shutdown */
|
||||
while (--pmu_shutdown_retries >= 0) {
|
||||
if (!pmu_try_shutdown())
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PMU_HARD_RESET
|
||||
/* We ran out of tries, so reset the board */
|
||||
CPUTS("PMU shutdown failed. Hard-resetting.\n");
|
||||
cflush();
|
||||
pmu_hard_reset();
|
||||
#endif
|
||||
|
||||
/* If we're still here, we couldn't shutdown OR reset */
|
||||
return EC_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill all of the pmu registers with known good values, this allows the
|
||||
* pmu to recover by rebooting the system if its registers were trashed.
|
||||
*/
|
||||
static void pmu_init_registers(void)
|
||||
{
|
||||
const struct {
|
||||
uint8_t index;
|
||||
uint8_t value;
|
||||
} reg[] = {
|
||||
{IRQ1MASK, 0x00},
|
||||
{IRQ2MASK, 0x00},
|
||||
{CG_CTRL0, 0x02},
|
||||
{CG_CTRL1, 0x20},
|
||||
{CG_CTRL2, 0x4b},
|
||||
{CG_CTRL3, 0xbf},
|
||||
{CG_CTRL4, 0xf3},
|
||||
{CG_CTRL5, 0xc0},
|
||||
{DCDC1_CTRL, 0x0e},
|
||||
{DCDC2_CTRL, 0x0e},
|
||||
{DCDC3_CTRL, 0x0e},
|
||||
{FET1_CTRL, 0x02},
|
||||
{FET2_CTRL, 0x02},
|
||||
{FET3_CTRL, 0x02},
|
||||
{FET4_CTRL, 0x02},
|
||||
{FET5_CTRL, 0x02},
|
||||
{FET6_CTRL, 0x02},
|
||||
{FET7_CTRL, 0x02},
|
||||
{AD_CTRL, 0x00},
|
||||
{IRQ1_REG, 0x00}
|
||||
};
|
||||
uint8_t i;
|
||||
|
||||
/*
|
||||
* Write all PMU registers. Ignore return value from pmu_write()
|
||||
* because there's nothing we can reasonably do if it fails.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(reg); i++)
|
||||
pmu_write(reg[i].index, reg[i].value);
|
||||
}
|
||||
DECLARE_HOOK(HOOK_CHIPSET_PRE_INIT, pmu_init_registers, HOOK_PRIO_DEFAULT);
|
||||
|
||||
void pmu_init(void)
|
||||
{
|
||||
int failure = 0, retries_remaining = 3;
|
||||
|
||||
while (--retries_remaining >= 0) {
|
||||
failure = pmu_board_init();
|
||||
|
||||
/* Enable interrupts */
|
||||
if (!failure) {
|
||||
failure = pmu_write(IRQ1MASK,
|
||||
EVENT_VACG | /* AC voltage good */
|
||||
EVENT_VSYSG | /* System voltage good */
|
||||
EVENT_VBATG | /* Battery voltage good */
|
||||
EVENT_CGACT | /* Charging status */
|
||||
EVENT_CGCPL); /* Charging complete */
|
||||
}
|
||||
if (!failure)
|
||||
failure = pmu_write(IRQ2MASK, 0);
|
||||
if (!failure)
|
||||
failure = pmu_clear_irq();
|
||||
|
||||
/* Exit the retry loop if there was no failure */
|
||||
if (!failure)
|
||||
break;
|
||||
}
|
||||
|
||||
if (failure) {
|
||||
CPUTS("Failed to initialize PMU. Hard-resetting.\n");
|
||||
cflush();
|
||||
pmu_hard_reset();
|
||||
}
|
||||
}
|
||||
|
||||
/* Initializes PMU when power is turned on. This is necessary because the TPS'
|
||||
* 3.3V rail is not powered until the power is turned on. */
|
||||
static void pmu_chipset_startup(void)
|
||||
{
|
||||
pmu_init();
|
||||
|
||||
#ifdef BOARD_PIT
|
||||
/* Enable FET4 by default which allows for SD Card booting */
|
||||
{
|
||||
int pgood;
|
||||
pmu_enable_fet(4, 1, &pgood);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
DECLARE_HOOK(HOOK_CHIPSET_STARTUP, pmu_chipset_startup, HOOK_PRIO_DEFAULT);
|
||||
|
||||
#ifdef CONFIG_CMD_PMU
|
||||
static int print_pmu_info(void)
|
||||
{
|
||||
int reg, ret;
|
||||
int value;
|
||||
|
||||
ccprintf(" ");
|
||||
for (reg = 0; reg <= 0x18; reg++)
|
||||
ccprintf("%02x ", reg);
|
||||
ccprintf("\n");
|
||||
|
||||
ccprintf("PMU: ");
|
||||
for (reg = 0; reg <= 0x18; reg++) {
|
||||
ret = pmu_read(reg, &value);
|
||||
if (ret)
|
||||
return ret;
|
||||
ccprintf("%02x ", value);
|
||||
}
|
||||
ccputs("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int command_pmu(int argc, char **argv)
|
||||
{
|
||||
int repeat = 1;
|
||||
int rv = 0;
|
||||
int loop;
|
||||
int value;
|
||||
char *e;
|
||||
|
||||
if (argc > 1) {
|
||||
repeat = strtoi(argv[1], &e, 0);
|
||||
if (*e) {
|
||||
if (strlen(argv[1]) >= 1 && argv[1][0] == 'r') {
|
||||
pmu_hard_reset();
|
||||
/* If this returns, there was an error */
|
||||
return EC_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
ccputs("Invalid repeat count\n");
|
||||
return EC_ERROR_INVAL;
|
||||
}
|
||||
}
|
||||
|
||||
for (loop = 0; loop < repeat; loop++) {
|
||||
rv = print_pmu_info();
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
rv = pmu_read(IRQ1_REG, &value);
|
||||
if (rv)
|
||||
return rv;
|
||||
CPRINTS("pmu events b%08b", value);
|
||||
CPRINTS("ac gpio %d", extpower_is_present());
|
||||
|
||||
if (rv)
|
||||
ccprintf("Failed - error %d\n", rv);
|
||||
|
||||
return rv ? EC_ERROR_UNKNOWN : EC_SUCCESS;
|
||||
}
|
||||
DECLARE_CONSOLE_COMMAND(pmu, command_pmu,
|
||||
"<repeat_count|reset>",
|
||||
"Print PMU info or force a hard reset");
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* TPSchrome LDO pass-through
|
||||
*/
|
||||
#ifdef CONFIG_I2C_PASSTHROUGH
|
||||
static int host_command_ldo_get(struct host_cmd_handler_args *args)
|
||||
{
|
||||
int rv;
|
||||
int val;
|
||||
const struct ec_params_ldo_get *p = args->params;
|
||||
struct ec_response_ldo_get *r = args->response;
|
||||
|
||||
/* is this an existing TPSchrome FET ? */
|
||||
if ((p->index < 1) || (p->index > 7))
|
||||
return EC_RES_ERROR;
|
||||
|
||||
rv = pmu_read(FET_CTRL_BASE + p->index, &val);
|
||||
if (rv)
|
||||
return EC_RES_ERROR;
|
||||
|
||||
r->state = !!(val & FET_CTRL_PGFET);
|
||||
args->response_size = sizeof(struct ec_response_ldo_get);
|
||||
|
||||
return EC_RES_SUCCESS;
|
||||
}
|
||||
DECLARE_HOST_COMMAND(EC_CMD_LDO_GET,
|
||||
host_command_ldo_get,
|
||||
EC_VER_MASK(0));
|
||||
|
||||
static int host_command_ldo_set(struct host_cmd_handler_args *args)
|
||||
{
|
||||
int rv;
|
||||
const struct ec_params_ldo_set *p = args->params;
|
||||
|
||||
/* is this an existing TPSchrome FET ? */
|
||||
if ((p->index < 1) || (p->index > 7))
|
||||
return EC_RES_ERROR;
|
||||
rv = pmu_enable_fet(p->index, p->state & EC_LDO_STATE_ON, NULL);
|
||||
|
||||
return rv ? EC_RES_ERROR : EC_RES_SUCCESS;
|
||||
}
|
||||
DECLARE_HOST_COMMAND(EC_CMD_LDO_SET,
|
||||
host_command_ldo_set,
|
||||
EC_VER_MASK(0));
|
||||
#endif
|
|
@ -1,556 +0,0 @@
|
|||
/* 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 TPS65090 PMU charging task.
|
||||
*/
|
||||
|
||||
#include "battery.h"
|
||||
#include "battery_smart.h"
|
||||
#include "clock.h"
|
||||
#include "chipset.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "extpower.h"
|
||||
#include "hooks.h"
|
||||
#include "gpio.h"
|
||||
#include "pmu_tpschrome.h"
|
||||
#include "system.h"
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
|
||||
#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args)
|
||||
|
||||
/* Charging and discharging alarms */
|
||||
#define ALARM_DISCHARGING (ALARM_TERMINATE_DISCHARGE | ALARM_OVER_TEMP)
|
||||
#define ALARM_CHARGED (ALARM_OVER_CHARGED | ALARM_TERMINATE_CHARGE)
|
||||
|
||||
/* Maximum time allowed to revive a extremely low charge battery */
|
||||
#define PRE_CHARGING_TIMEOUT (15 * SECOND)
|
||||
|
||||
/*
|
||||
* Time delay in usec for idle, charging and discharging. Defined in battery
|
||||
* charging flow.
|
||||
*/
|
||||
#define T1_OFF_USEC (60 * SECOND)
|
||||
#define T1_SUSPEND_USEC (60 * SECOND)
|
||||
#define T1_USEC (5 * SECOND)
|
||||
#define T2_USEC (10 * SECOND)
|
||||
#define T3_USEC (10 * SECOND)
|
||||
|
||||
#ifndef BATTERY_AP_OFF_LEVEL
|
||||
#define BATTERY_AP_OFF_LEVEL 0
|
||||
#endif
|
||||
|
||||
static const char * const state_list[] = CHARGE_STATE_NAME_TABLE;
|
||||
|
||||
/* States for throttling PMU task */
|
||||
static timestamp_t last_waken; /* Initialized to 0 */
|
||||
static int has_pending_event;
|
||||
|
||||
static enum charging_state current_state = ST_IDLE0;
|
||||
|
||||
/* Cached version of battery parameter */
|
||||
static struct batt_params batt_params_copy;
|
||||
|
||||
|
||||
#ifdef CONFIG_PMU_TPS65090_CHARGING_LED
|
||||
static void update_battery_led(void)
|
||||
{
|
||||
int alarm;
|
||||
int led_on = 0;
|
||||
if(extpower_is_present()){
|
||||
battery_status(&alarm);
|
||||
if((alarm & ALARM_CHARGED) && !gpio_get_level(GPIO_CHARGER_EN))
|
||||
led_on = 1;
|
||||
}
|
||||
|
||||
gpio_set_level(GPIO_CHARGING_LED, led_on);
|
||||
}
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static int battery_start_charging_range(int deci_k)
|
||||
{
|
||||
int8_t temp_c = DECI_KELVIN_TO_CELSIUS(deci_k);
|
||||
const struct battery_info *info = battery_get_info();
|
||||
|
||||
return (temp_c >= info->start_charging_min_c &&
|
||||
temp_c < info->start_charging_max_c);
|
||||
}
|
||||
|
||||
static int battery_charging_range(int deci_k)
|
||||
{
|
||||
int8_t temp_c = DECI_KELVIN_TO_CELSIUS(deci_k);
|
||||
const struct battery_info *info = battery_get_info();
|
||||
|
||||
return (temp_c >= info->charging_min_c &&
|
||||
temp_c < info->charging_max_c);
|
||||
}
|
||||
|
||||
static int battery_discharging_range(int deci_k)
|
||||
{
|
||||
int8_t temp_c = DECI_KELVIN_TO_CELSIUS(deci_k);
|
||||
const struct battery_info *info = battery_get_info();
|
||||
|
||||
return (temp_c >= info->discharging_min_c &&
|
||||
temp_c < info->discharging_max_c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn off the AP
|
||||
*/
|
||||
static int system_off(void)
|
||||
{
|
||||
if (chipset_in_state(CHIPSET_STATE_ON)) {
|
||||
CPRINTS("pmu turning system off");
|
||||
chipset_force_shutdown();
|
||||
}
|
||||
|
||||
return ST_IDLE0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the host when battery remaining charge is lower than 10%
|
||||
*/
|
||||
static int notify_battery_low(void)
|
||||
{
|
||||
static timestamp_t last_notify_time;
|
||||
timestamp_t now;
|
||||
|
||||
if (chipset_in_state(CHIPSET_STATE_ON)) {
|
||||
now = get_time();
|
||||
if (now.val - last_notify_time.val > MINUTE) {
|
||||
CPRINTS("pmu notify battery low (< 4%)");
|
||||
last_notify_time = now;
|
||||
/* TODO(crosbug.com/p/23814): Actually notify AP */
|
||||
}
|
||||
}
|
||||
return ST_DISCHARGING;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate relative state of charge moving average
|
||||
*
|
||||
* @param state_of_charge Current battery state of charge reading,
|
||||
* from 0 to 100. When state_of_charge < 0,
|
||||
* resets the moving average window
|
||||
* @return Average state of charge, rounded to nearest
|
||||
* integer.
|
||||
* -1 when window reset.
|
||||
*
|
||||
* The returned value will be rounded to the nearest integer, by set moving
|
||||
* average init value to (0.5 * window_size).
|
||||
*
|
||||
*/
|
||||
static int rsoc_moving_average(int state_of_charge)
|
||||
{
|
||||
static uint8_t rsoc[4];
|
||||
static int8_t index = -1;
|
||||
int moving_average = ARRAY_SIZE(rsoc) / 2;
|
||||
int i;
|
||||
|
||||
if (state_of_charge < 0) {
|
||||
index = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (index < 0) {
|
||||
for (i = 0; i < ARRAY_SIZE(rsoc); i++)
|
||||
rsoc[i] = (uint8_t)state_of_charge;
|
||||
index = 0;
|
||||
return state_of_charge;
|
||||
}
|
||||
|
||||
rsoc[index] = (uint8_t)state_of_charge;
|
||||
index++;
|
||||
index %= sizeof(rsoc);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rsoc); i++)
|
||||
moving_average += (int)rsoc[i];
|
||||
moving_average /= ARRAY_SIZE(rsoc);
|
||||
|
||||
return moving_average;
|
||||
}
|
||||
|
||||
/*
|
||||
* This saves battery parameters for charger_current_battery_params().
|
||||
*/
|
||||
static void battery_get_params_and_save_a_copy(struct batt_params *batt)
|
||||
{
|
||||
battery_get_params(&batt_params_copy);
|
||||
memcpy(batt, &batt_params_copy, sizeof(*batt));
|
||||
}
|
||||
|
||||
struct batt_params *charger_current_battery_params(void)
|
||||
{
|
||||
return &batt_params_copy;
|
||||
}
|
||||
|
||||
static int calc_next_state(int state)
|
||||
{
|
||||
struct batt_params batt;
|
||||
int alarm;
|
||||
|
||||
battery_get_params_and_save_a_copy(&batt);
|
||||
|
||||
switch (state) {
|
||||
case ST_IDLE0:
|
||||
case ST_BAD_COND:
|
||||
case ST_IDLE:
|
||||
/* Check AC and chipset state */
|
||||
if (!extpower_is_present()) {
|
||||
if (chipset_in_state(CHIPSET_STATE_ON))
|
||||
return ST_DISCHARGING;
|
||||
return ST_IDLE;
|
||||
}
|
||||
|
||||
/* Stay in idle mode if charger overtemp */
|
||||
if (pmu_is_charger_alarm())
|
||||
return ST_BAD_COND;
|
||||
|
||||
/* Enable charging when battery doesn't respond */
|
||||
if (!(batt.flags & BATT_FLAG_RESPONSIVE))
|
||||
return ST_PRE_CHARGING;
|
||||
|
||||
/* Turn off charger when battery temperature is out
|
||||
* of the start charging range.
|
||||
*/
|
||||
if (!battery_start_charging_range(batt.temperature))
|
||||
return ST_BAD_COND;
|
||||
|
||||
/* Turn off charger on battery over temperature alarm */
|
||||
if (battery_status(&alarm) || (alarm & ALARM_OVER_TEMP))
|
||||
return ST_BAD_COND;
|
||||
|
||||
/* Stop charging if the battery says it's charged */
|
||||
if (alarm & ALARM_CHARGED)
|
||||
return ST_IDLE;
|
||||
|
||||
/* Start charging only when battery charge lower than 100% */
|
||||
if (!(batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE)) {
|
||||
if (batt.state_of_charge < 100)
|
||||
return ST_CHARGING;
|
||||
}
|
||||
|
||||
return ST_IDLE;
|
||||
|
||||
case ST_PRE_CHARGING:
|
||||
if (!extpower_is_present())
|
||||
return ST_IDLE0;
|
||||
|
||||
/*
|
||||
* If the battery goes online after enabling the charger, go
|
||||
* into charging state.
|
||||
*/
|
||||
if (batt.flags & BATT_FLAG_RESPONSIVE) {
|
||||
if (!battery_start_charging_range(batt.temperature))
|
||||
return ST_IDLE0;
|
||||
if (!(batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE)) {
|
||||
if (batt.state_of_charge >= 100)
|
||||
return ST_IDLE0;
|
||||
}
|
||||
return ST_CHARGING;
|
||||
}
|
||||
|
||||
return ST_PRE_CHARGING;
|
||||
|
||||
case ST_CHARGING:
|
||||
/* Go back to idle state when AC is unplugged */
|
||||
if (!extpower_is_present())
|
||||
return ST_IDLE0;
|
||||
|
||||
/*
|
||||
* Disable charging on battery access error, or charging
|
||||
* temperature out of range.
|
||||
*/
|
||||
if (!(batt.flags & BATT_FLAG_RESPONSIVE)) {
|
||||
CPRINTS("pmu charging: unable to get battery "
|
||||
"temperature");
|
||||
return ST_IDLE0;
|
||||
} else if (!battery_charging_range(batt.temperature)) {
|
||||
CPRINTS("pmu charging: temperature out of range "
|
||||
"%dC",
|
||||
DECI_KELVIN_TO_CELSIUS(batt.temperature));
|
||||
return ST_CHARGING_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable charging on battery alarm events or access error:
|
||||
* - over temperature
|
||||
* - over current
|
||||
*/
|
||||
if (battery_status(&alarm))
|
||||
return ST_IDLE0;
|
||||
|
||||
if (alarm & ALARM_OVER_TEMP) {
|
||||
CPRINTS("pmu charging: battery over temp");
|
||||
return ST_CHARGING_ERROR;
|
||||
}
|
||||
|
||||
/* Go to idle state if battery is fully charged */
|
||||
if (alarm & ALARM_CHARGED)
|
||||
return ST_IDLE;
|
||||
|
||||
/*
|
||||
* Disable charging on charger alarm events:
|
||||
* - charger over current
|
||||
* - charger over temperature
|
||||
*/
|
||||
if (pmu_is_charger_alarm()) {
|
||||
CPRINTS("pmu charging: charger alarm");
|
||||
return ST_IDLE0;
|
||||
}
|
||||
|
||||
return ST_CHARGING;
|
||||
|
||||
case ST_CHARGING_ERROR:
|
||||
/*
|
||||
* This state indicates AC is plugged but the battery is not
|
||||
* charging. The conditions to exit this state:
|
||||
* - battery detected
|
||||
* - battery temperature is in start charging range
|
||||
* - no battery alarm
|
||||
*/
|
||||
if (extpower_is_present()) {
|
||||
if (battery_status(&alarm))
|
||||
return ST_CHARGING_ERROR;
|
||||
|
||||
if (alarm & ALARM_OVER_TEMP)
|
||||
return ST_CHARGING_ERROR;
|
||||
|
||||
if (!(batt.flags & BATT_FLAG_RESPONSIVE))
|
||||
return ST_CHARGING_ERROR;
|
||||
|
||||
if (!battery_charging_range(batt.temperature))
|
||||
return ST_CHARGING_ERROR;
|
||||
|
||||
return ST_CHARGING;
|
||||
}
|
||||
|
||||
return ST_IDLE0;
|
||||
|
||||
|
||||
case ST_DISCHARGING:
|
||||
/* Go back to idle state when AC is plugged */
|
||||
if (extpower_is_present())
|
||||
return ST_IDLE0;
|
||||
|
||||
/* Prepare EC sleep after system stopped discharging */
|
||||
if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
|
||||
return ST_IDLE0;
|
||||
|
||||
/* Check battery discharging temperature range */
|
||||
if (batt.flags & BATT_FLAG_RESPONSIVE) {
|
||||
if (!battery_discharging_range(batt.temperature)) {
|
||||
CPRINTS("pmu discharging: temperature out of "
|
||||
"range %dC",
|
||||
DECI_KELVIN_TO_CELSIUS(
|
||||
batt.temperature));
|
||||
return system_off();
|
||||
}
|
||||
}
|
||||
/* Check discharging alarm */
|
||||
if (!battery_status(&alarm) && (alarm & ALARM_DISCHARGING)) {
|
||||
CPRINTS("pmu discharging: battery alarm %016b", alarm);
|
||||
return system_off();
|
||||
}
|
||||
/* Check remaining charge % */
|
||||
if (!(batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE)) {
|
||||
/*
|
||||
* Shutdown AP when state of charge < 1.5%.
|
||||
* Moving average is rounded to integer.
|
||||
*/
|
||||
if (rsoc_moving_average(batt.state_of_charge) < 2)
|
||||
return system_off();
|
||||
else if (batt.state_of_charge < 4)
|
||||
notify_battery_low();
|
||||
}
|
||||
|
||||
return ST_DISCHARGING;
|
||||
}
|
||||
|
||||
return ST_IDLE0;
|
||||
}
|
||||
|
||||
enum charging_state charge_get_state(void)
|
||||
{
|
||||
return current_state;
|
||||
}
|
||||
|
||||
int charge_keep_power_off(void)
|
||||
{
|
||||
int charge;
|
||||
|
||||
if (BATTERY_AP_OFF_LEVEL == 0)
|
||||
return 0;
|
||||
|
||||
if (battery_remaining_capacity(&charge))
|
||||
return current_state != ST_CHARGING_ERROR;
|
||||
|
||||
return charge <= BATTERY_AP_OFF_LEVEL;
|
||||
}
|
||||
|
||||
void charger_task(void)
|
||||
{
|
||||
int next_state;
|
||||
int wait_time = T1_USEC;
|
||||
timestamp_t pre_chg_start = get_time();
|
||||
|
||||
pmu_init();
|
||||
|
||||
/* Enable low current charging */
|
||||
pmu_low_current_charging(1);
|
||||
|
||||
/* Enable charger interrupt */
|
||||
gpio_enable_interrupt(GPIO_CHARGER_INT_L);
|
||||
|
||||
/*
|
||||
* EC STOP mode support
|
||||
* The charging loop can be stopped in idle state with AC unplugged.
|
||||
* Charging loop will be resumed by TPSCHROME interrupt.
|
||||
*/
|
||||
enable_charging(0);
|
||||
disable_sleep(SLEEP_MASK_CHARGING);
|
||||
|
||||
while (1) {
|
||||
last_waken = get_time();
|
||||
pmu_clear_irq();
|
||||
|
||||
#ifdef CONFIG_PMU_TPS65090_CHARGING_LED
|
||||
update_battery_led();
|
||||
#endif
|
||||
/*
|
||||
* When battery is extremely low, the internal voltage can not
|
||||
* power on its gas gauge IC. Charging loop will enable the
|
||||
* charger and turn on trickle charging. For safety reason,
|
||||
* charger should be disabled if the communication to battery
|
||||
* failed.
|
||||
*/
|
||||
if (current_state == ST_PRE_CHARGING &&
|
||||
get_time().val - pre_chg_start.val >= PRE_CHARGING_TIMEOUT)
|
||||
next_state = ST_CHARGING_ERROR;
|
||||
else
|
||||
next_state = calc_next_state(current_state);
|
||||
|
||||
if (next_state != current_state) {
|
||||
/* Reset state of charge moving average window */
|
||||
rsoc_moving_average(-1);
|
||||
|
||||
CPRINTS("batt state %s -> %s",
|
||||
state_list[current_state],
|
||||
state_list[next_state]);
|
||||
|
||||
current_state = next_state;
|
||||
|
||||
switch (current_state) {
|
||||
case ST_PRE_CHARGING:
|
||||
pre_chg_start = get_time();
|
||||
/* Fall through */
|
||||
case ST_CHARGING:
|
||||
if (pmu_blink_led(0))
|
||||
next_state = ST_CHARGING_ERROR;
|
||||
else
|
||||
enable_charging(1);
|
||||
break;
|
||||
case ST_CHARGING_ERROR:
|
||||
/*
|
||||
* Enable hardware charging circuit after set
|
||||
* PMU to hardware error state.
|
||||
*/
|
||||
if (pmu_blink_led(1))
|
||||
enable_charging(0);
|
||||
else
|
||||
enable_charging(1);
|
||||
break;
|
||||
case ST_IDLE:
|
||||
case ST_IDLE0:
|
||||
case ST_BAD_COND:
|
||||
case ST_DISCHARGING:
|
||||
enable_charging(0);
|
||||
/* Ignore charger error when discharging */
|
||||
pmu_blink_led(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (current_state) {
|
||||
case ST_CHARGING:
|
||||
case ST_CHARGING_ERROR:
|
||||
wait_time = T2_USEC;
|
||||
break;
|
||||
case ST_DISCHARGING:
|
||||
wait_time = T3_USEC;
|
||||
break;
|
||||
case ST_PRE_CHARGING:
|
||||
wait_time = T1_USEC;
|
||||
if (get_time().val - pre_chg_start.val >=
|
||||
PRE_CHARGING_TIMEOUT)
|
||||
enable_charging(0);
|
||||
break;
|
||||
default:
|
||||
if (extpower_is_present()) {
|
||||
wait_time = T1_USEC;
|
||||
break;
|
||||
} else if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
|
||||
wait_time = T1_OFF_USEC;
|
||||
enable_sleep(SLEEP_MASK_CHARGING);
|
||||
} else if (chipset_in_state(CHIPSET_STATE_SUSPEND)) {
|
||||
wait_time = T1_SUSPEND_USEC;
|
||||
} else {
|
||||
wait_time = T1_USEC;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_pending_event) {
|
||||
task_wait_event(wait_time);
|
||||
disable_sleep(SLEEP_MASK_CHARGING);
|
||||
} else {
|
||||
has_pending_event = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pmu_task_throttled_wake(void)
|
||||
{
|
||||
timestamp_t now = get_time();
|
||||
if (now.val - last_waken.val >= HOOK_TICK_INTERVAL) {
|
||||
has_pending_event = 0;
|
||||
task_wake(TASK_ID_CHARGER);
|
||||
} else {
|
||||
has_pending_event = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void wake_pmu_task_if_necessary(void)
|
||||
{
|
||||
if (has_pending_event) {
|
||||
has_pending_event = 0;
|
||||
task_wake(TASK_ID_CHARGER);
|
||||
}
|
||||
}
|
||||
DECLARE_HOOK(HOOK_TICK, wake_pmu_task_if_necessary, HOOK_PRIO_DEFAULT);
|
||||
|
||||
/* Wake charging task on chipset events */
|
||||
static void pmu_chipset_events(void)
|
||||
{
|
||||
pmu_task_throttled_wake();
|
||||
}
|
||||
DECLARE_HOOK(HOOK_CHIPSET_STARTUP, pmu_chipset_events, HOOK_PRIO_DEFAULT);
|
||||
DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, pmu_chipset_events, HOOK_PRIO_DEFAULT);
|
||||
DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, pmu_chipset_events, HOOK_PRIO_DEFAULT);
|
||||
DECLARE_HOOK(HOOK_CHIPSET_RESUME, pmu_chipset_events, HOOK_PRIO_DEFAULT);
|
||||
|
||||
void pmu_irq_handler(enum gpio_signal signal)
|
||||
{
|
||||
pmu_task_throttled_wake();
|
||||
CPRINTS("Charger IRQ received");
|
||||
}
|
||||
|
|
@ -1,159 +0,0 @@
|
|||
/* 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.
|
||||
*
|
||||
* TPSChrome powerinfo commands.
|
||||
*/
|
||||
|
||||
#include "battery.h"
|
||||
#include "console.h"
|
||||
#include "extpower.h"
|
||||
#include "host_command.h"
|
||||
#include "pmu_tpschrome.h"
|
||||
#include "util.h"
|
||||
|
||||
/*
|
||||
* All these constants are specific to the Pit board. If we reuse this command
|
||||
* on other boards, we'll need to move the table to board.c.
|
||||
*/
|
||||
static const struct {
|
||||
const char *name;
|
||||
int voltage_mv;
|
||||
int current_range_ma;
|
||||
} pmu_fet[] = {
|
||||
{"backlight", 11400, 1100},
|
||||
{"video" , 5000, 220},
|
||||
{"wwan" , 3300, 3300},
|
||||
{"sdcard" , 3300, 1100},
|
||||
{"camera" , 3300, 1100},
|
||||
{"lcd" , 3300, 1100},
|
||||
{"video_add", 5000, 1100},
|
||||
}, pmu_dcdc[] = {
|
||||
{"p5000", 5050, 5000},
|
||||
{"p3300", 3333, 5000},
|
||||
{"p1350", 1350, 5000},
|
||||
};
|
||||
|
||||
/* These constants may be Pit-specific as well. */
|
||||
static const int pmu_voltage_range_mv = 17000;
|
||||
static const int pmu_ac_sense_range_mv = 33;
|
||||
static const int pmu_bat_sense_range_mv = 40;
|
||||
static const int pmu_adc_resolution = 1024;
|
||||
static const int pmu_sense_resistor_bat = CONFIG_CHARGER_SENSE_RESISTOR;
|
||||
static const int pmu_sense_resistor_ac = CONFIG_CHARGER_SENSE_RESISTOR_AC;
|
||||
|
||||
static inline int calc_voltage(int adc_value, int range_mv)
|
||||
{
|
||||
return adc_value * range_mv / pmu_adc_resolution;
|
||||
}
|
||||
|
||||
static inline int calc_current(int adc_value, int range_ma)
|
||||
{
|
||||
return adc_value * range_ma / pmu_adc_resolution;
|
||||
}
|
||||
|
||||
static inline int calc_current_sr(int adc_value, int sense_resistor_mohm,
|
||||
int range_mv)
|
||||
{
|
||||
return adc_value * range_mv * 1000 / sense_resistor_mohm /
|
||||
pmu_adc_resolution;
|
||||
}
|
||||
|
||||
static int command_powerinfo(int argc, char **argv)
|
||||
{
|
||||
int voltage, current;
|
||||
int index;
|
||||
|
||||
ccputs("[pmu powerinfo]\n");
|
||||
/* DC to DC converter */
|
||||
for (index = 0; index < ARRAY_SIZE(pmu_dcdc); index++) {
|
||||
current = calc_current(
|
||||
pmu_adc_read(ADC_IDCDC1 + index, ADC_FLAG_KEEP_ON),
|
||||
pmu_dcdc[index].current_range_ma);
|
||||
voltage = pmu_dcdc[index].voltage_mv;
|
||||
ccprintf("DCDC%d:%6d mV,%4d mA,%4d mW %s\n",
|
||||
index + 1, voltage, current, voltage * current / 1000,
|
||||
pmu_dcdc[index].name);
|
||||
}
|
||||
|
||||
/* FET */
|
||||
for (index = 0; index < ARRAY_SIZE(pmu_fet); index++) {
|
||||
current = calc_current(
|
||||
pmu_adc_read(ADC_IFET1 + index, ADC_FLAG_KEEP_ON),
|
||||
pmu_fet[index].current_range_ma);
|
||||
voltage = pmu_fet[index].voltage_mv;
|
||||
ccprintf("FET%d :%6d mV,%4d mA,%4d mW %s\n",
|
||||
index + 1, voltage, current, voltage * current / 1000,
|
||||
pmu_fet[index].name);
|
||||
}
|
||||
|
||||
/* Battery charging */
|
||||
voltage = calc_voltage(
|
||||
pmu_adc_read(ADC_VBAT, ADC_FLAG_KEEP_ON),
|
||||
pmu_voltage_range_mv);
|
||||
current = calc_current_sr(
|
||||
pmu_adc_read(ADC_IBAT, ADC_FLAG_KEEP_ON),
|
||||
pmu_sense_resistor_bat, pmu_bat_sense_range_mv);
|
||||
ccprintf("Chg :%6d mV,%4d mA,%4d mW\n", voltage, current,
|
||||
voltage * current / 1000);
|
||||
|
||||
/* AC input */
|
||||
voltage = calc_voltage(
|
||||
pmu_adc_read(ADC_VAC, ADC_FLAG_KEEP_ON),
|
||||
pmu_voltage_range_mv);
|
||||
current = calc_current_sr(
|
||||
pmu_adc_read(ADC_IAC, 0),
|
||||
pmu_sense_resistor_ac, pmu_ac_sense_range_mv);
|
||||
ccprintf("AC :%6d mV,%4d mA,%4d mW\n", voltage, current,
|
||||
voltage * current / 1000);
|
||||
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
DECLARE_CONSOLE_COMMAND(powerinfo, command_powerinfo,
|
||||
NULL,
|
||||
"Show PMU power info");
|
||||
|
||||
/**
|
||||
* Host command to get power info from PMU
|
||||
*
|
||||
* This reuses the same EC_CMD_POWER_INFO host command as Spring, but doesn't
|
||||
* provide the full set of information because Pit doesn't take power over USB.
|
||||
*/
|
||||
static int power_command_info(struct host_cmd_handler_args *args)
|
||||
{
|
||||
struct ec_response_power_info *r = args->response;
|
||||
|
||||
r->voltage_ac = calc_voltage(
|
||||
pmu_adc_read(ADC_VAC, ADC_FLAG_KEEP_ON),
|
||||
pmu_voltage_range_mv);
|
||||
if (extpower_is_present()) {
|
||||
/* Power source = AC */
|
||||
r->voltage_system = r->voltage_ac;
|
||||
r->current_system = calc_current_sr(
|
||||
pmu_adc_read(ADC_IAC, ADC_FLAG_KEEP_ON),
|
||||
pmu_sense_resistor_ac, pmu_ac_sense_range_mv);
|
||||
} else {
|
||||
/* Power source == battery */
|
||||
struct batt_params batt;
|
||||
|
||||
r->voltage_system = calc_voltage(
|
||||
pmu_adc_read(ADC_VBAT, ADC_FLAG_KEEP_ON),
|
||||
pmu_voltage_range_mv);
|
||||
/*
|
||||
* PMU reads charging current. When battery is discharging, ADC
|
||||
* returns 0. Use battery gas gauge output instead.
|
||||
*/
|
||||
battery_get_params(&batt);
|
||||
r->current_system = -batt.current;
|
||||
}
|
||||
|
||||
/* Ignore USB powerinfo fields. */
|
||||
r->usb_dev_type = 0;
|
||||
r->usb_current_limit = 0;
|
||||
|
||||
args->response_size = sizeof(*r);
|
||||
|
||||
return EC_RES_SUCCESS;
|
||||
}
|
||||
DECLARE_HOST_COMMAND(EC_CMD_POWER_INFO, power_command_info, EC_VER_MASK(0));
|
|
@ -1,298 +0,0 @@
|
|||
/* 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.
|
||||
*
|
||||
* TPSChrome PMU APIs.
|
||||
*/
|
||||
|
||||
#ifndef __CROS_EC_PMU_TPSCHROME_H
|
||||
#define __CROS_EC_PMU_TPSCHROME_H
|
||||
|
||||
#include "gpio.h"
|
||||
|
||||
/* Non-SBS charging states */
|
||||
enum charging_state {
|
||||
ST_IDLE0,
|
||||
ST_IDLE,
|
||||
ST_BAD_COND,
|
||||
ST_PRE_CHARGING,
|
||||
ST_CHARGING,
|
||||
ST_CHARGING_ERROR,
|
||||
ST_DISCHARGING,
|
||||
};
|
||||
|
||||
/* Debugging constants, in the same order as enum power_state. This string
|
||||
* table was moved here to sync with enum above.
|
||||
*/
|
||||
#define CHARGE_STATE_NAME_TABLE { \
|
||||
"idle0", \
|
||||
"idle", \
|
||||
"bad cond", \
|
||||
"pre-charging", \
|
||||
"charging", \
|
||||
"charging error", \
|
||||
"discharging" \
|
||||
}
|
||||
/* End of CHARGE_STATE_NAME_TABLE macro */
|
||||
|
||||
/* JEITA temperature threshold */
|
||||
enum TPS_TEMPERATURE {
|
||||
TSET_T1,
|
||||
TSET_T2,
|
||||
TSET_T3,
|
||||
TSET_T4,
|
||||
};
|
||||
|
||||
/* JEITA temperature range */
|
||||
enum TPS_TEMPERATURE_RANGE {
|
||||
RANGE_T01,
|
||||
RANGE_T12, /* low charging temperature range */
|
||||
RANGE_T23, /* standard charging temperature range */
|
||||
RANGE_T34, /* high charging temperature range */
|
||||
RANGE_T40,
|
||||
};
|
||||
|
||||
/* Termination voltage */
|
||||
enum TPS_TERMINATION_VOLTAGE {
|
||||
TERM_V2000, /* 2.000 V */
|
||||
TERM_V2050, /* 2.050 V */
|
||||
TERM_V2075, /* 2.075 V */
|
||||
TERM_V2100, /* 2.100 V */
|
||||
};
|
||||
|
||||
/* Termination current */
|
||||
enum TPS_TERMINATION_CURRENT {
|
||||
TERM_I0000, /* 0 % */
|
||||
TERM_I0250, /* 25 % */
|
||||
TERM_I0375, /* 37.5 % */
|
||||
TERM_I0500, /* 50 % */
|
||||
TERM_I0625, /* 62.5 % */
|
||||
TERM_I0750, /* 75 % */
|
||||
TERM_I0875, /* 87.5 % */
|
||||
TERM_I1000, /* 100 % */
|
||||
};
|
||||
|
||||
/* Fast charge timeout */
|
||||
enum FASTCHARGE_TIMEOUT {
|
||||
TIMEOUT_2HRS,
|
||||
TIMEOUT_3HRS,
|
||||
TIMEOUT_4HRS,
|
||||
TIMEOUT_5HRS,
|
||||
TIMEOUT_6HRS,
|
||||
TIMEOUT_7HRS,
|
||||
TIMEOUT_8HRS,
|
||||
TIMEOUT_10HRS, /* No 9 hours option */
|
||||
};
|
||||
|
||||
#define FET_BACKLIGHT 1
|
||||
#define FET_WWAN 3
|
||||
#define FET_VIDEO 4
|
||||
#define FET_CAMERA 5
|
||||
#define FET_LCD_PANEL 6
|
||||
#define FET_TS 7
|
||||
|
||||
#define ADC_VAC 0
|
||||
#define ADC_VBAT 1
|
||||
#define ADC_IAC 2
|
||||
#define ADC_IBAT 3
|
||||
#define ADC_IDCDC1 4
|
||||
#define ADC_IDCDC2 5
|
||||
#define ADC_IDCDC3 6
|
||||
#define ADC_IFET1 7
|
||||
#define ADC_IFET2 8
|
||||
#define ADC_IFET3 9
|
||||
#define ADC_IFET4 10
|
||||
#define ADC_IFET5 11
|
||||
#define ADC_IFET6 12
|
||||
#define ADC_IFET7 13
|
||||
|
||||
/* do not turn off voltage reference */
|
||||
#define ADC_FLAG_KEEP_ON 0x1
|
||||
|
||||
/**
|
||||
* Clear tps65090 IRQ register
|
||||
*
|
||||
* @return return EC_SUCCESS on success, err code otherwise
|
||||
*/
|
||||
int pmu_clear_irq(void);
|
||||
|
||||
/**
|
||||
* Read pmu register
|
||||
*
|
||||
* @param reg register offset
|
||||
* @param value pointer to output value
|
||||
* @return return EC_SUCCESS on success, err code otherwise
|
||||
*/
|
||||
int pmu_read(int reg, int *value);
|
||||
|
||||
/**
|
||||
* Write pmu register
|
||||
*
|
||||
* @param reg register offset
|
||||
* @param value new register value
|
||||
* @return return EC_SUCCESS on success, err code otherwise
|
||||
*/
|
||||
int pmu_write(int reg, int value);
|
||||
|
||||
/**
|
||||
* Read tpschrome version
|
||||
*
|
||||
* @param version output tpschrome version info
|
||||
*/
|
||||
int pmu_version(int *version);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Check pmu charge timeout
|
||||
*
|
||||
* @return 1 if charge timed out
|
||||
*/
|
||||
int pmu_is_charge_timeout(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 force charging mode
|
||||
*
|
||||
* @param enable 0 to disable the charger, 1 to enable
|
||||
* @return EC_SUCCESS if no I2C communication error
|
||||
*/
|
||||
int pmu_enable_charger(int enable);
|
||||
|
||||
/**
|
||||
* Set termination current for temperature ranges
|
||||
*
|
||||
* @param range T01 T12 T23 T34 T40
|
||||
* @param current enum termination current, I0250 == 25.0%:
|
||||
* I0000 I0250 I0375 I0500 I0625 I0750 I0875 I1000
|
||||
*/
|
||||
int pmu_set_term_current(enum TPS_TEMPERATURE_RANGE range,
|
||||
enum TPS_TERMINATION_CURRENT current);
|
||||
|
||||
/**
|
||||
* Set termination voltage for temperature ranges
|
||||
*
|
||||
* @param range T01 T12 T23 T34 T40
|
||||
* @param voltage enum termination voltage, V2050 == 2.05V:
|
||||
* V2000 V2050 V2075 V2100
|
||||
*/
|
||||
int pmu_set_term_voltage(enum TPS_TEMPERATURE_RANGE range,
|
||||
enum TPS_TERMINATION_VOLTAGE voltage);
|
||||
|
||||
/**
|
||||
* Enable low current charging
|
||||
*
|
||||
* @param enable enable/disable low current charging
|
||||
*/
|
||||
int pmu_low_current_charging(int enable);
|
||||
|
||||
/**
|
||||
* Read ADC channel
|
||||
*
|
||||
* @param adc_idx Index of ADC channel
|
||||
* @param flags combination of ADC_FLAG_* constants
|
||||
*/
|
||||
int pmu_adc_read(int adc_idx, int flags);
|
||||
|
||||
#ifdef HAS_TASK_CHARGER
|
||||
/**
|
||||
* Handles charger interrupts from tpschrome
|
||||
*
|
||||
* @param signal Indicates signal type.
|
||||
*/
|
||||
void pmu_irq_handler(enum gpio_signal signal);
|
||||
#else
|
||||
#define pmu_irq_handler NULL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set temperature threshold
|
||||
*
|
||||
* @param temp_n TSET_T1 to TSET_T4
|
||||
* @param value 0b000 ~ 0b111, temperature threshold
|
||||
*/
|
||||
int pmu_set_temp_threshold(enum TPS_TEMPERATURE temp_n, uint8_t value);
|
||||
|
||||
/**
|
||||
* Force charger into error state, turn off charging and blinks charging LED
|
||||
*
|
||||
* @param enable true to turn off charging and blink LED
|
||||
* @return EC_SUCCESS if ok
|
||||
*/
|
||||
int pmu_blink_led(int enable);
|
||||
|
||||
/**
|
||||
* * Initialize pmu
|
||||
* */
|
||||
void pmu_init(void);
|
||||
|
||||
/**
|
||||
* Shut down the pmu, by resetting it's registers to disable it's FETs,
|
||||
* DCDCs and ADC.
|
||||
*/
|
||||
int pmu_shutdown(void);
|
||||
|
||||
/**
|
||||
* Set external charge enable pin
|
||||
*
|
||||
* @param enable boolean, set 1 to eanble external control
|
||||
*/
|
||||
int pmu_enable_ext_control(int enable);
|
||||
|
||||
/**
|
||||
* Set fast charge timeout
|
||||
*
|
||||
* @param timeout enum FASTCHARGE_TIMEOUT
|
||||
*/
|
||||
int pmu_set_fastcharge(enum FASTCHARGE_TIMEOUT timeout);
|
||||
|
||||
/**
|
||||
* Wake TPS65090 charger task, but throttled to at most one call per tick
|
||||
*/
|
||||
void pmu_task_throttled_wake(void);
|
||||
|
||||
/**
|
||||
* Get current charge state
|
||||
*/
|
||||
enum charging_state charge_get_state(void);
|
||||
|
||||
/**
|
||||
* Return non-zero if battery is so low we want to keep AP off.
|
||||
*/
|
||||
int charge_keep_power_off(void);
|
||||
|
||||
/**
|
||||
* Initialize PMU registers using board settings.
|
||||
*
|
||||
* Boards must supply this function. This will be called from pmu_init().
|
||||
*
|
||||
* @return EC_SUCCESS, or non-zero if error.
|
||||
*/
|
||||
int pmu_board_init(void);
|
||||
|
||||
#endif /* __CROS_EC_PMU_TPSCHROME_H */
|
||||
|
|
@ -9,7 +9,6 @@
|
|||
power-$(CONFIG_CHIPSET_APOLLOLAKE)+=apollolake.o intel_x86.o
|
||||
power-$(CONFIG_CHIPSET_BRASWELL)+=braswell.o
|
||||
power-$(CONFIG_CHIPSET_ECDRIVEN)+=ec_driven.o
|
||||
power-$(CONFIG_CHIPSET_GAIA)+=gaia.o
|
||||
power-$(CONFIG_CHIPSET_MEDIATEK)+=mediatek.o
|
||||
power-$(CONFIG_CHIPSET_RK3399)+=rk3399.o
|
||||
power-$(CONFIG_CHIPSET_ROCKCHIP)+=rockchip.o
|
||||
|
|
747
power/gaia.c
747
power/gaia.c
|
@ -1,747 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* GAIA SoC power sequencing module for Chrome EC
|
||||
*
|
||||
* This implements the following features:
|
||||
*
|
||||
* - Cold reset powers off the AP
|
||||
*
|
||||
* When powered off:
|
||||
* - Press pwron turns on the AP
|
||||
* - Hold pwron turns on the AP, and then 16s later turns it off and leaves
|
||||
* it off until pwron is released and pressed again
|
||||
*
|
||||
* When powered on:
|
||||
* - The PMIC PWRON signal is released <= 1 second after the power button is
|
||||
* released (we expect that U-Boot as asserted XPSHOLD by then)
|
||||
* - Holding pwron for 8s powers off the AP
|
||||
* - Pressing and releasing pwron within that 8s is ignored
|
||||
* - If XPSHOLD is dropped by the AP, then we power the AP off
|
||||
*/
|
||||
|
||||
#include "battery.h"
|
||||
#include "clock.h"
|
||||
#include "chipset.h" /* This module implements chipset functions too */
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "gpio.h"
|
||||
#include "hooks.h"
|
||||
#include "lid_switch.h"
|
||||
#include "keyboard_scan.h"
|
||||
#include "power_led.h"
|
||||
#include "pmu_tpschrome.h"
|
||||
#include "system.h"
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Console output macros */
|
||||
#define CPUTS(outstr) cputs(CC_CHIPSET, outstr)
|
||||
#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args)
|
||||
|
||||
/* Time necessary for the 5V and 3.3V regulator outputs to stabilize */
|
||||
#ifdef BOARD_PIT
|
||||
#define DELAY_5V_SETUP (2 * MSEC)
|
||||
#define DELAY_3V_SETUP (2 * MSEC)
|
||||
#else
|
||||
#define DELAY_5V_SETUP MSEC
|
||||
#endif
|
||||
|
||||
/* Delay between 1.35v and 3.3v rails startup */
|
||||
#define DELAY_RAIL_STAGGERING 100 /* 100us */
|
||||
|
||||
/* Long power key press to force shutdown */
|
||||
#define DELAY_FORCE_SHUTDOWN (8 * SECOND)
|
||||
|
||||
/* Time necessary for pulling down XPSHOLD to shutdown PMIC power */
|
||||
#define DELAY_XPSHOLD_PULL (2 * MSEC)
|
||||
|
||||
/*
|
||||
* If the power key is pressed to turn on, then held for this long, we
|
||||
* power off.
|
||||
*
|
||||
* The idea here is that behavior for 8s for AP shutdown is unchanged
|
||||
* but power-on is modified to allow enough time U-Boot to be updated
|
||||
* via USB (which takes about 10sec).
|
||||
*
|
||||
* So after power button is pressed:
|
||||
|
||||
* Normal case: User releases power button and chipset_task() goes
|
||||
* into the inner loop, waiting for next event to occur (power button
|
||||
* press or XPSHOLD == 0).
|
||||
*
|
||||
* U-Boot updating: User presses and holds power button. If EC does not
|
||||
* see XPSHOLD, it waits up to 16sec for an event. If no event occurs
|
||||
* within 16sec, EC powers off AP.
|
||||
*/
|
||||
#define DELAY_SHUTDOWN_ON_POWER_HOLD (8 * SECOND)
|
||||
#define DELAY_SHUTDOWN_ON_USB_BOOT (16 * SECOND)
|
||||
|
||||
/* Maximum delay after power button press before we deassert GPIO_PMIC_PWRON */
|
||||
#define DELAY_RELEASE_PWRON SECOND /* 1s */
|
||||
|
||||
/* debounce time to prevent accidental power-on after keyboard power off */
|
||||
#define KB_PWR_ON_DEBOUNCE 250 /* 250us */
|
||||
|
||||
/* debounce time to prevent accidental power event after lid open/close */
|
||||
#define LID_SWITCH_DEBOUNCE 250 /* 250us */
|
||||
|
||||
/* PMIC fails to set the LDO2 output */
|
||||
#define PMIC_TIMEOUT (100 * MSEC) /* 100ms */
|
||||
|
||||
/* Default timeout for input transition */
|
||||
#define FAIL_TIMEOUT (500 * MSEC) /* 500ms */
|
||||
|
||||
|
||||
/* Application processor power state */
|
||||
static int ap_on;
|
||||
static int ap_suspended;
|
||||
|
||||
/* simulated event state */
|
||||
static int force_signal = -1;
|
||||
static int force_value;
|
||||
|
||||
/* 1 if the power button was pressed last time we checked */
|
||||
static char power_button_was_pressed;
|
||||
|
||||
/* 1 if lid-open event has been detected */
|
||||
static char lid_opened;
|
||||
|
||||
/* time where we will power off, if power button still held down */
|
||||
static timestamp_t power_off_deadline;
|
||||
|
||||
/* force AP power on (used for recovery keypress) */
|
||||
static int auto_power_on;
|
||||
|
||||
enum power_request_t {
|
||||
POWER_REQ_NONE,
|
||||
POWER_REQ_OFF,
|
||||
POWER_REQ_ON,
|
||||
|
||||
POWER_REQ_COUNT,
|
||||
};
|
||||
|
||||
static enum power_request_t power_request;
|
||||
|
||||
/**
|
||||
* Wait for GPIO "signal" to reach level "value".
|
||||
* Returns EC_ERROR_TIMEOUT if timeout before reaching the desired state.
|
||||
*
|
||||
* @param signal Signal to watch
|
||||
* @param value Value to watch for
|
||||
* @param timeout Timeout in microseconds from now, or -1 to wait forever
|
||||
* @return 0 if signal did change to required value, EC_ERROR_TIMEOUT if we
|
||||
* timed out first.
|
||||
*/
|
||||
static int wait_in_signal(enum gpio_signal signal, int value, int timeout)
|
||||
{
|
||||
timestamp_t deadline;
|
||||
timestamp_t now = get_time();
|
||||
|
||||
deadline.val = now.val + timeout;
|
||||
|
||||
while (((force_signal != signal) || (force_value != value)) &&
|
||||
gpio_get_level(signal) != value) {
|
||||
now = get_time();
|
||||
if (timeout < 0) {
|
||||
task_wait_event(-1);
|
||||
} else if (timestamp_expired(deadline, &now) ||
|
||||
(task_wait_event(deadline.val - now.val) ==
|
||||
TASK_EVENT_TIMER)) {
|
||||
CPRINTS("power timeout waiting for GPIO %d/%s",
|
||||
signal, gpio_get_name(signal));
|
||||
return EC_ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the PMIC PWROK signal.
|
||||
*
|
||||
* @param asserted Assert (=1) or deassert (=0) the signal. This is the
|
||||
* logical level of the pin, not the physical level.
|
||||
*/
|
||||
static void set_pmic_pwrok(int asserted)
|
||||
{
|
||||
#ifdef BOARD_PIT
|
||||
/* Signal is active-high */
|
||||
gpio_set_level(GPIO_PMIC_PWRON, asserted);
|
||||
#else
|
||||
/* Signal is active-low */
|
||||
gpio_set_level(GPIO_PMIC_PWRON_L, asserted ? 0 : 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check for some event triggering the shutdown.
|
||||
*
|
||||
* It can be either a long power button press or a shutdown triggered from the
|
||||
* AP and detected by reading XPSHOLD.
|
||||
*
|
||||
* @return 1 if a shutdown should happen, 0 if not
|
||||
*/
|
||||
static int check_for_power_off_event(void)
|
||||
{
|
||||
timestamp_t now;
|
||||
int pressed = 0;
|
||||
|
||||
/* Check for power button press */
|
||||
if (gpio_get_level(GPIO_KB_PWR_ON_L) == 0) {
|
||||
udelay(KB_PWR_ON_DEBOUNCE);
|
||||
if (gpio_get_level(GPIO_KB_PWR_ON_L) == 0)
|
||||
pressed = 1;
|
||||
}
|
||||
|
||||
now = get_time();
|
||||
if (pressed) {
|
||||
set_pmic_pwrok(1);
|
||||
|
||||
if (!power_button_was_pressed) {
|
||||
power_off_deadline.val = now.val + DELAY_FORCE_SHUTDOWN;
|
||||
CPRINTS("power waiting for long press %u",
|
||||
power_off_deadline.le.lo);
|
||||
} else if (timestamp_expired(power_off_deadline, &now)) {
|
||||
power_off_deadline.val = 0;
|
||||
CPRINTS("power off after long press now=%u, %u",
|
||||
now.le.lo, power_off_deadline.le.lo);
|
||||
return 2;
|
||||
}
|
||||
} else if (power_button_was_pressed) {
|
||||
CPRINTS("power off cancel");
|
||||
set_pmic_pwrok(0);
|
||||
}
|
||||
|
||||
power_button_was_pressed = pressed;
|
||||
|
||||
/* XPSHOLD released by AP : shutdown immediately */
|
||||
if (gpio_get_level(GPIO_SOC1V8_XPSHOLD) == 0)
|
||||
return 3;
|
||||
|
||||
if (power_request == POWER_REQ_OFF) {
|
||||
power_request = POWER_REQ_NONE;
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deferred handling for suspend events
|
||||
*
|
||||
* The suspend event needs to be able to call the suspend and resume hooks.
|
||||
* This cannot be done from interrupt level, since the handlers from those
|
||||
* hooks may need to use mutexes or other functionality not present at
|
||||
* interrupt level. Use a deferred function instead.
|
||||
*
|
||||
* Deferred functions are called from the hook task and not the chipset task,
|
||||
* so that's a slight deviation from the spec in hooks.h, but a minor one.
|
||||
*/
|
||||
static void gaia_suspend_deferred(void)
|
||||
{
|
||||
int new_ap_suspended;
|
||||
|
||||
if (!ap_on) /* power on/off : not a real suspend / resume */
|
||||
return;
|
||||
|
||||
/*
|
||||
* Note: For Snow, suspend state can only be reliably
|
||||
* determined when the AP is on (crosbug.com/p/13200).
|
||||
*/
|
||||
new_ap_suspended = !gpio_get_level(GPIO_SUSPEND_L);
|
||||
|
||||
/* We never want to call two suspend or two resumes in a row */
|
||||
if (ap_suspended == new_ap_suspended)
|
||||
return;
|
||||
|
||||
ap_suspended = new_ap_suspended;
|
||||
|
||||
if (ap_suspended) {
|
||||
if (lid_is_open())
|
||||
powerled_set_state(POWERLED_STATE_SUSPEND);
|
||||
else
|
||||
powerled_set_state(POWERLED_STATE_OFF);
|
||||
/* Call hooks here since we don't know it prior to AP suspend */
|
||||
hook_notify(HOOK_CHIPSET_SUSPEND);
|
||||
} else {
|
||||
powerled_set_state(POWERLED_STATE_ON);
|
||||
hook_notify(HOOK_CHIPSET_RESUME);
|
||||
}
|
||||
|
||||
}
|
||||
DECLARE_DEFERRED(gaia_suspend_deferred);
|
||||
|
||||
void power_signal_interrupt(enum gpio_signal signal)
|
||||
{
|
||||
if (signal == GPIO_SUSPEND_L) {
|
||||
/* Handle suspend events in the hook task */
|
||||
hook_call_deferred(&gaia_suspend_deferred_data, 0);
|
||||
} else {
|
||||
/* All other events are handled in the chipset task */
|
||||
task_wake(TASK_ID_CHIPSET);
|
||||
}
|
||||
}
|
||||
|
||||
static void gaia_lid_event(void)
|
||||
{
|
||||
/* Power task only cares about lid-open events */
|
||||
if (!lid_is_open())
|
||||
return;
|
||||
|
||||
lid_opened = 1;
|
||||
task_wake(TASK_ID_CHIPSET);
|
||||
}
|
||||
DECLARE_HOOK(HOOK_LID_CHANGE, gaia_lid_event, HOOK_PRIO_DEFAULT);
|
||||
|
||||
static int gaia_power_init(void)
|
||||
{
|
||||
/* Enable interrupts for our GPIOs */
|
||||
gpio_enable_interrupt(GPIO_KB_PWR_ON_L);
|
||||
gpio_enable_interrupt(GPIO_SOC1V8_XPSHOLD);
|
||||
gpio_enable_interrupt(GPIO_SUSPEND_L);
|
||||
gpio_enable_interrupt(GPIO_PP1800_LDO2);
|
||||
|
||||
/* Leave power off only if requested by reset flags */
|
||||
if (!(system_get_reset_flags() & RESET_FLAG_AP_OFF)) {
|
||||
CPRINTS("auto_power_on is set due to reset_flag 0x%x",
|
||||
system_get_reset_flags());
|
||||
auto_power_on = 1;
|
||||
}
|
||||
|
||||
#ifdef BOARD_PIT
|
||||
/*
|
||||
* Force the AP into reset unless we're doing a sysjump. Otherwise a
|
||||
* suspended AP may still be in a strange state from the last reboot,
|
||||
* and will hold XPSHOLD for a long time if it's in a low power state.
|
||||
* See crosbug.com/p/22233.
|
||||
*/
|
||||
if (!(system_get_reset_flags() & RESET_FLAG_SYSJUMP)) {
|
||||
CPRINTS("not sysjump; forcing AP reset");
|
||||
gpio_set_level(GPIO_AP_RESET_L, 0);
|
||||
udelay(1000);
|
||||
gpio_set_level(GPIO_AP_RESET_L, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Chipset interface */
|
||||
|
||||
int chipset_in_state(int state_mask)
|
||||
{
|
||||
/* If AP is off, match any off state for now */
|
||||
if ((state_mask & CHIPSET_STATE_ANY_OFF) && !ap_on)
|
||||
return 1;
|
||||
|
||||
/* If AP is on, match on state */
|
||||
if ((state_mask & CHIPSET_STATE_ON) && ap_on && !ap_suspended)
|
||||
return 1;
|
||||
|
||||
/* if AP is suspended, match on state */
|
||||
if ((state_mask & CHIPSET_STATE_SUSPEND) && ap_on && ap_suspended)
|
||||
return 1;
|
||||
|
||||
/* In any other case, we don't have a match */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void chipset_exit_hard_off(void)
|
||||
{
|
||||
/*
|
||||
* TODO(crosbug.com/p/23822): Implement, if/when we take the AP down to
|
||||
* a hard-off state.
|
||||
*/
|
||||
}
|
||||
|
||||
void chipset_reset(int is_cold)
|
||||
{
|
||||
/*
|
||||
* TODO(crosbug.com/p/23822): Implement cold reset. For now, all
|
||||
* resets are warm resets.
|
||||
*/
|
||||
CPRINTS("EC triggered warm reboot");
|
||||
|
||||
/*
|
||||
* This is a hack to do an AP warm reboot while still preserving RAM
|
||||
* contents. This is useful for looking at kernel log message contents
|
||||
* from previous boot in cases where the AP/OS is hard hung.
|
||||
*/
|
||||
#ifdef CONFIG_CHIPSET_HAS_PP5000
|
||||
gpio_set_level(GPIO_EN_PP5000, 0);
|
||||
#endif
|
||||
gpio_set_level(GPIO_EN_PP3300, 0);
|
||||
|
||||
power_request = POWER_REQ_ON;
|
||||
task_wake(TASK_ID_CHIPSET);
|
||||
}
|
||||
|
||||
void chipset_force_shutdown(void)
|
||||
{
|
||||
/* Turn off all rails */
|
||||
gpio_set_level(GPIO_EN_PP3300, 0);
|
||||
#ifdef CONFIG_CHIPSET_HAS_PP1350
|
||||
/*
|
||||
* Turn off PP1350 unless we're immediately waking back up. This
|
||||
* works with the hack in chipset_reset() to preserve the contents of
|
||||
* RAM across a reset.
|
||||
*/
|
||||
if (power_request != POWER_REQ_ON)
|
||||
gpio_set_level(GPIO_EN_PP1350, 0);
|
||||
#endif
|
||||
set_pmic_pwrok(0);
|
||||
#ifdef CONFIG_CHIPSET_HAS_PP5000
|
||||
gpio_set_level(GPIO_EN_PP5000, 0);
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_PIT
|
||||
/*
|
||||
* Force the AP into reset. Otherwise it will hold XPSHOLD for a long
|
||||
* time if it's in a low power state. See crosbug.com/p/22233.
|
||||
*/
|
||||
gpio_set_level(GPIO_AP_RESET_L, 0);
|
||||
udelay(1000);
|
||||
gpio_set_level(GPIO_AP_RESET_L, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Check if there has been a power-on event
|
||||
*
|
||||
* This checks all power-on event signals and returns non-zero if any have been
|
||||
* triggered (with debounce taken into account).
|
||||
*
|
||||
* @return non-zero if there has been a power-on event, 0 if not.
|
||||
*/
|
||||
static int check_for_power_on_event(void)
|
||||
{
|
||||
/* Check if we've already powered the system on */
|
||||
if (gpio_get_level(GPIO_EN_PP3300)) {
|
||||
CPRINTS("system is on, thus clear auto_power_on");
|
||||
auto_power_on = 0; /* no need to arrange another power on */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* power on requested at EC startup for recovery */
|
||||
if (auto_power_on) {
|
||||
auto_power_on = 0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Check lid open */
|
||||
if (lid_opened) {
|
||||
lid_opened = 0;
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* check for power button press */
|
||||
if (gpio_get_level(GPIO_KB_PWR_ON_L) == 0) {
|
||||
udelay(KB_PWR_ON_DEBOUNCE);
|
||||
if (gpio_get_level(GPIO_KB_PWR_ON_L) == 0)
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (power_request == POWER_REQ_ON) {
|
||||
power_request = POWER_REQ_NONE;
|
||||
return 5;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Power on the AP
|
||||
*
|
||||
* @return 0 if ok, -1 on error (PP1800_LDO2 failed to come on)
|
||||
*/
|
||||
static int power_on(void)
|
||||
{
|
||||
#ifdef CONFIG_CHIPSET_HAS_PP5000
|
||||
/* Enable 5v power rail */
|
||||
gpio_set_level(GPIO_EN_PP5000, 1);
|
||||
/* Wait for it to stabilize */
|
||||
usleep(DELAY_5V_SETUP);
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_PIT
|
||||
/*
|
||||
* 3.3V rail must come up right after 5V, because it sources power to
|
||||
* various buck supplies.
|
||||
*/
|
||||
gpio_set_level(GPIO_EN_PP3300, 1);
|
||||
usleep(DELAY_3V_SETUP);
|
||||
#endif
|
||||
if (gpio_get_level(GPIO_SOC1V8_XPSHOLD) == 0) {
|
||||
/* Initialize non-AP components */
|
||||
hook_notify(HOOK_CHIPSET_PRE_INIT);
|
||||
|
||||
/*
|
||||
* Initiate PMIC power-on sequence only if cold booting AP to
|
||||
* avoid accidental reset (crosbug.com/p/12650).
|
||||
*/
|
||||
set_pmic_pwrok(1);
|
||||
}
|
||||
|
||||
/* wait for all PMIC regulators to be ready */
|
||||
wait_in_signal(GPIO_PP1800_LDO2, 1, PMIC_TIMEOUT);
|
||||
|
||||
/*
|
||||
* If PP1800_LDO2 did not come up (e.g. PMIC_TIMEOUT was reached),
|
||||
* turn off 5V rail (and 3.3V, if turned on above) and start over.
|
||||
*/
|
||||
if (gpio_get_level(GPIO_PP1800_LDO2) == 0) {
|
||||
gpio_set_level(GPIO_EN_PP5000, 0);
|
||||
gpio_set_level(GPIO_EN_PP3300, 0);
|
||||
usleep(DELAY_5V_SETUP);
|
||||
CPRINTS("power error: PMIC failed to enable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Enable DDR 1.35v power rail */
|
||||
gpio_set_level(GPIO_EN_PP1350, 1);
|
||||
/* Wait to avoid large inrush current */
|
||||
usleep(DELAY_RAIL_STAGGERING);
|
||||
|
||||
/* Enable 3.3v power rail, if it's not already on */
|
||||
gpio_set_level(GPIO_EN_PP3300, 1);
|
||||
|
||||
ap_on = 1;
|
||||
disable_sleep(SLEEP_MASK_AP_RUN);
|
||||
powerled_set_state(POWERLED_STATE_ON);
|
||||
|
||||
/* Call hooks now that AP is running */
|
||||
hook_notify(HOOK_CHIPSET_STARTUP);
|
||||
|
||||
CPRINTS("AP running ...");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for the power button to be released
|
||||
*
|
||||
* @return 0 if ok, -1 if power button failed to release
|
||||
*/
|
||||
static int wait_for_power_button_release(unsigned int timeout_us)
|
||||
{
|
||||
/* wait for Power button release */
|
||||
wait_in_signal(GPIO_KB_PWR_ON_L, 1, timeout_us);
|
||||
|
||||
udelay(KB_PWR_ON_DEBOUNCE);
|
||||
if (gpio_get_level(GPIO_KB_PWR_ON_L) == 0) {
|
||||
CPRINTS("power button not released in time");
|
||||
return -1;
|
||||
}
|
||||
CPRINTS("power button released");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for the XPSHOLD signal from the AP to be asserted within timeout_us
|
||||
* and if asserted clear the PMIC_PWRON signal
|
||||
*
|
||||
* @return 0 if ok, -1 if power button failed to release
|
||||
*/
|
||||
static int react_to_xpshold(unsigned int timeout_us)
|
||||
{
|
||||
/* wait for Power button release */
|
||||
wait_in_signal(GPIO_SOC1V8_XPSHOLD, 1, timeout_us);
|
||||
|
||||
if (gpio_get_level(GPIO_SOC1V8_XPSHOLD) == 0) {
|
||||
CPRINTS("XPSHOLD not seen in time");
|
||||
return -1;
|
||||
}
|
||||
CPRINTS("XPSHOLD seen");
|
||||
set_pmic_pwrok(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Power off the AP
|
||||
*/
|
||||
static void power_off(void)
|
||||
{
|
||||
/* Call hooks before we drop power rails */
|
||||
hook_notify(HOOK_CHIPSET_SHUTDOWN);
|
||||
/* switch off all rails */
|
||||
chipset_force_shutdown();
|
||||
ap_on = 0;
|
||||
ap_suspended = 0;
|
||||
lid_opened = 0;
|
||||
enable_sleep(SLEEP_MASK_AP_RUN);
|
||||
powerled_set_state(POWERLED_STATE_OFF);
|
||||
#ifdef CONFIG_PMU_TPS65090
|
||||
pmu_shutdown();
|
||||
#endif
|
||||
CPRINTS("power shutdown complete");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Calculates the delay in microseconds to the next time we have to check
|
||||
* for a power event,
|
||||
*
|
||||
*@return delay to next check, or -1 if no future check is needed
|
||||
*/
|
||||
static int next_pwr_event(void)
|
||||
{
|
||||
if (!power_off_deadline.val)
|
||||
return -1;
|
||||
|
||||
return power_off_deadline.val - get_time().val;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int wait_for_power_on(void)
|
||||
{
|
||||
int value;
|
||||
while (1) {
|
||||
value = check_for_power_on_event();
|
||||
if (!value) {
|
||||
task_wait_event(-1);
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef HAS_TASK_CHARGER
|
||||
/*
|
||||
* If the system is already on (value == 1), the kernel
|
||||
* would handle low power condition and we should not
|
||||
* shutdown the system from EC.
|
||||
*/
|
||||
if (value != 1 && charge_keep_power_off()) {
|
||||
CPRINTS("power on ignored due to low battery");
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
CPRINTS("power on %d", value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
void chipset_task(void)
|
||||
{
|
||||
int value;
|
||||
|
||||
gaia_power_init();
|
||||
ap_on = 0;
|
||||
battery_wait_for_stable();
|
||||
|
||||
while (1) {
|
||||
/* Wait until we need to power on, then power on */
|
||||
wait_for_power_on();
|
||||
|
||||
if (!power_on()) {
|
||||
int continue_power = 0;
|
||||
|
||||
if (!react_to_xpshold(DELAY_RELEASE_PWRON)) {
|
||||
/* AP looks good */
|
||||
if (!wait_for_power_button_release(
|
||||
DELAY_SHUTDOWN_ON_POWER_HOLD))
|
||||
continue_power = 1;
|
||||
} else {
|
||||
/* AP is possibly in bad shape */
|
||||
/* allow USB boot in 16 secs */
|
||||
if (!wait_for_power_button_release(
|
||||
DELAY_SHUTDOWN_ON_USB_BOOT))
|
||||
continue_power = 1;
|
||||
}
|
||||
if (continue_power) {
|
||||
power_button_was_pressed = 0;
|
||||
while (!(value = check_for_power_off_event()))
|
||||
task_wait_event(next_pwr_event());
|
||||
CPRINTS("power ending loop %d", value);
|
||||
}
|
||||
}
|
||||
power_off();
|
||||
wait_for_power_button_release(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Console debug command */
|
||||
|
||||
static int command_force_power(int argc, char **argv)
|
||||
{
|
||||
/* simulate power button pressed */
|
||||
force_signal = GPIO_KB_PWR_ON_L;
|
||||
force_value = 1;
|
||||
/* Wake up the task */
|
||||
task_wake(TASK_ID_CHIPSET);
|
||||
/* Wait 100 ms */
|
||||
msleep(100);
|
||||
/* Release power button */
|
||||
force_signal = -1;
|
||||
force_value = 0;
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
DECLARE_CONSOLE_COMMAND(forcepower, command_force_power,
|
||||
NULL,
|
||||
"Force power on");
|
||||
|
||||
static const char *power_req_name[POWER_REQ_COUNT] = {
|
||||
"none",
|
||||
"off",
|
||||
"on",
|
||||
};
|
||||
|
||||
/* Power states that we can report */
|
||||
enum power_state_t {
|
||||
PSTATE_UNKNOWN,
|
||||
PSTATE_OFF,
|
||||
PSTATE_SUSPEND,
|
||||
PSTATE_ON,
|
||||
|
||||
PSTATE_COUNT,
|
||||
};
|
||||
|
||||
static const char * const state_name[] = {
|
||||
"unknown",
|
||||
"off",
|
||||
"suspend",
|
||||
"on",
|
||||
};
|
||||
|
||||
static int command_power(int argc, char **argv)
|
||||
{
|
||||
int v;
|
||||
|
||||
if (argc < 2) {
|
||||
enum power_state_t state;
|
||||
|
||||
state = PSTATE_UNKNOWN;
|
||||
if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
|
||||
state = PSTATE_OFF;
|
||||
if (chipset_in_state(CHIPSET_STATE_SUSPEND))
|
||||
state = PSTATE_SUSPEND;
|
||||
if (chipset_in_state(CHIPSET_STATE_ON))
|
||||
state = PSTATE_ON;
|
||||
ccprintf("%s\n", state_name[state]);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
if (!parse_bool(argv[1], &v))
|
||||
return EC_ERROR_PARAM1;
|
||||
|
||||
power_request = v ? POWER_REQ_ON : POWER_REQ_OFF;
|
||||
ccprintf("Requesting power %s\n", power_req_name[power_request]);
|
||||
task_wake(TASK_ID_CHIPSET);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
DECLARE_CONSOLE_COMMAND(power, command_power,
|
||||
"on/off",
|
||||
"Turn AP power on/off");
|
|
@ -10,7 +10,6 @@ test-list-y=pingpong timer_calib timer_dos timer_jump mutex utils
|
|||
#disable: powerdemo
|
||||
|
||||
test-list-$(BOARD_BDS)+=
|
||||
test-list-$(BOARD_PIT)+=kb_scan stress
|
||||
|
||||
# Samus has board-specific chipset code, and the tests don't
|
||||
# compile with it. Disable them for now.
|
||||
|
|
|
@ -30,11 +30,8 @@ struct i2c_test_param_t {
|
|||
int addr;
|
||||
int offset;
|
||||
int data; /* Non-negative represents data to write. -1 to read. */
|
||||
} i2c_test_params[] = {
|
||||
#if defined(BOARD_PIT)
|
||||
{8, 0, 0x90, 0x19, -1},
|
||||
#endif
|
||||
};
|
||||
} i2c_test_params[];
|
||||
|
||||
/* Disable I2C test for boards without test configuration */
|
||||
#if defined(BOARD_BDS) || defined(BOARD_AURON)
|
||||
#undef CONFIG_I2C
|
||||
|
|
Loading…
Reference in New Issue