From f4f934c10374bad4f49a9fe4f96f6140a2e7f2e0 Mon Sep 17 00:00:00 2001 From: Katie Roberts-Hoffman Date: Wed, 5 Mar 2014 16:57:42 -0800 Subject: Add initial big support BRANCH=big BUG=chrome-os-partner:26533 TEST=emerge-nyan_big chromeos-ec; flash big board, verify ec is alive and version is reported as big Change-Id: Idbf84d029b5c7b7c198f8c4a2bd2a90d79524441 Reviewed-on: https://chromium-review.googlesource.com/188926 Tested-by: Katie Roberts-Hoffman Reviewed-by: Yung-chieh Lo Commit-Queue: Katie Roberts-Hoffman Reviewed-by: Randall Spangler --- board/big/battery.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++ board/big/board.c | 121 +++++++++++++++++++++++++ board/big/board.h | 121 +++++++++++++++++++++++++ board/big/build.mk | 13 +++ board/big/ec.tasklist | 24 +++++ util/flash_ec | 2 +- 6 files changed, 522 insertions(+), 1 deletion(-) create mode 100644 board/big/battery.c create mode 100644 board/big/board.c create mode 100644 board/big/board.h create mode 100644 board/big/build.mk create mode 100644 board/big/ec.tasklist diff --git a/board/big/battery.c b/board/big/battery.c new file mode 100644 index 0000000000..6bd445fdf4 --- /dev/null +++ b/board/big/battery.c @@ -0,0 +1,242 @@ +/* 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 CPRINTF(format, args...) cprintf(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 battery_cut_off; + +struct battery_device { + char manuf[9]; + char device[9]; + int design_mv; + struct battery_info *battery_info; + int support_cut_off; +}; + +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_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, + } +}; + +#ifdef CONFIG_BATTERY_VENDOR_PARAMS +/* + * The following parameters are for 2S battery. + * There is no corresponding params for 3S battery. + */ +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; +} + +void battery_vendor_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); + + if (battery_info == NULL) + return; + + /* Return if the battery is not a 2S battery */ + if (battery_info->voltage_max != info_2s.voltage_max) + return; + + /* Limit charging voltage */ + if (batt->desired_voltage > battery_info->voltage_max) + batt->desired_voltage = battery_info->voltage_max; + + /* Don't charge if outside of allowable temperature range */ + if (bat_temp_c >= battery_info->charging_max_c || + bat_temp_c < battery_info->charging_min_c) { + batt->desired_voltage = 0; + batt->desired_current = 0; + batt->flags &= ~BATT_FLAG_WANT_CHARGE; + 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 < battery_info->precharge_current) + *desired_current = battery_info->precharge_current; +} +#endif /* CONFIG_BATTERY_VENDOR_PARAMS */ + +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))) { + CPRINTF("[%T Failed to get MANUF name]\n"); + return NULL; + } + + if (battery_device_name(device, sizeof(device))) { + CPRINTF("[%T Failed to get DEVICE name]\n"); + return NULL; + } + if (battery_design_voltage((int *)&design_mv)) { + CPRINTF("[%T Failed to get DESIGN_VOLTAGE]\n"); + return NULL; + } + + 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)) { + CPRINTF("[%T battery Manuf:%s, Device=%s, design=%u]\n", + manuf, device, design_mv); + battery_cut_off = support_batteries[i].support_cut_off; + battery_info = support_batteries[i].battery_info; + return battery_info; + } + } + + return NULL; +} + +int battery_command_cut_off(struct host_cmd_handler_args *args) +{ + if (battery_cut_off) + return sb_write(SB_SHIP_MODE_ADDR, SB_SHIP_MODE_DATA); + else + return EC_RES_INVALID_COMMAND; +} +DECLARE_HOST_COMMAND(EC_CMD_BATTERY_CUT_OFF, battery_command_cut_off, + EC_VER_MASK(0)); diff --git a/board/big/board.c b/board/big/board.c new file mode 100644 index 0000000000..4cf2dac7b9 --- /dev/null +++ b/board/big/board.c @@ -0,0 +1,121 @@ +/* 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. + */ +/* 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" + +#define GPIO_KB_INPUT (GPIO_INPUT | GPIO_PULL_UP | GPIO_INT_BOTH) +#define GPIO_KB_OUTPUT GPIO_ODR_HIGH + +/* GPIO signal list. Must match order from enum gpio_signal. */ +const struct gpio_info gpio_list[] = { + /* Inputs with interrupt handlers are first for efficiency */ + {"POWER_BUTTON_L", GPIO_B, (1<<5), GPIO_INT_BOTH, + power_button_interrupt}, + {"XPSHOLD", GPIO_A, (1<<3), GPIO_INT_BOTH, + power_signal_interrupt}, + {"LID_OPEN", GPIO_C, (1<<13), GPIO_INT_BOTH, lid_interrupt}, + {"SUSPEND_L", GPIO_C, (1<<7), GPIO_KB_INPUT, + power_signal_interrupt}, + {"SPI1_NSS", GPIO_A, (1<<4), GPIO_INT_BOTH | GPIO_PULL_UP, + spi_event}, + {"AC_PRESENT", GPIO_A, (1<<0), GPIO_INT_BOTH, extpower_interrupt}, + {"KB_IN00", GPIO_C, (1<<8), GPIO_KB_INPUT, + keyboard_raw_gpio_interrupt}, + {"KB_IN01", GPIO_C, (1<<9), GPIO_KB_INPUT, + keyboard_raw_gpio_interrupt}, + {"KB_IN02", GPIO_C, (1<<10), GPIO_KB_INPUT, + keyboard_raw_gpio_interrupt}, + {"KB_IN03", GPIO_C, (1<<11), GPIO_KB_INPUT, + keyboard_raw_gpio_interrupt}, + {"KB_IN04", GPIO_C, (1<<12), GPIO_KB_INPUT, + keyboard_raw_gpio_interrupt}, + {"KB_IN05", GPIO_C, (1<<14), GPIO_KB_INPUT, + keyboard_raw_gpio_interrupt}, + {"KB_IN06", GPIO_C, (1<<15), GPIO_KB_INPUT, + keyboard_raw_gpio_interrupt}, + {"KB_IN07", GPIO_D, (1<<2), GPIO_KB_INPUT, + keyboard_raw_gpio_interrupt}, + /* Other inputs */ + {"WP_L", GPIO_B, (1<<4), GPIO_INPUT, NULL}, + /* Outputs */ + {"AP_RESET_L", GPIO_B, (1<<3), GPIO_ODR_HIGH, NULL}, + {"CHARGER_EN", GPIO_B, (1<<2), GPIO_OUT_LOW, NULL}, + {"EC_INT", GPIO_B, (1<<9), GPIO_ODR_HIGH, NULL}, + {"ENTERING_RW", GPIO_H, (1<<0), GPIO_OUT_LOW, NULL}, + {"I2C1_SCL", GPIO_B, (1<<6), GPIO_ODR_HIGH, NULL}, + {"I2C1_SDA", GPIO_B, (1<<7), GPIO_ODR_HIGH, NULL}, + {"I2C2_SCL", GPIO_B, (1<<10), GPIO_ODR_HIGH, NULL}, + {"I2C2_SDA", GPIO_B, (1<<11), GPIO_ODR_HIGH, NULL}, + {"LED_POWER_L", GPIO_A, (1<<2), GPIO_OUT_HIGH, NULL}, /* PWR_LED1 */ + {"PMIC_PWRON_L", GPIO_A, (1<<12), GPIO_OUT_HIGH, NULL}, + {"PMIC_RESET", GPIO_A, (1<<15), GPIO_OUT_LOW, NULL}, + {"KB_OUT00", GPIO_B, (1<<0), GPIO_KB_OUTPUT, NULL}, + {"KB_OUT01", GPIO_B, (1<<8), GPIO_KB_OUTPUT, NULL}, + {"KB_OUT02", GPIO_B, (1<<12), GPIO_KB_OUTPUT, NULL}, + {"KB_OUT03", GPIO_B, (1<<13), GPIO_KB_OUTPUT, NULL}, + {"KB_OUT04", GPIO_B, (1<<14), GPIO_KB_OUTPUT, NULL}, + {"KB_OUT05", GPIO_B, (1<<15), GPIO_KB_OUTPUT, NULL}, + {"KB_OUT06", GPIO_C, (1<<0), GPIO_KB_OUTPUT, NULL}, + {"KB_OUT07", GPIO_C, (1<<1), GPIO_KB_OUTPUT, NULL}, + {"KB_OUT08", GPIO_C, (1<<2), GPIO_KB_OUTPUT, NULL}, + {"KB_OUT09", GPIO_B, (1<<1), GPIO_KB_OUTPUT, NULL}, + {"KB_OUT10", GPIO_C, (1<<5), GPIO_KB_OUTPUT, NULL}, + {"KB_OUT11", GPIO_C, (1<<4), GPIO_KB_OUTPUT, NULL}, + {"KB_OUT12", GPIO_A, (1<<13), GPIO_KB_OUTPUT, NULL}, + {"PWR_LED0", GPIO_B, (1<<10), GPIO_OUT_LOW, NULL}, + {"BAT_LED0", GPIO_B, (1<<11), GPIO_OUT_LOW, NULL}, + {"BAT_LED1", GPIO_A, (1<<8), GPIO_OUT_LOW, NULL}, + {"CHARGING", GPIO_A, (1<<11), GPIO_OUT_LOW, NULL}, + {"EC_BL_OVERRIDE", GPIO_H, (1<<1), GPIO_ODR_HIGH, NULL}, + {"PMIC_THERM_L", GPIO_A, (1<<1), GPIO_ODR_HIGH, NULL}, + {"PMIC_WARM_RESET_L", GPIO_C, (1<<3), GPIO_ODR_HIGH, NULL}, +}; +BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT); + +/* Pins with alternate functions */ +const struct gpio_alt_func gpio_alt_funcs[] = { + {GPIO_A, 0x00f0, GPIO_ALT_SPI, MODULE_SPI, GPIO_DEFAULT}, + {GPIO_A, 0x0600, GPIO_ALT_USART, MODULE_UART, GPIO_DEFAULT}, + {GPIO_B, 0x00c0, GPIO_ALT_I2C, MODULE_I2C, GPIO_DEFAULT}, +}; +const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs); + +/* 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, GPIO_LED_POWER_L}, +}; +BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); diff --git a/board/big/board.h b/board/big/board.h new file mode 100644 index 0000000000..cd51279259 --- /dev/null +++ b/board/big/board.h @@ -0,0 +1,121 @@ +/* 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. + */ + +/* Big board configuration */ + +#ifndef __BOARD_H +#define __BOARD_H + +/* Optional features */ +#define CONFIG_AP_HANG_DETECT +#define CONFIG_BATTERY_SMART +#define CONFIG_CHARGER +#define CONFIG_CHARGER_BQ24725 +#define CONFIG_CHIPSET_TEGRA +#define CONFIG_POWER_COMMON +#define CONFIG_EXTPOWER_GPIO +#define CONFIG_HOST_COMMAND_STATUS +#define CONFIG_I2C +#define CONFIG_KEYBOARD_PROTOCOL_MKBP +#define CONFIG_SPI +#define CONFIG_PWM +#define CONFIG_POWER_BUTTON +#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 + +/* Timer selection */ +#define TIM_CLOCK_MSB 3 +#define TIM_CLOCK_LSB 9 +#define TIM_POWER_LED 2 +#define TIM_WATCHDOG 4 + +/* GPIO signal list */ +enum gpio_signal { + /* Inputs with interrupt handlers are first for efficiency */ + GPIO_POWER_BUTTON_L = 0, + GPIO_SOC1V8_XPSHOLD, + GPIO_LID_OPEN, + GPIO_SUSPEND_L, + GPIO_SPI1_NSS, + GPIO_AC_PRESENT, + /* Keyboard inputs */ + GPIO_KB_IN00, + GPIO_KB_IN01, + GPIO_KB_IN02, + GPIO_KB_IN03, + GPIO_KB_IN04, + GPIO_KB_IN05, + GPIO_KB_IN06, + GPIO_KB_IN07, + /* Other inputs */ + GPIO_WP_L, + /* Outputs */ + GPIO_AP_RESET_L, + GPIO_CHARGER_EN, + GPIO_EC_INT, + GPIO_ENTERING_RW, + GPIO_I2C1_SCL, + GPIO_I2C1_SDA, + GPIO_I2C2_SCL, + GPIO_I2C2_SDA, + GPIO_LED_POWER_L, /* alias to GPIO_PWR_LED1 */ + GPIO_PMIC_PWRON_L, + GPIO_PMIC_RESET, + GPIO_KB_OUT00, + GPIO_KB_OUT01, + GPIO_KB_OUT02, + GPIO_KB_OUT03, + GPIO_KB_OUT04, + GPIO_KB_OUT05, + GPIO_KB_OUT06, + GPIO_KB_OUT07, + GPIO_KB_OUT08, + GPIO_KB_OUT09, + GPIO_KB_OUT10, + GPIO_KB_OUT11, + GPIO_KB_OUT12, + GPIO_PWR_LED0, + GPIO_BAT_LED0, + GPIO_BAT_LED1, + GPIO_CHARGING, + GPIO_EC_BL_OVERRIDE, + GPIO_PMIC_THERM_L, + GPIO_PMIC_WARM_RESET_L, + /* Number of GPIOs; not an actual GPIO */ + GPIO_COUNT +}; + +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 */ +#define CONFIG_CHARGER_INPUT_CURRENT 4032 /* mA, based on Link HW design */ +#define CONFIG_CHARGER_CURRENT_LIMIT 3000 /* PL102 inductor 3.0A(3.8A) */ + +#endif /* !__ASSEMBLER__ */ + +#endif /* __BOARD_H */ diff --git a/board/big/build.mk b/board/big/build.mk new file mode 100644 index 0000000000..c950c382d6 --- /dev/null +++ b/board/big/build.mk @@ -0,0 +1,13 @@ +# -*- 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 STM32L100RBT6 +CHIP:=stm32 +CHIP_FAMILY:=stm32l +CHIP_VARIANT:=stm32l100 + +board-y=board.o battery.o diff --git a/board/big/ec.tasklist b/board/big/ec.tasklist new file mode 100644 index 0000000000..dcdca4df28 --- /dev/null +++ b/board/big/ec.tasklist @@ -0,0 +1,24 @@ +/* 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_NOTEST(POWERLED, power_led_task, NULL, 256) \ + 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) diff --git a/util/flash_ec b/util/flash_ec index 9a64bde8c4..c6eabf3419 100755 --- a/util/flash_ec +++ b/util/flash_ec @@ -222,7 +222,7 @@ fi save="$(servo_save)" case "${BOARD}" in - discovery | nyan | pit | snow | spring ) flash_stm32 ;; + big | discovery | nyan | pit | snow | spring ) flash_stm32 ;; falco | peppy | rambi | samus | squawks ) flash_lm4 ;; link ) flash_link ;; *) die "board ${BOARD} not supported" ;; -- cgit v1.2.1