diff options
-rw-r--r-- | chip/lm4/openocd/lm4x_cmds.tcl | 53 | ||||
-rw-r--r-- | chip/stm32/clock-stm32f.c | 17 | ||||
-rw-r--r-- | chip/stm32/power_led.c | 5 | ||||
-rw-r--r-- | common/build.mk | 3 | ||||
-rw-r--r-- | common/charge_state_v1.c | 5 | ||||
-rw-r--r-- | common/extpower_falco.c | 325 | ||||
-rw-r--r-- | common/extpower_snow.c | 46 | ||||
-rw-r--r-- | common/extpower_spring.c | 970 | ||||
-rw-r--r-- | common/host_command.c | 6 | ||||
-rw-r--r-- | common/lb_common.c | 9 | ||||
-rw-r--r-- | common/pmu_tps65090_charger.c | 20 | ||||
-rw-r--r-- | common/pmu_tps65090_powerinfo.c | 3 | ||||
-rw-r--r-- | driver/battery/link.c | 140 | ||||
-rw-r--r-- | driver/build.mk | 1 | ||||
-rw-r--r-- | include/config.h | 24 | ||||
-rw-r--r-- | include/extpower.h | 10 | ||||
-rw-r--r-- | include/extpower_falco.h | 54 | ||||
-rw-r--r-- | include/extpower_spring.h | 39 | ||||
-rw-r--r-- | power/build.mk | 1 | ||||
-rw-r--r-- | power/ivybridge.c | 347 | ||||
-rw-r--r-- | test/adapter.c | 610 | ||||
-rw-r--r-- | test/adapter.tasklist | 18 | ||||
-rw-r--r-- | test/adapter_externs.h | 21 | ||||
-rw-r--r-- | test/build.mk | 3 | ||||
-rw-r--r-- | test/stress.c | 15 | ||||
-rw-r--r-- | test/test_config.h | 30 | ||||
-rwxr-xr-x | util/flash_ec | 32 | ||||
-rwxr-xr-x | util/flash_pd.py | 11 |
28 files changed, 14 insertions, 2804 deletions
diff --git a/chip/lm4/openocd/lm4x_cmds.tcl b/chip/lm4/openocd/lm4x_cmds.tcl index aefca8e96e..601d03e445 100644 --- a/chip/lm4/openocd/lm4x_cmds.tcl +++ b/chip/lm4/openocd/lm4x_cmds.tcl @@ -14,19 +14,6 @@ proc flash_lm4 {path offset} { reset } -proc flash_link { } { - flash_lm4 ../../../build/link/ec.bin 0 -} - -proc flash_link_ro { } { - flash_lm4 ../../../build/link/ec.RO.flat 0 -} - -# Link originally had 80KB images, but TOT builds 128KB images -proc flash_link_rw { } { - flash_lm4 ../../../build/link/ec.RW.bin 131072 -} - proc flash_auron { } { flash_lm4 ../../../build/auron/ec.bin 0 } @@ -51,22 +38,6 @@ proc flash_samus_rw { } { flash_lm4 ../../../build/samus/ec.RW.bin 131072 } -proc flash_squawks { } { - flash_lm4 ../../../build/squawks/ec.bin 0 -} - -proc flash_squawks_ro { } { - flash_lm4 ../../../build/squawks/ec.RO.flat 0 -} - -proc flash_falco { } { - flash_lm4 ../../../build/falco/ec.bin 0 -} - -proc flash_peppy { } { - flash_lm4 ../../../build/peppy/ec.bin 0 -} - proc flash_rambi_ro { } { flash_lm4 ../../../build/rambi/ec.RO.flat 0 } @@ -75,20 +46,6 @@ proc flash_rambi_rw { } { flash_lm4 ../../../build/rambi/ec.RW.bin 131072 } -# link has pstate in last sector -proc unprotect_link { } { - reset halt - flash erase_sector 0 254 255 - reset -} - -# Peppy/falco have pstate following RO -proc unprotect_peppy { } { - reset halt - flash erase_sector 0 126 127 - reset -} - # Auron have pstate following RO proc unprotect_auron { } { reset halt @@ -105,16 +62,6 @@ proc ramboot_lm4 {path} { resume } -proc ramboot_link { } { - ramboot_lm4 ../../../build/link/ec.RO.flat -} - proc ramboot_bds { } { ramboot_lm4 ../../../build/bds/ec.RO.flat } - -proc flash_emerged_link { } { - set firmware_image ../../../../../../chroot/build/link/firmware/ec.bin - - flash_lm4 $firmware_image 0 -} diff --git a/chip/stm32/clock-stm32f.c b/chip/stm32/clock-stm32f.c index 029c34bd09..ed2c3abd2c 100644 --- a/chip/stm32/clock-stm32f.c +++ b/chip/stm32/clock-stm32f.c @@ -113,27 +113,18 @@ void __rtc_alarm_irq(void) } DECLARE_IRQ(STM32_IRQ_RTC_ALARM, __rtc_alarm_irq, 1); -#if defined(BOARD_SNOW) || defined(BOARD_SPRING) -/* - * stays on HSI (8MHz), no prescaler, PLLSRC = HSI/2, PLLMUL = x4 - * no MCO => PLLCLK = 16 Mhz - */ -#define DESIRED_CPU_CLOCK 16000000 -#define RCC_CFGR 0x00080000 -#elif defined(BOARD_MCCROSKEY) /* + * These were the clock settings we used for the STM32F103 reference, but + * they'll need updating for use on some other board. + * * HSI = 8MHz, no prescaler, no MCO * PLLSRC = HSI/2, PLLMUL = x12 => PLLCLK = 48MHz * USB clock = PLLCLK */ #define DESIRED_CPU_CLOCK 48000000 #define RCC_CFGR 0x00680000 -#elif defined(BOARD_KEYBORG) -#define DESIRED_CPU_CLOCK 48000000 -#define RCC_CFGR 0x00534000 -#else #error "Need board-specific clock settings" -#endif + BUILD_ASSERT(CPU_CLOCK == DESIRED_CPU_CLOCK); static void config_hispeed_clock(void) diff --git a/chip/stm32/power_led.c b/chip/stm32/power_led.c index 3c391dab86..03a7f33a82 100644 --- a/chip/stm32/power_led.c +++ b/chip/stm32/power_led.c @@ -64,12 +64,7 @@ static void power_led_manual_off(void) * configure it as an open-drain output and set it to high impedence, * but reconfiguring as an input had better results in testing. */ -#ifdef BOARD_SNOW - gpio_set_flags(GPIO_LED_POWER_L, GPIO_INPUT); - gpio_set_level(GPIO_LED_POWER_L, 1); -#else gpio_config_module(MODULE_POWER_LED, 0); -#endif } /** diff --git a/common/build.mk b/common/build.mk index cdde1f7fd3..be87443078 100644 --- a/common/build.mk +++ b/common/build.mk @@ -40,10 +40,7 @@ common-$(CONFIG_CRC8)+= crc8.o common-$(CONFIG_PMU_POWERINFO)+=pmu_tps65090_powerinfo.o common-$(CONFIG_PMU_TPS65090)+=pmu_tps65090.o common-$(CONFIG_EOPTION)+=eoption.o -common-$(CONFIG_EXTPOWER_FALCO)+=extpower_falco.o common-$(CONFIG_EXTPOWER_GPIO)+=extpower_gpio.o -common-$(CONFIG_EXTPOWER_SNOW)+=extpower_snow.o -common-$(CONFIG_EXTPOWER_SPRING)+=extpower_spring.o common-$(CONFIG_FANS)+=fan.o common-$(CONFIG_FLASH)+=flash.o common-$(CONFIG_FMAP)+=fmap.o diff --git a/common/charge_state_v1.c b/common/charge_state_v1.c index b817049138..90d93446a2 100644 --- a/common/charge_state_v1.c +++ b/common/charge_state_v1.c @@ -865,11 +865,6 @@ void charger_task(void) sleep_usec = CHARGE_POLL_PERIOD_SHORT; } -#ifdef CONFIG_EXTPOWER_FALCO - watch_adapter_closely(ctx); - sleep_usec = EXTPOWER_FALCO_POLL_PERIOD; -#endif - /* Show charging progress in console */ charging_progress(ctx); diff --git a/common/extpower_falco.c b/common/extpower_falco.c deleted file mode 100644 index f7e0516e70..0000000000 --- a/common/extpower_falco.c +++ /dev/null @@ -1,325 +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. - */ - -/* - * Falco adapters can support "charger hybrid turbo boost" mode and other - * buzzwords. The limits vary depending on each adapter's power rating, so we - * need to watch for changes and adjust the limits and high-current thresholds - * accordingly. If we go over, the AP needs to throttle itself. The EC's - * charging state logic isn't affected, just the AP's P-State. We try to save - * PROCHOT as a last resort. - */ - -#include <limits.h> /* part of the compiler */ - -#include "adc.h" -#include "battery_smart.h" -#include "charge_state.h" -#include "charger.h" -#include "chipset.h" -#include "common.h" -#include "console.h" -#include "driver/charger/bq24738.h" -#include "extpower.h" -#include "extpower_falco.h" -#include "hooks.h" -#include "host_command.h" -#include "throttle_ap.h" -#include "util.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_CHARGER, outstr) -#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args) - -/* Values for our supported adapters */ -static const char * const ad_name[] = { - "unknown", - "45W", - "65W", - "90W" -}; -BUILD_ASSERT(ARRAY_SIZE(ad_name) == NUM_ADAPTER_TYPES); - -test_export_static -struct adapter_id_vals ad_id_vals[] = { - /* mV low, mV high */ - {INT_MIN, INT_MAX}, /* anything = ADAPTER_UNKNOWN */ - {434, 554}, /* ADAPTER_45W */ - {561, 717}, /* ADAPTER_65W */ - {725, 925} /* ADAPTER_90W */ -}; -BUILD_ASSERT(ARRAY_SIZE(ad_id_vals) == NUM_ADAPTER_TYPES); - -test_export_static -int ad_input_current[][NUM_AC_TURBO_STATES] = { - /* - * Current limits in mA for each adapter, for turbo off and turbo on. - * Values are in hex to avoid roundoff, because the BQ24738 Input - * Current Register masks off bits 6-0. - * - * Note that this is very specific to the combinations of adapters and - * BQ24738 charger chip on Falco. - */ - - {0x0a00, 0x0a00}, /* ADAPTER_UNKNOWN ~ 2.5 A */ - {0x0600, 0x0800}, /* ADAPTER_45W ~ 1.5-2.0 A */ - {0x0a00, 0x0c00}, /* ADAPTER_65W ~ 2.5-3.0 A */ - {0x0f00, 0x1100} /* ADAPTER_90W ~ 3.8-4.3 A */ -}; -BUILD_ASSERT(ARRAY_SIZE(ad_input_current) == NUM_ADAPTER_TYPES); - -test_export_static -struct adapter_limits ad_limits[][NUM_AC_TURBO_STATES][NUM_AC_THRESHOLDS] = { - /* ADAPTER_UNKNOWN - treat as 65W, no turbo */ - { - /* Turbo off */ - { - { 3080, 2730, 16, 80, }, - { 3280, 2930, 1, 80, }, - }, - /* Turbo on - unused, except for testing */ - { - { 3080, 2730, 16, 80, }, - { 3280, 2930, 1, 80, }, - } - }, - /* ADAPTER_45W */ - { - /* Turbo off */ - { - { 2050, 1700, 16, 80, }, - { 2260, 1910, 1, 80, }, - }, - /* Turbo on */ - { - { 2310, 1960, 16, 80, }, - { 2560, 2210, 1, 80, }, - } - }, - /* ADAPTER_65W */ - { - /* Turbo off */ - { - { 3080, 2730, 16, 80, }, - { 3280, 2930, 1, 80, }, - }, - /* Turbo on */ - { - { 3330, 2980, 16, 80, }, - { 3590, 3240, 1, 80, }, - } - }, - /* ADAPTER_90W */ - { - /* Turbo off */ - { - { 4360, 4010, 16, 80, }, - { 4560, 4210, 1, 80, }, - }, - /* Turbo on */ - { - { 4620, 4270, 16, 80, }, - { 4870, 4520, 1, 80, }, - } - } -}; -BUILD_ASSERT(ARRAY_SIZE(ad_limits) == NUM_ADAPTER_TYPES); - -/* The battery current limits are independent of Turbo or adapter rating. - * hi_val and lo_val are DISCHARGE current in mA. - */ -test_export_static -struct adapter_limits batt_limits[] = { - { 7500, 7000, 16, 50, }, - { 8000, 7500, 1, 50, }, -}; -BUILD_ASSERT(ARRAY_SIZE(batt_limits) == NUM_BATT_THRESHOLDS); - -static int last_mv; -static enum adapter_type identify_adapter(void) -{ - int i; - last_mv = adc_read_channel(ADC_AC_ADAPTER_ID_VOLTAGE); - - /* ADAPTER_UNKNOWN matches everything, so search backwards */ - for (i = NUM_ADAPTER_TYPES - 1; i >= 0; i--) - if (last_mv >= ad_id_vals[i].lo && last_mv <= ad_id_vals[i].hi) - return i; - - return ADAPTER_UNKNOWN; /* should never get here */ -} - -test_export_static enum adapter_type ac_adapter; -static void ac_change_callback(void) -{ - if (extpower_is_present()) { - ac_adapter = identify_adapter(); - CPRINTS("AC Adapter is %s (%dmv)", - ad_name[ac_adapter], last_mv); - } else { - ac_adapter = ADAPTER_UNKNOWN; - CPRINTS("AC Adapter is not present"); - /* Charger unavailable. Clear local flags */ - } -} -DECLARE_HOOK(HOOK_AC_CHANGE, ac_change_callback, HOOK_PRIO_DEFAULT); - -test_export_static int ac_turbo = -1; -static void set_turbo(int on) -{ - int tmp, r; - - if (ac_turbo != on) - CPRINTS("turbo mode => %d", on); - - /* Set/clear turbo mode in charger */ - r = charger_get_option(&tmp); - if (r != EC_SUCCESS) - goto bad; - - if (on) - tmp |= OPTION_BOOST_MODE_ENABLE; - else - tmp &= ~OPTION_BOOST_MODE_ENABLE; - - r = charger_set_option(tmp); - if (r != EC_SUCCESS) - goto bad; - - /* Set allowed Io based on adapter. The charger will sometimes change - * this setting all by itself due to inrush current limiting, so we - * can't assume it stays where we put it. */ - r = charger_set_input_current(ad_input_current[ac_adapter][on]); - if (r != EC_SUCCESS) - goto bad; - - ac_turbo = on; - return; -bad: - CPRINTS("ERROR: can't talk to charger: %d", r); -} - - -/* We need to OR all the possible reasons to throttle in order to decide - * whether it should happen or not. Use one bit per reason. - */ -#define BATT_REASON_OFFSET 0 -#define AC_REASON_OFFSET NUM_BATT_THRESHOLDS -BUILD_ASSERT(NUM_BATT_THRESHOLDS + NUM_AC_THRESHOLDS < 32); - -test_export_static uint32_t ap_is_throttled; -static void set_throttle(int on, int whosays) -{ - if (on) - ap_is_throttled |= (1 << whosays); - else - ap_is_throttled &= ~(1 << whosays); - - throttle_ap(ap_is_throttled ? THROTTLE_ON : THROTTLE_OFF, - THROTTLE_SOFT, THROTTLE_SRC_POWER); -} - -test_export_static -void check_threshold(int current, struct adapter_limits *lim, int whoami) -{ - if (lim->triggered) { - /* watching for current to drop */ - if (current < lim->lo_val) { - if (++lim->count >= lim->lo_cnt) { - set_throttle(0, whoami); - lim->count = 0; - lim->triggered = 0; - } - } else { - lim->count = 0; - } - } else { - /* watching for current to rise */ - if (current > lim->hi_val) { - if (++lim->count >= lim->hi_cnt) { - set_throttle(1, whoami); - lim->count = 0; - lim->triggered = 1; - } - } else { - lim->count = 0; - } - } -} - - -test_export_static -void watch_battery_closely(struct charge_state_context *ctx) -{ - int i; - int current = ctx->curr.batt.current; - - /* NB: The values in batt_limits[] indicate DISCHARGE current (mA). - * However, the value returned from battery_current() is CHARGE - * current: postive for charging and negative for discharging. - * - * Turbo mode can discharge the battery even while connected to the - * charger. The spec says not to turn throttling off until the battery - * drain has been below the threshold for 5 seconds. That means we - * still need to check while on AC, or else just plugging the adapter - * in and out would mess up that 5-second timeout. Since the threshold - * logic uses signed numbers to compare the limits, everything Just - * Works. - */ - - /* Check limits against DISCHARGE current, not CHARGE current! */ - for (i = 0; i < NUM_BATT_THRESHOLDS; i++) - check_threshold(-current, &batt_limits[i], /* invert sign! */ - i + BATT_REASON_OFFSET); -} - -void watch_adapter_closely(struct charge_state_context *ctx) -{ - int current, i; - - /* We always watch the battery current drain, even when on AC. */ - watch_battery_closely(ctx); - - /* We can only talk to the charger if we're on AC. If there are no - * errors and we recognize the adapter, enable Turbo at 15% charge, - * disable it at 10% to provide hysteresis. */ - if (extpower_is_present()) { - if (ctx->curr.error || - ctx->curr.batt.state_of_charge < 10 || - ac_adapter == ADAPTER_UNKNOWN) { - set_turbo(0); - } else if (ctx->curr.batt.state_of_charge > 15) { - set_turbo(1); - } - } else { - /* If we're not on AC, we can't monitor the current, - * so watch for its return. - */ - ac_turbo = -1; - } - - /* If the AP is off, we won't need to throttle it. */ - if (chipset_in_state(CHIPSET_STATE_ANY_OFF | - CHIPSET_STATE_SUSPEND)) - return; - - /* Check all the thresholds. */ - current = adc_read_channel(ADC_CH_CHARGER_CURRENT); - for (i = 0; i < NUM_AC_THRESHOLDS; i++) - check_threshold(current, &ad_limits[ac_adapter][ac_turbo][i], - i + AC_REASON_OFFSET); -} - -static int command_adapter(int argc, char **argv) -{ - enum adapter_type v = identify_adapter(); - ccprintf("Adapter %s (%dmv), turbo %d, ap_is_throttled 0x%08x\n", - ad_name[v], last_mv, ac_turbo, ap_is_throttled); - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(adapter, command_adapter, - NULL, - "Display AC adapter information", - NULL); diff --git a/common/extpower_snow.c b/common/extpower_snow.c deleted file mode 100644 index 3713056c9a..0000000000 --- a/common/extpower_snow.c +++ /dev/null @@ -1,46 +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. - */ - -/* External power detection for snow */ - -#include "common.h" -#include "extpower.h" -#include "gpio.h" -#include "pmu_tpschrome.h" -#include "task.h" - -int extpower_is_present(void) -{ - /* - * Detect AC state using combined gpio pins - * - * On snow, there's no single gpio signal to detect AC. - * GPIO_AC_PWRBTN_L provides AC on and PWRBTN release. - * GPIO_KB_PWR_ON_L provides PWRBTN release. - * - * When AC plugged, both GPIOs will be high. - * - * One drawback of this detection is, when press-and-hold power - * button. AC state will be unknown. This function will fallback - * to PMU VACG. - */ - - int ac_good = 1, battery_good; - - if (gpio_get_level(GPIO_KB_PWR_ON_L)) - return gpio_get_level(GPIO_AC_PWRBTN_L); - - /* Check PMU VACG */ - if (!in_interrupt_context()) - pmu_get_power_source(&ac_good, &battery_good); - - /* - * Charging task only interacts with AP in discharging state. So - * return 1 when AC status can not be detected by GPIO or VACG. - */ - return ac_good; -} - -/* TODO(crosbug.com/p/23810): host events and hook notifications */ diff --git a/common/extpower_spring.c b/common/extpower_spring.c deleted file mode 100644 index 63735deab5..0000000000 --- a/common/extpower_spring.c +++ /dev/null @@ -1,970 +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. - */ - -/* USB charging control for spring board */ - -#include "adc.h" -#include "adc_chip.h" -#include "battery.h" -#include "battery_smart.h" -#include "chipset.h" -#include "clock.h" -#include "console.h" -#include "driver/tsu6721.h" -#include "extpower.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "keyboard_mkbp.h" -#include "pmu_tpschrome.h" -#include "pwm.h" -/* - * TODO(crosbug.com/p/23745): Refactor low-level STM32 ADC code out of this - * module. Files in common should not use chip registers directly. - */ -#include "registers.h" -#include "system.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -#define PWM_FREQUENCY 32000 /* Hz */ - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_USBCHARGE, outstr) -#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args) - -/* ILIM pin control */ -enum ilim_config { - ILIM_CONFIG_MANUAL_OFF, - ILIM_CONFIG_MANUAL_ON, - ILIM_CONFIG_PWM, -}; - -/* Devices that need VBUS power */ -#define POWERED_5000_DEVICE_TYPE (TSU6721_TYPE_OTG) -#define POWERED_3300_DEVICE_TYPE (TSU6721_TYPE_JIG_UART_ON) - -/* Toad cable */ -#define TOAD_DEVICE_TYPE (TSU6721_TYPE_UART | TSU6721_TYPE_AUDIO3) - -/* Voltage threshold of D+ for video */ -#define VIDEO_ID_THRESHOLD 1300 - -/* - * Mapping from PWM duty to current: - * Current = A + B * PWM_Duty - */ -#define PWM_MAPPING_A 2958 -#define PWM_MAPPING_B (-29) - -/* Map current in milli-amps to PWM duty cycle percentage */ -#define MA_TO_PWM(curr) (((curr) - PWM_MAPPING_A) / PWM_MAPPING_B) - -/* PWM controlled current limit */ -#define I_LIMIT_100MA MA_TO_PWM(100) -#define I_LIMIT_500MA MA_TO_PWM(500) -#define I_LIMIT_1000MA MA_TO_PWM(1000) -#define I_LIMIT_1500MA MA_TO_PWM(1500) -#define I_LIMIT_2000MA MA_TO_PWM(2000) -#define I_LIMIT_2400MA MA_TO_PWM(2400) -#define I_LIMIT_3000MA 0 - -/* PWM control loop parameters */ -#define PWM_CTRL_MAX_DUTY I_LIMIT_100MA /* Minimum current */ -#define PWM_CTRL_BEGIN_OFFSET 90 -#define PWM_CTRL_OC_MARGIN 15 -#define PWM_CTRL_OC_DETECT_TIME (1200 * MSEC) -#define PWM_CTRL_OC_BACK_OFF 3 -#define PWM_CTRL_OC_RETRY 2 -#define PWM_CTRL_STEP_DOWN 3 -#define PWM_CTRL_STEP_UP 5 -#define PWM_CTRL_VBUS_HARD_LOW 4400 -#define PWM_CTRL_VBUS_LOW 4500 -#define PWM_CTRL_VBUS_HIGH 4700 /* Must be higher than 4.5V */ -#define PWM_CTRL_VBUS_HIGH_500MA 4550 - -/* Delay before notifying kernel of device type change */ -#define BATTERY_KEY_DELAY (PWM_CTRL_OC_DETECT_TIME + 400 * MSEC) - -/* Delay for signals to settle */ -#define DELAY_POWER_MS 20 -#define DELAY_USB_DP_DN_MS 20 -#define DELAY_ID_MUX_MS 30 -#define CABLE_DET_POLL_MS 100 -#define CABLE_DET_POLL_COUNT 6 - -/* Current sense resistor values */ -#define R_INPUT_MOHM 20 /* mOhm */ -#define R_BATTERY_MOHM 33 /* mOhm */ - -static int current_dev_type = TSU6721_TYPE_NONE; -static int nominal_pwm_duty; -static int current_pwm_duty; -static int user_pwm_duty = -1; - -static int pending_tsu6721_reset; -static int pending_adc_watchdog_disable; -static int pending_dev_type_update; -static int pending_video_power_off; -static int restore_id_mux; - -static enum { - ADC_WATCH_NONE, - ADC_WATCH_TOAD, - ADC_WATCH_USB, -} current_watchdog = ADC_WATCH_NONE; - -struct { - int type; - const char *name; -} const known_dev_types[] = { - {TSU6721_TYPE_OTG, "OTG"}, - {TSU6721_TYPE_USB_HOST, "USB"}, - {TSU6721_TYPE_CHG12, "Type-1/2-Chg"}, - {TSU6721_TYPE_NON_STD_CHG, "Non-Std-Chg"}, - {TSU6721_TYPE_DCP, "DCP"}, - {TSU6721_TYPE_CDP, "CDP"}, - {TSU6721_TYPE_U200_CHG, "U200-Chg"}, - {TSU6721_TYPE_APPLE_CHG, "Apple-Chg"}, - {TSU6721_TYPE_JIG_UART_ON, "Video"}, - {TSU6721_TYPE_AUDIO3, "Audio-3"}, - {TSU6721_TYPE_UART, "UART"}, - {TSU6721_TYPE_VBUS_DEBOUNCED, "Power"} }; - -/* - * Last time we see a power source removed. Also records the power source - * type and PWM duty cycle at that moment. - * Index: 0 = Unknown power source. - * 1 = Recognized power source. - */ -static timestamp_t power_removed_time[2]; -static uint32_t power_removed_type[2]; -static int power_removed_pwm_duty[2]; -static int oc_detect_retry[2] = {PWM_CTRL_OC_RETRY, PWM_CTRL_OC_RETRY}; - -/* PWM duty cycle limit based on over current event */ -static int over_current_pwm_duty; - -static enum ilim_config current_ilim_config = ILIM_CONFIG_MANUAL_OFF; - -static const int apple_charger_type[4] = {I_LIMIT_500MA, - I_LIMIT_1000MA, - I_LIMIT_2000MA, - I_LIMIT_2400MA}; - -static int video_power_enabled; - -#define NON_STD_CHARGER_REDETECT_DELAY (600 * MSEC) -static enum { - NO_REDETECT, - REDETECT_SCHEDULED, - REDETECTED, -} charger_need_redetect = NO_REDETECT; -static timestamp_t charger_redetection_time; - -/** - * Directly read discharge current in mA; negative = charging. - */ -static int battery_current(int *current) -{ - int rv, d; - - rv = sb_read(SB_CURRENT, &d); - if (rv) { - *current = 0; - return rv; - } - - *current = (int16_t)d; - return EC_SUCCESS; -} - -static int get_video_power(void) -{ - return video_power_enabled; -} - -static void set_video_power(int enabled) -{ - int power_good; - - pmu_enable_fet(FET_VIDEO, enabled, enabled ? &power_good : NULL); - if (enabled && !power_good) - pmu_enable_fet(FET_VIDEO, 0, NULL); - video_power_enabled = enabled; -} - -static void ilim_use_gpio(void) -{ - pwm_enable(PWM_CH_ILIM, 0); - gpio_set_flags(GPIO_ILIM, GPIO_OUTPUT); -} - -/** - * Set ILIM pin control type. - */ -static void ilim_config(enum ilim_config config) -{ - if (config == current_ilim_config) - return; - current_ilim_config = config; - - switch (config) { - case ILIM_CONFIG_MANUAL_OFF: - case ILIM_CONFIG_MANUAL_ON: - ilim_use_gpio(); - gpio_set_level(GPIO_ILIM, - config == ILIM_CONFIG_MANUAL_ON ? 1 : 0); - break; - case ILIM_CONFIG_PWM: - pwm_enable(PWM_CH_ILIM, 1); - break; - default: - break; - } -} - -/** - * Return Apple charger current limit. - */ -static int apple_charger_current(void) -{ - int vp, vn; - int type = 0; - int data[ADC_CH_COUNT]; - - tsu6721_disable_interrupts(); - tsu6721_mux(TSU6721_MUX_USB); - /* Wait for signal to stablize */ - msleep(DELAY_USB_DP_DN_MS); - adc_read_all_channels(data); - vp = data[ADC_CH_USB_DP_SNS]; - vn = data[ADC_CH_USB_DN_SNS]; - tsu6721_mux(TSU6721_MUX_AUTO); - tsu6721_enable_interrupts(); - if (vp > 1215) - type |= 0x2; - if (vn > 1215) - type |= 0x1; - - return apple_charger_type[type]; -} - -static int hard_current_limit(int limit) -{ - /* - * The PWM duty cycle goes lower than the nominal - * cycle for PWM_CTRL_OC_MARGIN. Therefore, increase duty cycle by - * PWM_CTRL_OC_MARGIN avoids going over the hard limit. - * (Note that lower PWM cycle translates to higher current) - */ - return MIN(limit + PWM_CTRL_OC_MARGIN, 100); -} - -static int video_dev_type(int device_type) -{ - return (device_type & ~TSU6721_TYPE_USB_HOST) | - TSU6721_TYPE_JIG_UART_ON; -} - -static int usb_video_id_present(void) -{ - return adc_read_channel(ADC_CH_USB_DP_SNS) > VIDEO_ID_THRESHOLD; -} - -static int usb_poll_video_id(void) -{ - int i; - for (i = 0; i < CABLE_DET_POLL_COUNT; ++i) { - msleep(CABLE_DET_POLL_MS); - if (usb_video_id_present()) - return 1; - } - return 0; -} - -static int probe_video(int device_type) -{ - tsu6721_disable_interrupts(); - gpio_set_level(GPIO_ID_MUX, 1); - msleep(DELAY_ID_MUX_MS); - - if (usb_poll_video_id()) { - /* Not USB host but video */ - device_type = video_dev_type(device_type); - return device_type; - } else { - if (adc_read_channel(ADC_CH_USB_VBUS_SNS) > 3500) { - /* - * Either USB host or video dongle. - * Leave ID_MUX high so we see the change on - * DP_SNS if any. - * - * ADC watchdog is responsible for sensing a - * detach event and switch back ID_MUX. - */ - return device_type; - } else { - /* Unhandled unpowered video dongle. Ignore it. */ - gpio_set_level(GPIO_ID_MUX, 0); - msleep(DELAY_ID_MUX_MS); - tsu6721_enable_interrupts(); - return TSU6721_TYPE_NONE; - } - } -} - -/** - * Set PWM duty cycle. - */ -static void set_pwm_duty_cycle(int percent) -{ - if (current_ilim_config != ILIM_CONFIG_PWM) - ilim_config(ILIM_CONFIG_PWM); - if (percent < 0) - percent = 0; - if (percent > 100) - percent = 100; - pwm_set_duty(PWM_CH_ILIM, percent); - current_pwm_duty = percent; -} - -/** - * Returns next lower PWM duty cycle, or -1 for unchanged duty cycle. - */ -static int pwm_get_next_lower(void) -{ - if (current_pwm_duty > nominal_pwm_duty - - PWM_CTRL_OC_MARGIN && - current_pwm_duty > over_current_pwm_duty && - current_pwm_duty > 0) - return MAX(current_pwm_duty - PWM_CTRL_STEP_DOWN, 0); - return -1; -} - -static int pwm_check_vbus_low(int vbus, int battery_current) -{ - if (battery_current >= 0) - return vbus < PWM_CTRL_VBUS_LOW && current_pwm_duty < 100; - else - return vbus < PWM_CTRL_VBUS_HARD_LOW && current_pwm_duty < 100; -} - -static int pwm_check_vbus_high(int vbus) -{ - if (vbus > PWM_CTRL_VBUS_HIGH) - return 1; - if (vbus > PWM_CTRL_VBUS_HIGH_500MA && current_pwm_duty > I_LIMIT_500MA) - return 1; - return 0; -} - -static void pwm_nominal_duty_cycle(int percent) -{ - int new_percent = percent; - - new_percent += PWM_CTRL_BEGIN_OFFSET; - new_percent = MIN(new_percent, PWM_CTRL_MAX_DUTY); - - set_pwm_duty_cycle(new_percent); - nominal_pwm_duty = percent; -} - -static void adc_watch_vbus(int high, int low) -{ - adc_enable_watchdog(STM32_AIN(5), high, low); - task_clear_pending_irq(STM32_IRQ_ADC_1); - task_enable_irq(STM32_IRQ_ADC_1); -} - -static void adc_watch_toad(void) -{ - /* Watch VBUS and interrupt if voltage goes under 3V. */ - adc_watch_vbus(4095, 1800); - current_watchdog = ADC_WATCH_TOAD; -} - -static void adc_watch_usb(void) -{ - /* Watch VBUS and interrupt if voltage goes under 3V. */ - adc_watch_vbus(4095, 1800); - current_watchdog = ADC_WATCH_USB; -} - -static int usb_has_power_input(int dev_type) -{ - if (dev_type & TSU6721_TYPE_JIG_UART_ON) - return 1; - return (dev_type & TSU6721_TYPE_VBUS_DEBOUNCED) && - !(dev_type & POWERED_5000_DEVICE_TYPE); -} - -static int usb_need_boost(int dev_type) -{ - if (dev_type & POWERED_5000_DEVICE_TYPE) - return 0; - if (chipset_in_state(CHIPSET_STATE_ON | CHIPSET_STATE_SUSPEND)) - return 1; - return (dev_type != TSU6721_TYPE_NONE); -} - -static void usb_boost_power_hook(int power_on) -{ - if (current_dev_type == TSU6721_TYPE_NONE) - gpio_set_level(GPIO_BOOST_EN, power_on); - else if (current_dev_type & TSU6721_TYPE_JIG_UART_ON) - set_video_power(power_on); -} - -static int usb_charger_removed(int dev_type) -{ - if (!(current_dev_type & TSU6721_TYPE_VBUS_DEBOUNCED)) - return 0; - - /* Charger is removed */ - if (dev_type == TSU6721_TYPE_NONE) - return 1; - - /* - * Device type changed from known type to unknown type. Assuming - * it went away and came back. - */ - if ((current_dev_type != TSU6721_TYPE_VBUS_DEBOUNCED) && - (dev_type == TSU6721_TYPE_VBUS_DEBOUNCED)) - return 1; - - return 0; -} - -/** - * Detect over-current events. - * - * When a power source is removed, record time, power source type, and PWM duty - * cycle. Then when we see a power source, compare type and calculate time - * difference to determine if we have just encountered an over current event. - */ -static void usb_detect_overcurrent(int dev_type) -{ - if (usb_charger_removed(dev_type)) { - int idx = !(current_dev_type == TSU6721_TYPE_VBUS_DEBOUNCED); - power_removed_time[idx] = get_time(); - power_removed_type[idx] = current_dev_type; - power_removed_pwm_duty[idx] = current_pwm_duty; - } else if (dev_type & TSU6721_TYPE_VBUS_DEBOUNCED) { - int idx = !(dev_type == TSU6721_TYPE_VBUS_DEBOUNCED); - timestamp_t now = get_time(); - now.val -= power_removed_time[idx].val; - if (now.val >= PWM_CTRL_OC_DETECT_TIME) { - oc_detect_retry[idx] = PWM_CTRL_OC_RETRY; - return; - } - if (power_removed_type[idx] == dev_type) { - if (oc_detect_retry[idx] > 0) { - CPRINTS("USB overcurrent: Retry (%d)", - oc_detect_retry[idx]); - oc_detect_retry[idx]--; - return; - } - over_current_pwm_duty = power_removed_pwm_duty[idx] + - PWM_CTRL_OC_BACK_OFF; - CPRINTS("USB overcurrent: Limited to %d%%", - over_current_pwm_duty); - } - } -} - -/** - * Supply 5V VBUS if needed. - * - * If we toggle power output, wait for a moment, and then update device - * type. To avoid race condition, check if power requirement changes during - * this time. - */ -static int usb_manage_boost(int dev_type) -{ - int need_boost; - int retry_limit = 3; - - do { - if (retry_limit-- <= 0) - break; - - need_boost = usb_need_boost(dev_type); - if (need_boost != gpio_get_level(GPIO_BOOST_EN)) { - gpio_set_level(GPIO_BOOST_EN, need_boost); - msleep(DELAY_POWER_MS); - dev_type = tsu6721_get_device_type(); - if (gpio_get_level(GPIO_ID_MUX)) - dev_type = video_dev_type(dev_type); - } - } while (need_boost == !usb_need_boost(dev_type)); - - return dev_type; -} - -/** - * Update ILIM current limit according to device type. - */ -static void usb_update_ilim(int dev_type) -{ - if (usb_has_power_input(dev_type)) { - /* Limit USB port current. 500mA for not listed types. */ - int current_limit = I_LIMIT_500MA; - if (dev_type & TSU6721_TYPE_CHG12) - current_limit = I_LIMIT_3000MA; - else if (dev_type & TSU6721_TYPE_APPLE_CHG) - current_limit = apple_charger_current(); - else if (dev_type & TSU6721_TYPE_CDP) - current_limit = I_LIMIT_1500MA; - else if (dev_type & TSU6721_TYPE_DCP) - current_limit = hard_current_limit(I_LIMIT_1500MA); - else if (dev_type & TSU6721_TYPE_JIG_UART_ON) - current_limit = hard_current_limit(I_LIMIT_2000MA); - else if (dev_type & TOAD_DEVICE_TYPE) - current_limit = hard_current_limit(I_LIMIT_500MA); - else if (dev_type == TSU6721_TYPE_VBUS_DEBOUNCED) - current_limit = hard_current_limit(I_LIMIT_100MA); - - pwm_nominal_duty_cycle(current_limit); - } else { - ilim_config(ILIM_CONFIG_MANUAL_ON); - } -} - -static void usb_log_dev_type(int dev_type) -{ - int i = sizeof(known_dev_types) / sizeof(known_dev_types[0]); - - CPRINTF("[%T USB: 0x%06x", dev_type); - for (--i; i >= 0; --i) - if (dev_type & known_dev_types[i].type) - CPRINTF(" %s", known_dev_types[i].name); - CPRINTF("]\n"); -} - -static void send_battery_key_deferred(void) -{ - keyboard_send_battery_key(); -} -DECLARE_DEFERRED(send_battery_key_deferred); - -static void notify_dev_type_change(int dev_type) -{ - usb_log_dev_type(dev_type); - current_dev_type = dev_type; - hook_call_deferred(send_battery_key_deferred, BATTERY_KEY_DELAY); -} - -static void usb_device_change(int dev_type) -{ - - if (current_dev_type == dev_type) - return; - - over_current_pwm_duty = 0; - - /* - * Video output is recognized incorrectly as USB host. When we see - * USB host, probe for video output. - */ - if (dev_type & TSU6721_TYPE_USB_HOST) - dev_type = probe_video(dev_type); - - usb_detect_overcurrent(dev_type); - - dev_type = usb_manage_boost(dev_type); - - /* Supply 3.3V VBUS if needed. */ - if (dev_type & POWERED_3300_DEVICE_TYPE) - set_video_power(1); - - usb_update_ilim(dev_type); - - if ((dev_type & TOAD_DEVICE_TYPE) && - (dev_type & TSU6721_TYPE_VBUS_DEBOUNCED)) - adc_watch_toad(); - else if (dev_type & TSU6721_TYPE_USB_HOST) - adc_watch_usb(); - - if (dev_type != current_dev_type) { - if ((dev_type & TSU6721_TYPE_NON_STD_CHG || - dev_type == TSU6721_TYPE_VBUS_DEBOUNCED) && - charger_need_redetect == NO_REDETECT) { - /* Schedule redetection */ - charger_need_redetect = REDETECT_SCHEDULED; - charger_redetection_time = get_time(); - charger_redetection_time.val += - NON_STD_CHARGER_REDETECT_DELAY; - } else if (dev_type != TSU6721_TYPE_VBUS_DEBOUNCED && - !(dev_type & TSU6721_TYPE_NON_STD_CHG)) { - /* Not non-std charger. Disarm redetection timer. */ - charger_need_redetect = NO_REDETECT; - } - notify_dev_type_change(dev_type); - } - - if (dev_type) - disable_sleep(SLEEP_MASK_USB_PWR); - else - enable_sleep(SLEEP_MASK_USB_PWR); -} - -/*****************************************************************************/ -/* External API */ - -/* - * TODO(crosbug.com/p/23741): Init here until we can do with HOOK_INIT. Just - * need to set prio so we init before the charger task does. - */ -void extpower_charge_init(void) -{ - set_pwm_duty_cycle(I_LIMIT_500MA); - - /* - * TODO(crosbug.com/p/23742): For some reason the TSU6721 comes up very - * slowly. Wait for a while before accessing it. This delay seems to - * be long enough. Once we understand the slow start, it may be - * possible to remove this delay. - */ - msleep(500); - - tsu6721_reset(); - gpio_enable_interrupt(GPIO_USB_CHG_INT); - - /* TODO(crosbug.com/p/23742): Need delay after reset as well */ - msleep(100); - - extpower_charge_update(1); -} - -void extpower_charge_update(int force_update) -{ - int int_val = 0; - - if (restore_id_mux) { - gpio_set_level(GPIO_ID_MUX, 0); - msleep(DELAY_ID_MUX_MS); - restore_id_mux = 0; - } - - if (pending_adc_watchdog_disable) { - current_watchdog = ADC_WATCH_NONE; - adc_disable_watchdog(); - pending_adc_watchdog_disable = 0; - } - - if (pending_video_power_off) { - set_video_power(0); - pending_video_power_off = 0; - } - - if (pending_tsu6721_reset) { - tsu6721_reset(); - force_update = 1; - pending_tsu6721_reset = 0; - } - - if (pending_dev_type_update) { - force_update = 1; - pending_dev_type_update = 0; - } - - /* - * Check device type except when: - * 1. Current device type is non-standard charger or undetermined - * charger type. This is handled by charger re-detection. - * 2. ID_MUX=1. This is handled by ADC watchdog. - */ - if (current_dev_type != TSU6721_TYPE_VBUS_DEBOUNCED && - !(current_dev_type & TSU6721_TYPE_NON_STD_CHG) && - gpio_get_level(GPIO_ID_MUX) == 0) - force_update |= (tsu6721_get_device_type() != current_dev_type); - - if (!force_update) - int_val = tsu6721_get_interrupts(); - - if (int_val & TSU6721_INT_DETACH) - usb_device_change(TSU6721_TYPE_NONE); - else if (int_val || force_update) - usb_device_change(tsu6721_get_device_type()); -} - -int extpower_charge_needs_update(void) -{ - return tsu6721_peek_interrupts(); -} - -int extpower_is_present(void) -{ - static int last_vbus; - int vbus, vbus_good; - - if (!gpio_get_level(GPIO_BOOST_EN)) - return 0; - - /* - * UVLO is 4.1V. We consider AC bad when its voltage drops below 4.2V - * for two consecutive samples. This is to give PWM a chance to bring - * voltage up. - */ - vbus = adc_read_channel(ADC_CH_USB_VBUS_SNS); - vbus_good = (vbus >= 4200 || last_vbus >= 4200); - last_vbus = vbus; - - return vbus_good; -} - -void extpower_interrupt(enum gpio_signal signal) -{ - task_wake(TASK_ID_CHARGER); -} - -/*****************************************************************************/ -/* Hooks */ - -void adc_watchdog_interrupt(void) -{ - switch (current_watchdog) { - case ADC_WATCH_USB: - restore_id_mux = 1; - /* Fall through */ - case ADC_WATCH_TOAD: - pending_tsu6721_reset = 1; - pending_adc_watchdog_disable = 1; - task_disable_irq(STM32_IRQ_ADC_1); - task_wake(TASK_ID_CHARGER); - break; - default: - break; - } -} -DECLARE_IRQ(STM32_IRQ_ADC_1, adc_watchdog_interrupt, 2); - -static void usb_boost_pwr_on_hook(void) -{ - usb_boost_power_hook(1); -} -DECLARE_HOOK(HOOK_CHIPSET_PRE_INIT, usb_boost_pwr_on_hook, HOOK_PRIO_DEFAULT); - -static void usb_boost_pwr_off_hook(void) -{ - usb_boost_power_hook(0); -} -DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, usb_boost_pwr_off_hook, HOOK_PRIO_DEFAULT); - -static void pwm_tweak(void) -{ - int vbus, current; - int next; - - if (current_ilim_config != ILIM_CONFIG_PWM) - return; - - vbus = adc_read_channel(ADC_CH_USB_VBUS_SNS); - if (battery_current(¤t)) - current = 0; - - if (user_pwm_duty >= 0) { - if (current_pwm_duty != user_pwm_duty) - set_pwm_duty_cycle(user_pwm_duty); - return; - } - - /* - * If VBUS voltage is too low: - * - If battery is discharging, throttling more is going to draw - * more current from the battery, so do nothing unless VBUS is - * about to be lower than AC good threshold. - * - Otherwise, throttle input current to raise VBUS voltage. - * If VBUS voltage is high enough, allow more current until we hit - * current limit target. - */ - if (pwm_check_vbus_low(vbus, current)) { - set_pwm_duty_cycle(current_pwm_duty + PWM_CTRL_STEP_UP); - CPRINTS("PWM duty up %d%%", current_pwm_duty); - } else if (pwm_check_vbus_high(vbus)) { - next = pwm_get_next_lower(); - if (next >= 0) { - set_pwm_duty_cycle(next); - CPRINTS("PWM duty down %d%%", current_pwm_duty); - } - } -} -DECLARE_HOOK(HOOK_SECOND, pwm_tweak, HOOK_PRIO_DEFAULT); - -static void usb_detach_video(void) -{ - if (!(current_dev_type & TSU6721_TYPE_JIG_UART_ON)) - return; - pending_video_power_off = 1; - restore_id_mux = 1; - pending_tsu6721_reset = 1; - task_wake(TASK_ID_CHARGER); -} -DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, usb_detach_video, HOOK_PRIO_DEFAULT); -DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, usb_detach_video, HOOK_PRIO_DEFAULT); - -static void usb_monitor_detach(void) -{ - int vbus; - - if (!(current_dev_type & TSU6721_TYPE_JIG_UART_ON)) - return; - - if (!usb_video_id_present()) { - usb_detach_video(); - return; - } - - /* Check if there is external power */ - vbus = adc_read_channel(ADC_CH_USB_VBUS_SNS); - if (get_video_power() && vbus > 4000) { - set_video_power(0); - notify_dev_type_change(current_dev_type | - TSU6721_TYPE_VBUS_DEBOUNCED); - } else if (!get_video_power() && vbus <= 4000) { - set_pwm_duty_cycle(100); - set_video_power(1); - notify_dev_type_change(current_dev_type & - ~TSU6721_TYPE_VBUS_DEBOUNCED); - } -} -DECLARE_HOOK(HOOK_SECOND, usb_monitor_detach, HOOK_PRIO_DEFAULT); - -static void usb_monitor_cable_det(void) -{ - if (!(current_dev_type & TSU6721_TYPE_USB_HOST)) - return; - - if (usb_video_id_present()) - adc_watchdog_interrupt(); -} -DECLARE_HOOK(HOOK_SECOND, usb_monitor_cable_det, HOOK_PRIO_DEFAULT); - -static void usb_charger_redetect(void) -{ - if (charger_need_redetect != REDETECT_SCHEDULED) - return; - - if (timestamp_expired(charger_redetection_time, NULL)) { - CPRINTS("USB Redetecting"); - /* - * TSU6721 doesn't update device type if power or ID pin - * is present. Therefore, if the device type is the same, - * we need to reset TSU6721 to force a redetection. - */ - if (tsu6721_get_device_type() == current_dev_type) - pending_tsu6721_reset = 1; - else - pending_dev_type_update = 1; - if (gpio_get_level(GPIO_ID_MUX)) - restore_id_mux = 1; - charger_need_redetect = REDETECTED; - task_wake(TASK_ID_CHARGER); - } -} -DECLARE_HOOK(HOOK_SECOND, usb_charger_redetect, HOOK_PRIO_DEFAULT); - -/*****************************************************************************/ -/* Console commands for debugging */ - -#ifdef CONFIG_CMD_ILIM -static int command_ilim(int argc, char **argv) -{ - char *e; - int v; - - if (argc >= 2) { - if (parse_bool(argv[1], &v)) { - ilim_config(v ? ILIM_CONFIG_MANUAL_ON : - ILIM_CONFIG_MANUAL_OFF); - } else { - v = strtoi(argv[1], &e, 0); - if (*e) - return EC_ERROR_PARAM1; - set_pwm_duty_cycle(v); - } - } - - if (current_ilim_config == ILIM_CONFIG_MANUAL_ON) - ccprintf("ILIM is GPIO high\n"); - else if (current_ilim_config == ILIM_CONFIG_MANUAL_OFF) - ccprintf("ILIM is GPIO low\n"); - else - ccprintf("ILIM is PWM duty cycle %d%%\n", - pwm_get_duty(PWM_CH_ILIM)); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(ilim, command_ilim, - "[percent | on | off]", - "Set or show ILIM duty cycle/GPIO value", - NULL); -#endif /* CONFIG_CMD_ILIM */ - -#ifdef CONFIG_CMD_BATDEBUG -static int command_batdebug(int argc, char **argv) -{ - struct batt_params batt; - - battery_get_params(&batt); - - ccprintf("VBUS = %d mV\n", adc_read_channel(ADC_CH_USB_VBUS_SNS)); - ccprintf("VAC = %d mV\n", pmu_adc_read(ADC_VAC, ADC_FLAG_KEEP_ON) - * 17000 / 1024); - ccprintf("IAC = %d mA\n", pmu_adc_read(ADC_IAC, ADC_FLAG_KEEP_ON) - * (1000 / R_INPUT_MOHM) * 33 / 1024); - ccprintf("VBAT = %d mV\n", pmu_adc_read(ADC_VBAT, ADC_FLAG_KEEP_ON) - * 17000 / 1024); - ccprintf("IBAT = %d mA\n", pmu_adc_read(ADC_IBAT, 0) - * (1000 / R_BATTERY_MOHM) * 40 / 1024); - ccprintf("PWM = %d%%\n", pwm_get_duty(PWM_CH_ILIM)); - ccprintf("Battery Current = %d mA\n", batt.current); - ccprintf("Battery Voltage= %d mV\n", batt.voltage); - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(batdebug, command_batdebug, - NULL, NULL, NULL); -#endif /* CONFIG_CMD_BATDEBUG */ - -/*****************************************************************************/ -/* Host commands */ - -static int ext_power_command_current_limit(struct host_cmd_handler_args *args) -{ - const struct ec_params_ext_power_current_limit *p = args->params; - - if (system_is_locked()) - return EC_RES_ACCESS_DENIED; - - user_pwm_duty = ((int)(p->limit) - PWM_MAPPING_A) / PWM_MAPPING_B; - - return EC_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_EXT_POWER_CURRENT_LIMIT, - ext_power_command_current_limit, - EC_VER_MASK(0)); - -static int power_command_info(struct host_cmd_handler_args *args) -{ - struct ec_response_power_info *r = args->response; - - r->voltage_ac = adc_read_channel(ADC_CH_USB_VBUS_SNS); - r->voltage_system = pmu_adc_read(ADC_VAC, ADC_FLAG_KEEP_ON) - * 17000 / 1024; - r->current_system = pmu_adc_read(ADC_IAC, 0) - * (1000 / R_INPUT_MOHM) * 33 / 1024; - r->usb_dev_type = current_dev_type; - - /* Approximate value by PWM duty cycle */ - r->usb_current_limit = PWM_MAPPING_A + PWM_MAPPING_B * current_pwm_duty; - - args->response_size = sizeof(*r); - - return EC_RES_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_POWER_INFO, power_command_info, EC_VER_MASK(0)); diff --git a/common/host_command.c b/common/host_command.c index 451bff74f3..da73d2dbd5 100644 --- a/common/host_command.c +++ b/common/host_command.c @@ -719,10 +719,8 @@ static int host_command_get_features(struct host_cmd_handler_args *args) #ifdef CONFIG_TEMP_SENSOR | EC_FEATURE_MASK_0(EC_FEATURE_THERMAL) #endif -/* Hack to uniquely identify Samus and Falco ec */ -#if (defined CONFIG_BACKLIGHT_LID) || \ - (defined CONFIG_BATTERY_SAMUS) || \ - (defined CONFIG_EXTPOWER_FALCO) +/* Hack to uniquely identify Samus ec */ +#if (defined CONFIG_BACKLIGHT_LID) || (defined CONFIG_BATTERY_SAMUS) | EC_FEATURE_MASK_0(EC_FEATURE_BKLIGHT_SWITCH) #endif #ifdef CONFIG_WIRELESS diff --git a/common/lb_common.c b/common/lb_common.c index edd033d870..c964ab8be3 100644 --- a/common/lb_common.c +++ b/common/lb_common.c @@ -56,12 +56,6 @@ static inline uint8_t controller_read(int ctrl_num, uint8_t reg) #define MAX_GREEN 0x30 #define MAX_BLUE 0x67 #endif -#ifdef BOARD_LINK -/* Link uses seven segments, not four, but keep the same limits anyway */ -#define MAX_RED 0x5c -#define MAX_GREEN 0x30 -#define MAX_BLUE 0x67 -#endif #if defined(BOARD_SAMUS) || defined(BOARD_RYU) || defined(BOARD_RYU_P4P5) /* Samus uses completely different LEDs, so the numbers are different. The * Samus LEDs can handle much higher currents, but these constants were @@ -117,9 +111,6 @@ static const uint8_t led_to_ctrl[] = { 1, 1, 0, 0 }; #ifdef BOARD_BDS static const uint8_t led_to_isc[] = { 0x18, 0x15, 0x18, 0x15 }; #endif -#ifdef BOARD_LINK -static const uint8_t led_to_isc[] = { 0x18, 0x15, 0x18, 0x15 }; -#endif #ifdef BOARD_SAMUS static const uint8_t led_to_isc[] = { 0x15, 0x18, 0x15, 0x18 }; #endif diff --git a/common/pmu_tps65090_charger.c b/common/pmu_tps65090_charger.c index d03c9d05c5..6e56ef98ff 100644 --- a/common/pmu_tps65090_charger.c +++ b/common/pmu_tps65090_charger.c @@ -309,14 +309,6 @@ static int calc_next_state(int state) return ST_IDLE0; } -#ifdef CONFIG_EXTPOWER_SPRING - /* Re-init on charger timeout. */ - if (pmu_is_charge_timeout()) { - CPRINTS("[pmu] charging: timeout"); - return ST_IDLE0; - } -#endif - return ST_CHARGING; case ST_CHARGING_ERROR: @@ -428,18 +420,10 @@ void charger_task(void) enable_charging(0); disable_sleep(SLEEP_MASK_CHARGING); -#ifdef CONFIG_EXTPOWER_SPRING - extpower_charge_init(); -#endif - while (1) { last_waken = get_time(); pmu_clear_irq(); -#ifdef CONFIG_EXTPOWER_SPRING - extpower_charge_update(0); -#endif - #ifdef CONFIG_PMU_TPS65090_CHARGING_LED update_battery_led(); #endif @@ -525,10 +509,6 @@ void charger_task(void) } } -#ifdef CONFIG_EXTPOWER_SPRING - has_pending_event |= extpower_charge_needs_update(); -#endif - if (!has_pending_event) { task_wait_event(wait_time); disable_sleep(SLEEP_MASK_CHARGING); diff --git a/common/pmu_tps65090_powerinfo.c b/common/pmu_tps65090_powerinfo.c index e53e49a660..9eb6adca42 100644 --- a/common/pmu_tps65090_powerinfo.c +++ b/common/pmu_tps65090_powerinfo.c @@ -120,9 +120,6 @@ DECLARE_CONSOLE_COMMAND(powerinfo, command_powerinfo, * * 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. - * - * Note that Spring *also* uses the TPS65090 PMU, but it can't use this common - * code because it implements the same host command differently... */ static int power_command_info(struct host_cmd_handler_args *args) { diff --git a/driver/battery/link.c b/driver/battery/link.c deleted file mode 100644 index 37a4ffb150..0000000000 --- a/driver/battery/link.c +++ /dev/null @@ -1,140 +0,0 @@ -/* Copyright (c) 2012 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" - -static const struct battery_info info = { - /* - * 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, -}; - -const struct battery_info *battery_get_info(void) -{ - return &info; -} - -#ifdef CONFIG_BATTERY_OVERRIDE_PARAMS - -/* - * Design capacity - * Battery capacity = 8200 mAh - * 1C = 8200 mA - */ -#define DESIGN_CAPACITY 8200 - -enum { - TEMP_RANGE_10, - TEMP_RANGE_23, - TEMP_RANGE_35, - TEMP_RANGE_45, - TEMP_RANGE_50, - TEMP_RANGE_MAX -}; - -enum { - VOLT_RANGE_7200, - VOLT_RANGE_8000, - VOLT_RANGE_8400, - VOLT_RANGE_MAX -}; - -/* - * Vendor provided charging method - * temp : < 7.2V, 7.2V ~ 8.0V, 8.0V ~ 8.4V - * - 0 ~ 10 : 0.8A 1.6A 0.8A - * - 10 ~ 23 : 1.6A 4.0A 1.6A - * - 23 ~ 35 : 4.0A 4.0A 4.0A - * - 35 ~ 45 : 1.6A 4.0A 1.6A - * - 45 ~ 50 : 0.8A 1.6A 0.8A - */ -static const int const current_limit[TEMP_RANGE_MAX][VOLT_RANGE_MAX] = { - { 800, 1600, 800}, - {1600, 4000, 1600}, - {4000, 4000, 4000}, - {1600, 4000, 1600}, - { 800, 1600, 800}, -}; - -static inline void limit_value(int *val, int limit) -{ - if (*val > limit) - *val = limit; -} - -/** - * This can override the smart battery's charging profile. On entry, all the - * battery parameters have been updated from the smart battery. On return, the - * desired_voltage and desired_current will be passed to the charger. To use - * the smart battery's profile, simply do nothing. - */ -void battery_override_params(struct batt_params *batt) -{ - int *desired_current = &batt->desired_current; - int temp_range, volt_range; - int bat_temp_c = DECI_KELVIN_TO_CELSIUS(batt->temperature); - - /* Limit charging voltage */ - if (batt->desired_voltage > info.voltage_max) - batt->desired_voltage = info.voltage_max; - - /* Don't charge if outside of allowable temperature range */ - if (bat_temp_c >= info.charging_max_c || - bat_temp_c < info.charging_min_c) { - batt->flags &= ~BATT_FLAG_WANT_CHARGE; - batt->desired_voltage = 0; - batt->desired_current = 0; - return; - } - - if (bat_temp_c <= 10) - temp_range = TEMP_RANGE_10; - else if (bat_temp_c <= 23) - temp_range = TEMP_RANGE_23; - else if (bat_temp_c <= 35) - temp_range = TEMP_RANGE_35; - else if (bat_temp_c <= 45) - temp_range = TEMP_RANGE_45; - else - temp_range = TEMP_RANGE_50; - - if (batt->voltage < 7200) - volt_range = VOLT_RANGE_7200; - else if (batt->voltage < 8000) - volt_range = VOLT_RANGE_8000; - else - volt_range = VOLT_RANGE_8400; - - limit_value(desired_current, current_limit[temp_range][volt_range]); - - /* If battery wants current, give it at least the precharge current */ - if (*desired_current > 0 && *desired_current < info.precharge_current) - *desired_current = info.precharge_current; -} - -#endif /* CONFIG_BATTERY_OVERRIDE_PARAMS */ diff --git a/driver/build.mk b/driver/build.mk index aff6f45aa1..89a099226b 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -18,7 +18,6 @@ driver-$(CONFIG_ALS_ISL29035)+=als_isl29035.o driver-$(CONFIG_BATTERY_BQ20Z453)+=battery/bq20z453.o driver-$(CONFIG_BATTERY_BQ27541)+=battery/bq27541.o driver-$(CONFIG_BATTERY_BQ27621)+=battery/bq27621_g1.o -driver-$(CONFIG_BATTERY_LINK)+=battery/link.o driver-$(CONFIG_BATTERY_RYU)+=battery/ryu.o driver-$(CONFIG_BATTERY_SAMUS)+=battery/samus.o driver-$(CONFIG_BATTERY_SMART)+=battery/smart.o diff --git a/include/config.h b/include/config.h index 60adb684d7..aa5e05c7a4 100644 --- a/include/config.h +++ b/include/config.h @@ -89,7 +89,6 @@ #undef CONFIG_BATTERY_BQ20Z453 #undef CONFIG_BATTERY_BQ27541 #undef CONFIG_BATTERY_BQ27621 -#undef CONFIG_BATTERY_LINK #undef CONFIG_BATTERY_RYU #undef CONFIG_BATTERY_SAMUS @@ -326,7 +325,6 @@ #undef CONFIG_CHIPSET_BRASWELL /* Intel Braswell (x86) */ #undef CONFIG_CHIPSET_GAIA /* Gaia and Ares (ARM) */ #undef CONFIG_CHIPSET_HASWELL /* Intel Haswell (x86) */ -#undef CONFIG_CHIPSET_IVYBRIDGE /* Intel Ivy Bridge (x86) */ #undef CONFIG_CHIPSET_ROCKCHIP /* Rockchip rk32xx */ #undef CONFIG_CHIPSET_SKYLAKE /* Intel Skylake (x86) */ #undef CONFIG_CHIPSET_TEGRA /* nVidia Tegra 5 */ @@ -558,21 +556,9 @@ /* Include code for handling external power */ #define CONFIG_EXTPOWER -/* Support turbo-mode chargers */ -#undef CONFIG_EXTPOWER_FALCO - /* Support detecting external power presence via a GPIO */ #undef CONFIG_EXTPOWER_GPIO -/* - * Support detecting external power presence via a pair of GPIOs, as used - * on Snow. - */ -#undef CONFIG_EXTPOWER_SNOW - -/* Support providing power to the device via USB on Spring. */ -#undef CONFIG_EXTPOWER_SPRING - /*****************************************************************************/ /* Number of cooling fans. Undef if none. */ #undef CONFIG_FANS @@ -1009,15 +995,6 @@ /* PMU config */ /* - * Force switching on and off the FETs on the PMU controlling various power - * rails during AP startup and shutdown sequences. This is mainly useful for - * bringup when we don't have the corresponding sequences in the AP code. - * - * Currently supported only on spring platform. - */ -#undef CONFIG_PMU_FORCE_FET - -/* * Enable hard-resetting the PMU from the EC. 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 @@ -1547,7 +1524,6 @@ #undef CONFIG_CHIPSET_BRASWELL #undef CONFIG_CHIPSET_GAIA #undef CONFIG_CHIPSET_HASWELL -#undef CONFIG_CHIPSET_IVYBRIDGE #undef CONFIG_CHIPSET_ROCKCHIP #undef CONFIG_CHIPSET_TEGRA #undef CONFIG_POWER_COMMON diff --git a/include/extpower.h b/include/extpower.h index f75a1a5c06..d3f9a4f6ef 100644 --- a/include/extpower.h +++ b/include/extpower.h @@ -10,11 +10,6 @@ #include "common.h" -#ifdef CONFIG_EXTPOWER_SPRING -/* Spring-USB-power-specific methods */ -#include "extpower_spring.h" -#endif - /** * Return non-zero if external power is present. */ @@ -27,9 +22,4 @@ int extpower_is_present(void); */ void extpower_interrupt(enum gpio_signal signal); -#ifdef CONFIG_EXTPOWER_FALCO -/* Adapter-specific logic */ -#include "extpower_falco.h" -#endif - #endif /* __CROS_EC_EXTPOWER_H */ diff --git a/include/extpower_falco.h b/include/extpower_falco.h deleted file mode 100644 index 8d7cb57b8b..0000000000 --- a/include/extpower_falco.h +++ /dev/null @@ -1,54 +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. - */ - -/* We can do even smarter charging if we can identify the AC adapter */ - -#ifndef __CROS_EC_EXTPOWER_FALCO_H -#define __CROS_EC_EXTPOWER_FALCO_H - -#ifdef CONFIG_CHARGER_V2 -#error "This is not compatible with CONFIG_CHARGER_V2" -/* - * ... but we can't define CONFIG_CHARGER_V1 because the tests don't need or - * want charge_state_v1.c. Sigh. - */ -#endif -#include "charge_state.h" -#include "charge_state_v1.h" - -/* Supported adapters */ -enum adapter_type { - ADAPTER_UNKNOWN = 0, - ADAPTER_45W, - ADAPTER_65W, - ADAPTER_90W, - NUM_ADAPTER_TYPES -}; - -/* Adapter identification values */ -struct adapter_id_vals { - int lo, hi; -}; - -/* Adapter-specific parameters. */ -struct adapter_limits { - int hi_val, lo_val; /* current thresholds (mA) */ - int hi_cnt, lo_cnt; /* count needed to trigger */ - int count; /* samples past the limit */ - int triggered; /* threshold reached */ -}; - -/* Rate at which adapter samples are collected. */ -#define EXTPOWER_FALCO_POLL_PERIOD (MSEC * 100) - -/* Number of special states */ -#define NUM_AC_TURBO_STATES 2 -#define NUM_AC_THRESHOLDS 2 -#define NUM_BATT_THRESHOLDS 2 - -/* Change turbo mode or throttle the AP depending on the adapter state. */ -void watch_adapter_closely(struct charge_state_context *ctx); - -#endif /* __CROS_EC_EXTPOWER_FALCO_H */ diff --git a/include/extpower_spring.h b/include/extpower_spring.h deleted file mode 100644 index db38f2c230..0000000000 --- a/include/extpower_spring.h +++ /dev/null @@ -1,39 +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. - */ - -/* External power via USB on Spring for Chrome EC */ - -#ifndef __CROS_EC_EXTPOWER_SPRING_H -#define __CROS_EC_EXTPOWER_SPRING_H - -#include "common.h" - -/* - * TODO(crosbug.com/p/23813): this currently piggy-backs on the charger task. - * Should be able to move updates to deferred functions and get rid of all the - * ifdef's in the charger task. At that point, all these APIs will be internal - * to the extpower module and this entire header file can go away. - */ - -/** - * Properly limit input power on EC boot. - * - * Called from charger task. - */ -void extpower_charge_init(void); - -/** - * Update external power state. - * - * Called from charger task. - */ -void extpower_charge_update(int force_update); - -/** - * Return non-zero if external power needs update from charge task. - */ -int extpower_charge_needs_update(void); - -#endif /* __CROS_EC_EXTPOWER_SPRING_H */ diff --git a/power/build.mk b/power/build.mk index 52ac0ab3e7..90ffe342d5 100644 --- a/power/build.mk +++ b/power/build.mk @@ -11,7 +11,6 @@ power-$(CONFIG_CHIPSET_BRASWELL)+=braswell.o power-$(CONFIG_CHIPSET_ECDRIVEN)+=ec_driven.o power-$(CONFIG_CHIPSET_GAIA)+=gaia.o power-$(CONFIG_CHIPSET_HASWELL)+=haswell.o -power-$(CONFIG_CHIPSET_IVYBRIDGE)+=ivybridge.o power-$(CONFIG_CHIPSET_MEDIATEK)+=mediatek.o power-$(CONFIG_CHIPSET_ROCKCHIP)+=rockchip.o power-$(CONFIG_CHIPSET_SKYLAKE)+=skylake.o diff --git a/power/ivybridge.c b/power/ivybridge.c deleted file mode 100644 index 163afb330b..0000000000 --- a/power/ivybridge.c +++ /dev/null @@ -1,347 +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. - */ - -/* X86 ivybridge chipset power control module for Chrome EC */ - -#include "chipset.h" -#include "common.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "lid_switch.h" -#include "power.h" -#include "system.h" -#include "timer.h" -#include "util.h" -#include "wireless.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_CHIPSET, outstr) -#define CPRINTS(format, args...) cprints(CC_CHIPSET, format, ## args) - -/* Input state flags */ -#define IN_PGOOD_5VALW POWER_SIGNAL_MASK(X86_PGOOD_5VALW) -#define IN_PGOOD_1_5V_DDR POWER_SIGNAL_MASK(X86_PGOOD_1_5V_DDR) -#define IN_PGOOD_1_5V_PCH POWER_SIGNAL_MASK(X86_PGOOD_1_5V_PCH) -#define IN_PGOOD_1_8VS POWER_SIGNAL_MASK(X86_PGOOD_1_8VS) -#define IN_PGOOD_VCCP POWER_SIGNAL_MASK(X86_PGOOD_VCCP) -#define IN_PGOOD_VCCSA POWER_SIGNAL_MASK(X86_PGOOD_VCCSA) -#define IN_PGOOD_CPU_CORE POWER_SIGNAL_MASK(X86_PGOOD_CPU_CORE) -#define IN_PGOOD_VGFX_CORE POWER_SIGNAL_MASK(X86_PGOOD_VGFX_CORE) -#define IN_SLP_S3_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_S3_DEASSERTED) -#define IN_SLP_S4_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_S4_DEASSERTED) -#define IN_SLP_S5_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_S5_DEASSERTED) -#define IN_SLP_A_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_A_DEASSERTED) -#define IN_SLP_SUS_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_SUS_DEASSERTED) -#define IN_SLP_ME_DEASSERTED POWER_SIGNAL_MASK(X86_SLP_ME_DEASSERTED) - -/* All always-on supplies */ -#define IN_PGOOD_ALWAYS_ON (IN_PGOOD_5VALW) -/* All non-core power rails */ -#define IN_PGOOD_ALL_NONCORE (IN_PGOOD_1_5V_DDR | IN_PGOOD_1_5V_PCH | \ - IN_PGOOD_1_8VS | IN_PGOOD_VCCP | IN_PGOOD_VCCSA) -/* All core power rails */ -#define IN_PGOOD_ALL_CORE (IN_PGOOD_CPU_CORE | IN_PGOOD_VGFX_CORE) -/* Rails required for S3 */ -#define IN_PGOOD_S3 (IN_PGOOD_ALWAYS_ON | IN_PGOOD_1_5V_DDR) -/* Rails required for S0 */ -#define IN_PGOOD_S0 (IN_PGOOD_ALWAYS_ON | IN_PGOOD_ALL_NONCORE) - -/* All PM_SLP signals from PCH deasserted */ -#define IN_ALL_PM_SLP_DEASSERTED (IN_SLP_S3_DEASSERTED | \ - IN_SLP_S4_DEASSERTED | \ - IN_SLP_S5_DEASSERTED | \ - IN_SLP_A_DEASSERTED) -/* All inputs in the right state for S0 */ -#define IN_ALL_S0 (IN_PGOOD_ALWAYS_ON | IN_PGOOD_ALL_NONCORE | \ - IN_PGOOD_CPU_CORE | IN_ALL_PM_SLP_DEASSERTED) - -static int throttle_cpu; /* Throttle CPU? */ - -void chipset_force_shutdown(void) -{ - CPRINTS("chipset force shutdown"); - - /* - * Force power off. This condition will reset once the state machine - * transitions to G3. - */ - gpio_set_level(GPIO_PCH_DPWROK, 0); - gpio_set_level(GPIO_PCH_RSMRST_L, 0); -} - -void chipset_reset(int cold_reset) -{ - if (cold_reset) { - /* - * Drop and restore PWROK. This causes the PCH to reboot, - * regardless of its after-G3 setting. This type of reboot - * causes the PCH to assert PLTRST#, SLP_S3#, and SLP_S5#, so - * we actually drop power to the rest of the system (hence, a - * "cold" reboot). - */ - - /* Ignore if PWROK is already low */ - if (gpio_get_level(GPIO_PCH_PWROK) == 0) - return; - - /* PWROK must deassert for at least 3 RTC clocks = 91 us */ - gpio_set_level(GPIO_PCH_PWROK, 0); - udelay(100); - gpio_set_level(GPIO_PCH_PWROK, 1); - - } else { - /* - * Send a RCIN# pulse to the PCH. This just causes it to - * assert INIT# to the CPU without dropping power or asserting - * PLTRST# to reset the rest of the system. - */ - - /* Pulse must be at least 16 PCI clocks long = 500 ns */ - gpio_set_level(GPIO_PCH_RCIN_L, 0); - udelay(10); - gpio_set_level(GPIO_PCH_RCIN_L, 1); - } -} - -void chipset_throttle_cpu(int throttle) -{ - throttle_cpu = throttle; - - /* Immediately set throttling if CPU is on */ - if (chipset_in_state(CHIPSET_STATE_ON)) - gpio_set_level(GPIO_CPU_PROCHOT, throttle); -} - -enum power_state power_chipset_init(void) -{ - /* - * If we're switching between images without rebooting, see if the x86 - * is already powered on; if so, leave it there instead of cycling - * through G3. - */ - if (system_jumped_to_this_image()) { - if ((power_get_signals() & IN_ALL_S0) == IN_ALL_S0) { - CPRINTS("already in S0"); - return POWER_S0; - } else { - /* Force all signals to their G3 states */ - CPRINTS("forcing G3"); - gpio_set_level(GPIO_PCH_PWROK, 0); - gpio_set_level(GPIO_ENABLE_VCORE, 0); - gpio_set_level(GPIO_ENABLE_VS, 0); - gpio_set_level(GPIO_ENABLE_TOUCHPAD, 0); - gpio_set_level(GPIO_TOUCHSCREEN_RESET_L, 0); - gpio_set_level(GPIO_ENABLE_1_5V_DDR, 0); - gpio_set_level(GPIO_PCH_RSMRST_L, 0); - gpio_set_level(GPIO_PCH_DPWROK, 0); - } - } - - return POWER_G3; -} - -enum power_state power_handle_state(enum power_state state) -{ - switch (state) { - case POWER_G3: - break; - - case POWER_S5: - if (gpio_get_level(GPIO_PCH_SLP_S5_L) == 1) { - /* Power up to next state */ - return POWER_S5S3; - } - break; - - case POWER_S3: - /* - * If lid is closed; hold touchscreen in reset to cut power - * usage. If lid is open, take touchscreen out of reset so it - * can wake the processor. - */ - gpio_set_level(GPIO_TOUCHSCREEN_RESET_L, lid_is_open()); - - /* Check for state transitions */ - if (!power_has_signals(IN_PGOOD_S3)) { - /* Required rail went away */ - chipset_force_shutdown(); - return POWER_S3S5; - } else if (gpio_get_level(GPIO_PCH_SLP_S3_L) == 1) { - /* Power up to next state */ - return POWER_S3S0; - } else if (gpio_get_level(GPIO_PCH_SLP_S5_L) == 0) { - /* Power down to next state */ - return POWER_S3S5; - } - break; - - case POWER_S0: - if (!power_has_signals(IN_PGOOD_S0)) { - /* Required rail went away */ - chipset_force_shutdown(); - return POWER_S0S3; - } else if (gpio_get_level(GPIO_PCH_SLP_S3_L) == 0) { - /* Power down to next state */ - return POWER_S0S3; - } - break; - - case POWER_G3S5: - /* - * Wait 10ms after +3VALW good, since that powers VccDSW and - * VccSUS. - */ - msleep(10); - - /* Assert DPWROK, deassert RSMRST# */ - gpio_set_level(GPIO_PCH_DPWROK, 1); - gpio_set_level(GPIO_PCH_RSMRST_L, 1); - - /* Wait 5ms for SUSCLK to stabilize */ - msleep(5); - return POWER_S5; - - case POWER_S5S3: - /* Wait for the always-on rails to be good */ - if (power_wait_signals(IN_PGOOD_ALWAYS_ON)) { - chipset_force_shutdown(); - return POWER_S5; - } - - /* - * Take lightbar out of reset, now that +5VALW is available and - * we won't leak +3VALW through the reset line. - */ - gpio_set_level(GPIO_LIGHTBAR_RESET_L, 1); - - /* Turn on power to RAM */ - gpio_set_level(GPIO_ENABLE_1_5V_DDR, 1); - if (power_wait_signals(IN_PGOOD_S3)) { - chipset_force_shutdown(); - return POWER_S5; - } - - /* - * Enable touchpad power so it can wake the system from - * suspend. - */ - gpio_set_level(GPIO_ENABLE_TOUCHPAD, 1); - - /* Call hooks now that rails are up */ - hook_notify(HOOK_CHIPSET_STARTUP); - return POWER_S3; - - case POWER_S3S0: - /* Turn on power rails */ - gpio_set_level(GPIO_ENABLE_VS, 1); - - /* Enable wireless */ - wireless_set_state(WIRELESS_ON); - - /* - * Make sure touchscreen is out if reset (even if the lid is - * still closed); it may have been turned off if the lid was - * closed in S3. - */ - gpio_set_level(GPIO_TOUCHSCREEN_RESET_L, 1); - - /* Wait for non-core power rails good */ - if (power_wait_signals(IN_PGOOD_S0)) { - chipset_force_shutdown(); - gpio_set_level(GPIO_TOUCHSCREEN_RESET_L, 0); - wireless_set_state(WIRELESS_OFF); - gpio_set_level(GPIO_ENABLE_VS, 0); - return POWER_S3; - } - - /* - * Enable +CPU_CORE and +VGFX_CORE regulator. The CPU itself - * will request the supplies when it's ready. - */ - gpio_set_level(GPIO_ENABLE_VCORE, 1); - - /* Call hooks now that rails are up */ - hook_notify(HOOK_CHIPSET_RESUME); - - /* Wait 99ms after all voltages good */ - msleep(99); - - /* - * Throttle CPU if necessary. This should only be asserted - * when +VCCP is powered (it is by now). - */ - gpio_set_level(GPIO_CPU_PROCHOT, throttle_cpu); - - /* Set PCH_PWROK */ - gpio_set_level(GPIO_PCH_PWROK, 1); - return POWER_S0; - - case POWER_S0S3: - /* Call hooks before we remove power rails */ - hook_notify(HOOK_CHIPSET_SUSPEND); - - /* Clear PCH_PWROK */ - gpio_set_level(GPIO_PCH_PWROK, 0); - - /* Wait 40ns */ - udelay(1); - - /* Disable +CPU_CORE and +VGFX_CORE */ - gpio_set_level(GPIO_ENABLE_VCORE, 0); - - /* Suspend wireless */ - wireless_set_state(WIRELESS_SUSPEND); - - /* - * Deassert prochot since CPU is off and we're about to drop - * +VCCP. - */ - gpio_set_level(GPIO_CPU_PROCHOT, 0); - - /* Turn off power rails */ - gpio_set_level(GPIO_ENABLE_VS, 0); - return POWER_S3; - - case POWER_S3S5: - /* Call hooks before we remove power rails */ - hook_notify(HOOK_CHIPSET_SHUTDOWN); - - /* Disable wireless */ - wireless_set_state(WIRELESS_OFF); - - /* Disable touchpad power */ - gpio_set_level(GPIO_ENABLE_TOUCHPAD, 0); - - /* Turn off power to RAM */ - gpio_set_level(GPIO_ENABLE_1_5V_DDR, 0); - - /* - * Put touchscreen and lightbar in reset, so we won't leak - * +3VALW through the reset line to chips powered by +5VALW. - * - * (Note that we're no longer powering down +5VALW due to - * crosbug.com/p/16600, but to minimize side effects of that - * change we'll still reset these components in S5.) - */ - gpio_set_level(GPIO_TOUCHSCREEN_RESET_L, 0); - gpio_set_level(GPIO_LIGHTBAR_RESET_L, 0); - return POWER_S5; - - case POWER_S5G3: - /* Deassert DPWROK, assert RSMRST# */ - gpio_set_level(GPIO_PCH_DPWROK, 0); - gpio_set_level(GPIO_PCH_RSMRST_L, 0); - return POWER_G3; - } - - return state; -} - -void power_interrupt(enum gpio_signal signal) -{ - /* Route SUSWARN# back to SUSACK# */ - gpio_set_level(GPIO_PCH_SUSACK_L, gpio_get_level(GPIO_PCH_SUSWARN_L)); -} diff --git a/test/adapter.c b/test/adapter.c deleted file mode 100644 index 483dcf82ce..0000000000 --- a/test/adapter.c +++ /dev/null @@ -1,610 +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. - * - * Test GPIO extpower module. - */ - -#include "adc.h" -#include "chipset.h" -#include "common.h" -#include "console.h" -#include "extpower.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "test_util.h" -#include "timer.h" -#include "util.h" -#include "power.h" - -/* Normally private stuff from the modules we're going to test */ -#include "adapter_externs.h" - -/* Local state */ -static int mock_id; -static int mock_current; -static struct charge_state_context ctx; - -/* Mocked functions from the rest of the EC */ - -int adc_read_channel(enum adc_channel ch) -{ - switch (ch) { - case ADC_AC_ADAPTER_ID_VOLTAGE: - return mock_id; - case ADC_CH_CHARGER_CURRENT: - return mock_current; - default: - break; - } - - return 0; -} - -int charger_set_input_current(int input_current) -{ - return EC_SUCCESS; -} - -int charger_get_option(int *option) -{ - return EC_SUCCESS; -} - - -int charger_set_option(int option) -{ - return EC_SUCCESS; -} - -void chipset_throttle_cpu(int throttle) -{ - /* PROCHOT, ugh. */ -} - -/* Local functions to control the mocked functions. */ - -static void change_ac(int val) -{ - gpio_set_level(GPIO_AC_PRESENT, val); - msleep(50); -} - -static void set_id(int val) -{ - mock_id = val; -} - -static void test_reset_mocks(void) -{ - change_ac(0); - set_id(0); - mock_current = 0; - memset(&ctx, 0, sizeof(ctx)); -} - -/* Specify as discharge current */ -static void mock_batt(int cur) -{ - ctx.curr.batt.current = -cur; -} - -/* And the tests themselves... */ - -/* - * Run through the known ID ranges, making sure that values inside are - * correctly identified, and values outside are not. We'll skip the default - * ADAPTER_UNKNOWN range, of course. - * - * NOTE: This assumes that the ranges have a gap between them. - */ -static int test_identification(void) -{ - int i; - - test_reset_mocks(); - - for (i = 1; i < NUM_ADAPTER_TYPES; i++) { - - change_ac(0); - TEST_ASSERT(ac_adapter == ADAPTER_UNKNOWN); - - set_id(ad_id_vals[i].lo - 1); - change_ac(1); - TEST_ASSERT(ac_adapter == ADAPTER_UNKNOWN); - - change_ac(0); - TEST_ASSERT(ac_adapter == ADAPTER_UNKNOWN); - - set_id(ad_id_vals[i].lo); - change_ac(1); - TEST_ASSERT(ac_adapter == i); - - change_ac(0); - TEST_ASSERT(ac_adapter == ADAPTER_UNKNOWN); - - set_id(ad_id_vals[i].hi); - change_ac(1); - TEST_ASSERT(ac_adapter == i); - - change_ac(0); - TEST_ASSERT(ac_adapter == ADAPTER_UNKNOWN); - - set_id(ad_id_vals[i].hi + 1); - change_ac(1); - TEST_ASSERT(ac_adapter == ADAPTER_UNKNOWN); - } - - return EC_SUCCESS; -} - -/* Helper function */ -static void test_turbo_init(void) -{ - /* Battery is awake and in good shape */ - ctx.curr.error = 0; - ctx.curr.batt.state_of_charge = 25; - - /* Adapter is present and known */ - set_id(ad_id_vals[1].lo + 1); - change_ac(1); -} - -/* Test all the things that can turn turbo mode on and off */ -static int test_turbo(void) -{ - test_reset_mocks(); - - /* There's only one path that can enable turbo. Check it first. */ - test_turbo_init(); - watch_adapter_closely(&ctx); - TEST_ASSERT(ac_turbo == 1); - - /* Now test things that turn turbo off. */ - - test_turbo_init(); - ctx.curr.error = 1; - watch_adapter_closely(&ctx); - TEST_ASSERT(ac_turbo == 0); - - test_turbo_init(); - ctx.curr.batt.state_of_charge = 5; - watch_adapter_closely(&ctx); - TEST_ASSERT(ac_turbo == 0); - - test_turbo_init(); - change_ac(0); - set_id(ad_id_vals[1].lo - 1); - change_ac(1); - watch_adapter_closely(&ctx); - TEST_ASSERT(ac_turbo == 0); - - test_turbo_init(); - change_ac(0); - watch_adapter_closely(&ctx); - TEST_ASSERT(ac_turbo == -1); - - return EC_SUCCESS; -} - -/* Check the detection logic on one set of struct adapter_limits */ -static int test_thresholds_sequence(int entry) -{ - struct adapter_limits *lim = &ad_limits[ac_adapter][ac_turbo][entry]; - int longtime = MAX(lim->lo_cnt, lim->hi_cnt) + 2; - int i; - - /* reset, by staying low for a long time */ - mock_current = lim->lo_val - 1; - for (i = 1; i < longtime; i++) - check_threshold(mock_current, lim); - TEST_ASSERT(lim->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* midrange for a long time shouldn't do anything */ - mock_current = (lim->lo_val + lim->hi_val) / 2; - for (i = 1; i < longtime; i++) - check_threshold(mock_current, lim); - TEST_ASSERT(lim->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* above high limit for not quite long enough */ - mock_current = lim->hi_val + 1; - for (i = 1; i < lim->hi_cnt; i++) - check_threshold(mock_current, lim); - TEST_ASSERT(lim->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* drop below the high limit once */ - mock_current = lim->hi_val - 1; - check_threshold(mock_current, lim); - TEST_ASSERT(lim->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* now back up - that should have reset the count */ - mock_current = lim->hi_val + 1; - for (i = 1; i < lim->hi_cnt; i++) - check_threshold(mock_current, lim); - TEST_ASSERT(lim->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* one more ought to do it */ - check_threshold(mock_current, lim); - TEST_ASSERT(lim->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* going midrange for a long time shouldn't change anything */ - mock_current = (lim->lo_val + lim->hi_val) / 2; - for (i = 1; i < longtime; i++) - check_threshold(mock_current, lim); - TEST_ASSERT(lim->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* below low limit for not quite long enough */ - mock_current = lim->lo_val - 1; - for (i = 1; i < lim->lo_cnt; i++) - check_threshold(mock_current, lim); - TEST_ASSERT(lim->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* back above the low limit once */ - mock_current = lim->lo_val + 1; - check_threshold(mock_current, lim); - TEST_ASSERT(lim->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* now back down - that should have reset the count */ - mock_current = lim->lo_val - 1; - for (i = 1; i < lim->lo_cnt; i++) - check_threshold(mock_current, lim); - TEST_ASSERT(lim->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* One more ought to do it */ - check_threshold(mock_current, lim); - TEST_ASSERT(lim->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - return EC_SUCCESS; -} - -/* - * Check all sets of thresholds. This probably doesn't add much value, but at - * least it ensures that they're somewhat sane. - */ -static int test_thresholds(void) -{ - int e; - - for (ac_adapter = 0; ac_adapter < NUM_ADAPTER_TYPES; ac_adapter++) - for (ac_turbo = 0; ac_turbo < NUM_AC_TURBO_STATES; ac_turbo++) - for (e = 0; e < NUM_AC_THRESHOLDS; e++) - TEST_ASSERT(EC_SUCCESS == - test_thresholds_sequence(e)); - - return EC_SUCCESS; -} - -static int test_batt(void) -{ - struct adapter_limits *l, *h; - int longtime; - int i; - - /* NB: struct adapter_limits assumes hi_val > lo_val, so the values in - * batt_limits[] indicate discharge current (mA). However, the value - * returned from battery_current() is postive for charging, and - * negative for discharging. - */ - - /* We're assuming two limits, mild and urgent. */ - TEST_ASSERT(NUM_BATT_THRESHOLDS == 2); - /* Find out which is which */ - if (batt_limits[0].hi_val > batt_limits[1].hi_val) { - h = &batt_limits[0]; - l = &batt_limits[1]; - } else { - h = &batt_limits[1]; - l = &batt_limits[0]; - } - - /* Find a time longer than all sample count limits */ - for (i = longtime = 0; i < NUM_BATT_THRESHOLDS; i++) - longtime = MAX(longtime, - MAX(batt_limits[i].lo_cnt, - batt_limits[i].hi_cnt)); - longtime += 2; - - test_reset_mocks(); - TEST_ASSERT(ap_is_throttled == 0); - - /* reset, by staying low for a long time */ - for (i = 1; i < longtime; i++) - watch_battery_closely(&ctx); - TEST_ASSERT(l->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* mock_batt() specifies the DISCHARGE current. Charging - * should do nothing, no matter how high. */ - mock_batt(-(h->hi_val + 2)); - for (i = 1; i < longtime; i++) - watch_battery_closely(&ctx); - TEST_ASSERT(l->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* midrange for a long time shouldn't do anything */ - mock_batt((l->lo_val + l->hi_val) / 2); - for (i = 1; i < longtime; i++) - watch_battery_closely(&ctx); - TEST_ASSERT(l->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* above high limit for not quite long enough */ - mock_batt(l->hi_val + 1); - for (i = 1; i < l->hi_cnt; i++) - watch_battery_closely(&ctx); - TEST_ASSERT(l->count != 0); - TEST_ASSERT(l->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* drop below the high limit once */ - mock_batt(l->hi_val - 1); - watch_battery_closely(&ctx); - TEST_ASSERT(l->count == 0); - TEST_ASSERT(l->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* now back up */ - mock_batt(l->hi_val + 1); - for (i = 1; i < l->hi_cnt; i++) - watch_battery_closely(&ctx); - TEST_ASSERT(l->count != 0); - TEST_ASSERT(l->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* one more ought to do it */ - watch_battery_closely(&ctx); - TEST_ASSERT(l->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* going midrange for a long time shouldn't change anything */ - mock_batt((l->lo_val + l->hi_val) / 2); - for (i = 1; i < longtime; i++) - watch_battery_closely(&ctx); - TEST_ASSERT(l->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* charge for not quite long enough */ - mock_batt(-1); - for (i = 1; i < l->lo_cnt; i++) - watch_battery_closely(&ctx); - TEST_ASSERT(l->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* back above the low limit once */ - mock_batt(l->lo_val + 1); - watch_battery_closely(&ctx); - TEST_ASSERT(l->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* now charge again - that should have reset the count */ - mock_batt(-1); - for (i = 1; i < l->lo_cnt; i++) - watch_battery_closely(&ctx); - TEST_ASSERT(l->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* One more ought to do it */ - watch_battery_closely(&ctx); - TEST_ASSERT(l->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* Check the high limits too, just for fun */ - mock_batt(h->hi_val + 1); - for (i = 1; i < h->hi_cnt; i++) - watch_battery_closely(&ctx); - TEST_ASSERT(h->triggered == 0); - /* one more */ - watch_battery_closely(&ctx); - TEST_ASSERT(h->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - return EC_SUCCESS; -} - -static int test_batt_vs_adapter(void) -{ - /* Only need one set of adapter thresholds for this test */ - struct adapter_limits *a_lim; - - /* Same structs are used for battery thresholds */ - struct adapter_limits *b_lim; - - int longtime; - int i; - - /* For adapter, we'll use ADAPTER_UNKNOWN, Turbo off, softer limits */ - a_lim = &ad_limits[0][0][0]; - - /* NB: struct adapter_limits assumes hi_val > lo_val, so the values in - * batt_limits[] indicate discharge current (mA). However, the value - * returned from battery_current() is postive for charging, and - * negative for discharging. - */ - - /* We're assuming two limits, mild and urgent. */ - TEST_ASSERT(NUM_BATT_THRESHOLDS == 2); - /* Find out which is which. We want the mild one. */ - if (batt_limits[0].hi_val > batt_limits[1].hi_val) - b_lim = &batt_limits[1]; - else - b_lim = &batt_limits[0]; - - - /* DANGER: we need these two to not be in sync. */ - TEST_ASSERT(a_lim->hi_cnt == 16); - TEST_ASSERT(b_lim->hi_cnt == 16); - /* Now that we know they're the same, let's change one */ - b_lim->hi_cnt = 12; - - /* DANGER: We also rely on these values */ - TEST_ASSERT(a_lim->lo_cnt == 80); - TEST_ASSERT(b_lim->lo_cnt == 50); - - - /* Find a time longer than all sample count limits */ - longtime = MAX(MAX(a_lim->lo_cnt, a_lim->hi_cnt), - MAX(b_lim->lo_cnt, b_lim->hi_cnt)) + 2; - - - test_reset_mocks(); /* everything == 0 */ - ctx.curr.batt.state_of_charge = 25; - change_ac(1); - - /* make sure no limits are triggered by staying low for a long time */ - mock_current = a_lim->lo_val - 1; /* charger current is safe */ - mock_batt(-1); /* battery is charging */ - - for (i = 1; i < longtime; i++) - watch_adapter_closely(&ctx); - TEST_ASSERT(a_lim->triggered == 0); - TEST_ASSERT(b_lim->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - - /* battery discharge current is too high for almost long enough */ - mock_batt(b_lim->hi_val + 1); - for (i = 1; i < b_lim->hi_cnt; i++) - watch_adapter_closely(&ctx); - TEST_ASSERT(b_lim->count != 0); - TEST_ASSERT(b_lim->triggered == 0); - TEST_ASSERT(a_lim->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* one more ought to do it */ - watch_adapter_closely(&ctx); - TEST_ASSERT(b_lim->triggered == 1); - TEST_ASSERT(a_lim->triggered == 0); - TEST_ASSERT(ap_is_throttled); - - - /* charge for not quite long enough */ - mock_batt(-1); - for (i = 1; i < b_lim->lo_cnt; i++) - watch_adapter_closely(&ctx); - TEST_ASSERT(b_lim->triggered == 1); - TEST_ASSERT(a_lim->triggered == 0); - TEST_ASSERT(ap_is_throttled); - - /* and one more */ - watch_adapter_closely(&ctx); - TEST_ASSERT(b_lim->triggered == 0); - TEST_ASSERT(a_lim->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - - /* Now adapter current is too high for almost long enough */ - mock_current = a_lim->hi_val + 1; - for (i = 1; i < a_lim->hi_cnt; i++) - watch_adapter_closely(&ctx); - TEST_ASSERT(a_lim->triggered == 0); - TEST_ASSERT(b_lim->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* one more ought to do it */ - watch_adapter_closely(&ctx); - TEST_ASSERT(a_lim->triggered == 1); - TEST_ASSERT(b_lim->triggered == 0); - TEST_ASSERT(ap_is_throttled); - - /* below low limit for not quite long enough */ - mock_current = a_lim->lo_val - 1; - for (i = 1; i < a_lim->lo_cnt; i++) - watch_adapter_closely(&ctx); - TEST_ASSERT(a_lim->triggered == 1); - TEST_ASSERT(b_lim->triggered == 0); - TEST_ASSERT(ap_is_throttled); - - /* One more ought to do it */ - watch_adapter_closely(&ctx); - TEST_ASSERT(a_lim->triggered == 0); - TEST_ASSERT(b_lim->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - - /* Now both are high, but battery hi_cnt is shorter */ - mock_batt(b_lim->hi_val + 1); - mock_current = a_lim->hi_val + 1; - for (i = 1; i < b_lim->hi_cnt; i++) /* just under battery limit */ - watch_adapter_closely(&ctx); - TEST_ASSERT(a_lim->triggered == 0); - TEST_ASSERT(b_lim->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - /* one more should kick the battery threshold */ - watch_adapter_closely(&ctx); - TEST_ASSERT(a_lim->triggered == 0); - TEST_ASSERT(b_lim->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* don't quite reach the adapter threshold */ - for (i = 1; i < a_lim->hi_cnt - b_lim->hi_cnt; i++) - watch_adapter_closely(&ctx); - TEST_ASSERT(a_lim->triggered == 0); - TEST_ASSERT(b_lim->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* okay, now */ - watch_adapter_closely(&ctx); - TEST_ASSERT(a_lim->triggered == 1); - TEST_ASSERT(b_lim->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* Leave battery high, let the adapter come down */ - mock_current = a_lim->lo_val - 1; - for (i = 1; i < a_lim->lo_cnt; i++) - watch_adapter_closely(&ctx); - TEST_ASSERT(a_lim->triggered == 1); - TEST_ASSERT(b_lim->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* One more ought to do it for the adapter */ - watch_adapter_closely(&ctx); - TEST_ASSERT(a_lim->triggered == 0); - TEST_ASSERT(b_lim->triggered == 1); - TEST_ASSERT(ap_is_throttled); - - /* now charge the battery again */ - mock_batt(-1); - for (i = 1; i < b_lim->lo_cnt; i++) - watch_adapter_closely(&ctx); - TEST_ASSERT(b_lim->triggered == 1); - TEST_ASSERT(a_lim->triggered == 0); - TEST_ASSERT(ap_is_throttled); - - /* and one more */ - watch_adapter_closely(&ctx); - TEST_ASSERT(b_lim->triggered == 0); - TEST_ASSERT(a_lim->triggered == 0); - TEST_ASSERT(ap_is_throttled == 0); - - return EC_SUCCESS; -} - - - -void run_test(void) -{ - test_reset(); - test_chipset_on(); - - RUN_TEST(test_identification); - RUN_TEST(test_turbo); - RUN_TEST(test_thresholds); - RUN_TEST(test_batt); - - RUN_TEST(test_batt_vs_adapter); - - test_print_result(); -} diff --git a/test/adapter.tasklist b/test/adapter.tasklist deleted file mode 100644 index 8ef20bab32..0000000000 --- a/test/adapter.tasklist +++ /dev/null @@ -1,18 +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_TEST(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_TEST_TASK_LIST \ - TASK_TEST(CHIPSET, chipset_task, NULL, TASK_STACK_SIZE) diff --git a/test/adapter_externs.h b/test/adapter_externs.h deleted file mode 100644 index c55cecea88..0000000000 --- a/test/adapter_externs.h +++ /dev/null @@ -1,21 +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. - */ - -#ifndef __ADAPTER_EXTERNS_H -#define __ADAPTER_EXTERNS_H - -/* Normally private symbols from the modules that we're testing. */ - -extern enum adapter_type ac_adapter; -extern struct adapter_id_vals ad_id_vals[]; -extern struct adapter_limits - ad_limits[][NUM_AC_TURBO_STATES][NUM_AC_THRESHOLDS]; -extern int ac_turbo; -extern uint32_t ap_is_throttled; -extern void check_threshold(int current, struct adapter_limits *lim); -extern struct adapter_limits batt_limits[NUM_BATT_THRESHOLDS]; -extern void watch_battery_closely(struct charge_state_context *ctx); - -#endif /* __ADAPTER_EXTERNS_H */ diff --git a/test/build.mk b/test/build.mk index 5addad174f..9fc35555b2 100644 --- a/test/build.mk +++ b/test/build.mk @@ -36,13 +36,12 @@ test-list-$(BOARD_OAK_PD)= # Emulator tests test-list-host=mutex pingpong utils kb_scan kb_mkbp lid_sw power_button hooks test-list-host+=thermal flash queue kb_8042 extpwr_gpio console_edit system -test-list-host+=sbs_charging adapter host_command +test-list-host+=sbs_charging host_command test-list-host+=bklight_lid bklight_passthru interrupt timer_dos button test-list-host+=motion_lid math_util sbs_charging_v2 battery_get_params_smart test-list-host+=lightbar inductive_charging usb_pd fan charge_manager test-list-host+=charge_ramp -adapter-y=adapter.o battery_get_params_smart-y=battery_get_params_smart.o bklight_lid-y=bklight_lid.o bklight_passthru-y=bklight_passthru.o diff --git a/test/stress.c b/test/stress.c index c9c5d7fa36..58a727adbe 100644 --- a/test/stress.c +++ b/test/stress.c @@ -31,23 +31,12 @@ struct i2c_test_param_t { int offset; int data; /* Non-negative represents data to write. -1 to read. */ } i2c_test_params[] = { -#ifdef BOARD_SPRING - {8, 0, 0x60, 0x0, -1}, - {8, 0, 0x60, 0x0, 0x40}, - {8, 0, 0x4a, 0x1, -1}, -#elif defined(BOARD_LINK) - {8, 0, 0x16, 0x8, -1}, - {8, 0, 0x16, 0x9, -1}, - {8, 0, 0x16, 0xa, -1}, -#elif defined(BOARD_PIT) +#if defined(BOARD_PIT) {8, 0, 0x90, 0x19, -1}, -#elif defined(BOARD_SNOW) - {8, 1, 0x90, 0x19, -1}, #endif }; /* Disable I2C test for boards without test configuration */ -#if defined(BOARD_BDS) || defined(BOARD_MCCROSKEY) || \ - defined(BOARD_FALCO) || defined(BOARD_PEPPY) || defined(BOARD_AURON) +#if defined(BOARD_BDS) || defined(BOARD_AURON) #undef CONFIG_I2C #endif diff --git a/test/test_config.h b/test/test_config.h index 39746787b5..88382c89c8 100644 --- a/test/test_config.h +++ b/test/test_config.h @@ -14,11 +14,6 @@ /* Don't compile vboot hash support unless specifically testing for it */ #undef CONFIG_VBOOT_HASH -#ifdef TEST_ADAPTER -#define CONFIG_CHIPSET_CAN_THROTTLE -#define CONFIG_EXTPOWER_FALCO -#endif - #ifdef TEST_BKLIGHT_LID #define CONFIG_BACKLIGHT_LID #endif @@ -40,16 +35,6 @@ #define CONFIG_KEYBOARD_PROTOCOL_MKBP #endif -#ifdef TEST_LED_SPRING -#define CONFIG_BATTERY_MOCK -#define CONFIG_BATTERY_SMART -#define CONFIG_CHARGER_INPUT_CURRENT 4032 -#define CONFIG_LED_DRIVER_LP5562 -#define I2C_PORT_MASTER 1 -#define I2C_PORT_BATTERY 1 -#define I2C_PORT_CHARGER 1 -#endif - #ifdef TEST_MOTION_LID #define CONFIG_LID_ANGLE #define CONFIG_LID_ANGLE_SENSOR_BASE 0 @@ -89,21 +74,6 @@ int board_discharge_on_ac(int enabled); #define CONFIG_TEMP_SENSOR #endif -#ifdef TEST_THERMAL_FALCO -#define CONFIG_BATTERY_MOCK -#define CONFIG_BATTERY_SMART -#define CONFIG_CHARGER -#define CONFIG_CHARGER_V1 -#define CONFIG_CHARGER_INPUT_CURRENT 4032 -#define CONFIG_CHIPSET_CAN_THROTTLE -#define CONFIG_EXTPOWER_FALCO -#define CONFIG_FANS 1 -#define CONFIG_TEMP_SENSOR -#define I2C_PORT_BATTERY 1 -#define I2C_PORT_CHARGER 1 -#define I2C_PORT_MASTER 1 -#endif - #ifdef TEST_FAN #define CONFIG_FANS 1 #endif diff --git a/util/flash_ec b/util/flash_ec index 486e4801d1..a75c0bf637 100755 --- a/util/flash_ec +++ b/util/flash_ec @@ -44,14 +44,10 @@ die() { exit 1 } -# Note: Link is a special case and is not included here. BOARDS_LM4=( auron - falco - peppy rambi samus - squawks ) BOARDS_LM4_USB=( @@ -62,16 +58,11 @@ BOARDS_STM32=( big blaze discovery - firefly - fruitpie glados_pd honeybuns - jerry kitty llama - mighty minimuffin - nyan oak oak_pd pinky @@ -81,9 +72,6 @@ BOARDS_STM32=( ryu_p4p5 ryu_sh samus_pd - snow - speedy - spring zinger ) BOARDS_STM32_PROG_EN=( @@ -404,24 +392,6 @@ function flash_stm32_dfu() { sudo $DFU_UTIL -a 0 -s ${ADDR}:${SIZE} -D "${IMG}" } -function flash_link() { - OCD_PATH="${EC_DIR}/chip/lm4/openocd" - setup_openocd - - OCD_CMDS="init; flash_lm4 ${IMG} ${FLAGS_offset};" - if [ "${FLAGS_unprotect}" = ${FLAGS_TRUE} ] ; then - info "Clearing write protect flag." - OCD_CMDS="${OCD_CMDS} unprotect_link;" - fi - OCD_CMDS="${OCD_CMDS} shutdown;" - - dut_control jtag_buf_on_flex_en:on - dut_control jtag_buf_en:on - - sudo openocd -s "${OCD_PATH}" -f "${OCD_CFG}" -c "${OCD_CMDS}" || \ - die "Failed to program ${IMG}" -} - function flash_lm4() { OCD_PATH="${EC_DIR}/chip/lm4/openocd" setup_openocd @@ -533,8 +503,6 @@ elif $(in_array "${BOARDS_STM32[@]}" "${BOARD}"); then flash_stm32 elif $(in_array "${BOARDS_STM32_DFU[@]}" "${BOARD}"); then flash_stm32_dfu -elif [ "${BOARD}" == "link" ]; then - flash_link elif $(in_array "${BOARDS_NPCX[@]}" "${BOARD}"); then flash_npcx elif $(in_array "${BOARDS_MEC1322[@]}" "${BOARD}"); then diff --git a/util/flash_pd.py b/util/flash_pd.py index f3e9aaeca9..bc9eab1996 100755 --- a/util/flash_pd.py +++ b/util/flash_pd.py @@ -37,12 +37,11 @@ class FlashPDError(Exception): class FlashPD(client.ServoClient): """class to flash PD MCU. - Note, - Some designs(samus) have multiple embedded MCUs. In that case the convention - is to name the pty associated with usbpd as 'usbpd_uart_pty'. In the case - where there is only one MCU (fruitpie) we prefer 'usbpd_uart_pty' but will - also associate 'ecu_uart_pty' with having capability to flash the UBS-PD - capable PSU(zinger). + Note, Some designs(samus) have multiple embedded MCUs. In that case + the convention is to name the pty associated with usbpd as + 'usbpd_uart_pty'. In the case where there is only one MCU we prefer + 'usbpd_uart_pty' but will also associate 'ecu_uart_pty' with having + capability to flash the USB-PD capable PSU(zinger). Attributes: _options : Values instance from optparse. |