summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2015-02-13 17:09:17 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-02-18 04:53:44 +0000
commit9cb03971f6852fa03df3290e44a8451e01774755 (patch)
treef5bc19f5f920555a101a2d62f528f2eb541ff453
parent51227a3cca61bc7a81d391ffab46498ce4cf7fa3 (diff)
downloadchrome-ec-9cb03971f6852fa03df3290e44a8451e01774755.tar.gz
samus: add charge ramp module
Add charge ramp module to samus. For BC1.2 DCPs allow ramping up to 2A, and for BC1.2 SDPs allow ramping to 1A. Charge ramp is disabled when in RO and write protected. BUG=chrome-os-partner:34946 BRANCH=samus TEST=tested with a variety of BC1.2 chargers, type-C only chargers, and PD chargers to make sure we always stabilize charging at an appropriate current limit. tested in RO and write protected, BC1.2 chargers do not ramp. when you jump to RW it does ramp. Change-Id: I7c36c8fb0a34139c69a475307c325f891099b3dd Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/249933 Reviewed-by: Shawn N <shawnn@chromium.org>
-rw-r--r--board/samus_pd/board.c102
-rw-r--r--board/samus_pd/board.h1
-rw-r--r--board/samus_pd/ec.tasklist1
3 files changed, 104 insertions, 0 deletions
diff --git a/board/samus_pd/board.c b/board/samus_pd/board.c
index d4432e73b6..942a0092cd 100644
--- a/board/samus_pd/board.c
+++ b/board/samus_pd/board.c
@@ -8,6 +8,7 @@
#include "adc_chip.h"
#include "battery.h"
#include "charge_manager.h"
+#include "charge_ramp.h"
#include "common.h"
#include "console.h"
#include "gpio.h"
@@ -713,12 +714,108 @@ int pd_is_max_request_allowed(void)
}
/**
+ * Return whether ramping is allowed for given supplier
+ */
+int board_is_ramp_allowed(int supplier)
+{
+ /* Don't allow ramping in RO when write protected */
+ if (system_get_image_copy() != SYSTEM_IMAGE_RW
+ && system_is_locked())
+ return 0;
+ else
+ return supplier == CHARGE_SUPPLIER_BC12_DCP ||
+ supplier == CHARGE_SUPPLIER_BC12_SDP;
+}
+
+/**
+ * Return the maximum allowed input current
+ */
+int board_get_ramp_current_limit(int supplier)
+{
+ switch (supplier) {
+ case CHARGE_SUPPLIER_BC12_DCP:
+ return 2000;
+ case CHARGE_SUPPLIER_BC12_SDP:
+ return 1000;
+ default:
+ return 500;
+ }
+}
+
+/**
+ * Return if board is consuming full amount of input current
+ */
+int board_is_consuming_full_charge(void)
+{
+ return batt_soc >= 1 && batt_soc < 95;
+}
+
+/*
+ * Number of VBUS samples to average when computing if VBUS is too low
+ * for the ramp stable state.
+ */
+#define VBUS_STABLE_SAMPLE_COUNT 4
+
+/* VBUS too low threshold */
+#define VBUS_LOW_THRESHOLD_MV 4600
+
+/**
+ * Return if VBUS is sagging too low
+ */
+int board_is_vbus_too_low(enum chg_ramp_vbus_state ramp_state)
+{
+ static int vbus[VBUS_STABLE_SAMPLE_COUNT];
+ static int vbus_idx, vbus_samples_full;
+ int vbus_sum, i;
+
+ /*
+ * If we are not allowing charging, it's because the EC saw
+ * ACOK go low, so we know VBUS is drooping too far.
+ */
+ if (charge_state == PD_CHARGE_NONE)
+ return 1;
+
+ /* If we are ramping, only look at one reading */
+ if (ramp_state == CHG_RAMP_VBUS_RAMPING) {
+ /* Reset the VBUS array vars used for the stable state */
+ vbus_idx = vbus_samples_full = 0;
+ return adc_read_channel(ADC_VBUS) < VBUS_LOW_THRESHOLD_MV;
+ }
+
+ /* Fill VBUS array with ADC readings */
+ vbus[vbus_idx] = adc_read_channel(ADC_VBUS);
+ vbus_idx = (vbus_idx == VBUS_STABLE_SAMPLE_COUNT-1) ? 0 : vbus_idx + 1;
+ if (vbus_idx == 0)
+ vbus_samples_full = 1;
+
+ /* If VBUS array is not full yet, then return ok */
+ if (!vbus_samples_full)
+ return 0;
+
+ /* All VBUS samples are populated, take average */
+ vbus_sum = 0;
+ for (i = 0; i < VBUS_STABLE_SAMPLE_COUNT; i++)
+ vbus_sum += vbus[i];
+
+ /* Return if average is lower than threshold */
+ return vbus_sum < (VBUS_STABLE_SAMPLE_COUNT * VBUS_LOW_THRESHOLD_MV);
+}
+
+/**
* Set the charge limit based upon desired maximum.
*
* @param charge_ma Desired charge limit (mA).
*/
void board_set_charge_limit(int charge_ma)
{
+ static int last_charge_ma = -1;
+
+ /* if current hasn't changed, don't do anything */
+ if (charge_ma == last_charge_ma)
+ return;
+
+ last_charge_ma = charge_ma;
+
#ifdef CONFIG_PWM
int pwm_duty = MA_TO_PWM(charge_ma);
if (pwm_duty < 0)
@@ -805,6 +902,11 @@ static int ec_status_host_cmd(struct host_cmd_handler_args *args)
gpio_set_level(GPIO_USB_C1_CHARGE_EN_L, 1);
pd_set_new_power_request(
pd_status.active_charge_port);
+ /*
+ * Wake charge ramp task so that it will check
+ * board_is_vbus_too_low() and stop ramping up.
+ */
+ task_wake(TASK_ID_CHG_RAMP);
CPRINTS("Chg: None");
break;
case PD_CHARGE_5V:
diff --git a/board/samus_pd/board.h b/board/samus_pd/board.h
index a0dff70daf..be567cf16d 100644
--- a/board/samus_pd/board.h
+++ b/board/samus_pd/board.h
@@ -19,6 +19,7 @@
#define CONFIG_ADC
#define CONFIG_BOARD_PRE_INIT
#define CONFIG_CHARGE_MANAGER
+#define CONFIG_CHARGE_RAMP
#undef CONFIG_CMD_HASH
#undef CONFIG_CMD_TYPEC
#undef CONFIG_CMD_I2C_SCAN
diff --git a/board/samus_pd/ec.tasklist b/board/samus_pd/ec.tasklist
index 3084a2a74b..aa38ddb8a4 100644
--- a/board/samus_pd/ec.tasklist
+++ b/board/samus_pd/ec.tasklist
@@ -18,6 +18,7 @@
*/
#define CONFIG_TASK_LIST \
TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(CHG_RAMP, chg_ramp_task, NULL, SMALLER_TASK_STACK_SIZE) \
TASK_ALWAYS(USB_CHG_P0, usb_charger_task, NULL, \
SMALLER_TASK_STACK_SIZE) \
TASK_ALWAYS(USB_CHG_P1, usb_charger_task, NULL, \