Driver: BD99955: Enable BC1.2 support

BUG=none
BRANCH=none
TEST=Manually tested on Amenia.
     Connected Zinger, Type-C, DCP & CDP chargers. Device can negotiate
     to desired current & voltage and the battery can charge.
     USB2.0 sync device is detected by Kernel.

Change-Id: I58cb69289eef9a966e06bef8fe31d35beaec5e27
Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/341030
Commit-Ready: Vijay P Hiremath <vijay.p.hiremath@intel.com>
Tested-by: Vijay P Hiremath <vijay.p.hiremath@intel.com>
Tested-by: Kevin K Wong <kevin.k.wong@intel.com>
Reviewed-by: Shawn N <shawnn@chromium.org>
This commit is contained in:
Vijay Hiremath
2016-04-16 01:08:55 -07:00
committed by chrome-bot
parent f4e617e118
commit 313355302b
23 changed files with 372 additions and 85 deletions

View File

@@ -49,43 +49,6 @@
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
#if 1 /* TODO: CHARGER / BC1.2 */
static void update_vbus_supplier(int port, int vbus_level)
{
struct charge_port_info charge;
charge.voltage = USB_CHARGER_VOLTAGE_MV;
charge.current = vbus_level ? USB_CHARGER_MIN_CURR_MA : 0;
charge_manager_update_charge(CHARGE_SUPPLIER_VBUS, port, &charge);
}
static void reset_charge(int port)
{
struct charge_port_info charge_none;
charge_none.voltage = USB_CHARGER_VOLTAGE_MV;
charge_none.current = 0;
charge_manager_update_charge(CHARGE_SUPPLIER_PROPRIETARY,
port,
&charge_none);
charge_manager_update_charge(CHARGE_SUPPLIER_BC12_CDP,
port,
&charge_none);
charge_manager_update_charge(CHARGE_SUPPLIER_BC12_DCP,
port,
&charge_none);
charge_manager_update_charge(CHARGE_SUPPLIER_BC12_SDP,
port,
&charge_none);
charge_manager_update_charge(CHARGE_SUPPLIER_OTHER,
port,
&charge_none);
/* Initialize VBUS supplier based on whether VBUS is present */
update_vbus_supplier(port, pd_snk_is_vbus_provided(port));
}
#endif
uint16_t tcpc_get_alert_status(void)
{
uint16_t status = 0;
@@ -123,8 +86,7 @@ void vbus0_evt(enum gpio_signal signal)
return;
/* VBUS present GPIO is inverted */
update_vbus_supplier(0, !gpio_get_level(signal));
usb_charger_vbus_change(0, !gpio_get_level(signal));
task_wake(TASK_ID_PD_C0);
}
@@ -134,8 +96,7 @@ void vbus1_evt(enum gpio_signal signal)
return;
/* VBUS present GPIO is inverted */
update_vbus_supplier(1, !gpio_get_level(signal));
usb_charger_vbus_change(1, !gpio_get_level(signal));
task_wake(TASK_ID_PD_C1);
}
@@ -309,14 +270,6 @@ const struct button_config buttons[CONFIG_BUTTON_COUNT] = {
/* Initialize board. */
static void board_init(void)
{
#if 1 /* TODO: CHARGER / BC1.2 */
int i;
/* Initialize all BC1.2 charge suppliers to 0 */
for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++)
reset_charge(i);
#endif
#if 0 /* TODO: CHARGER */
/* Enable charger interrupt */
gpio_enable_interrupt(GPIO_CHARGER_INT_L);
@@ -343,8 +296,7 @@ int board_set_active_charge_port(int charge_port)
int is_real_port = (charge_port >= 0 &&
charge_port < CONFIG_USB_PD_PORT_COUNT);
/* check if we are source vbus on that port */
int source = gpio_get_level(charge_port == 0 ? GPIO_USB_C0_5V_EN :
GPIO_USB_C1_5V_EN);
int source = usb_charger_port_is_sourcing_vbus(charge_port);
if (is_real_port && source) {
CPRINTS("Skip enable p%d", charge_port);
@@ -374,10 +326,20 @@ int board_set_active_charge_port(int charge_port)
/**
* Set the charge limit based upon desired maximum.
*
* @param port Port number.
* @param supplier Charge supplier type.
* @param charge_ma Desired charge limit (mA).
*/
void board_set_charge_limit(int charge_ma)
void board_set_charge_limit(int port, int supplier, int charge_ma)
{
/* Enable charging trigger by BC1.2 detection */
if (supplier == CHARGE_SUPPLIER_BC12_CDP ||
supplier == CHARGE_SUPPLIER_BC12_DCP ||
supplier == CHARGE_SUPPLIER_BC12_SDP) {
if (bd99955_bc12_enable_charging(port, 1))
return;
}
charge_set_input_current_limit(MAX(charge_ma,
CONFIG_CHARGER_INPUT_CURRENT));
}

View File

@@ -42,6 +42,7 @@
#define CONFIG_CHARGER_NARROW_VDC
#define CONFIG_CHARGER_SENSE_RESISTOR 10
#define CONFIG_CHARGER_SENSE_RESISTOR_AC 20
#define CONFIG_USB_CHARGER
#define CONFIG_CHIPSET_APOLLOLAKE
#define CONFIG_CMD_ACCELS

View File

@@ -19,6 +19,8 @@
#define CONFIG_TASK_LIST \
TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \
TASK_ALWAYS(ALS, als_task, NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(USB_CHG_P0, usb_charger_task, NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(USB_CHG_P1, usb_charger_task, NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(CHARGER, charger_task, NULL, LARGER_TASK_STACK_SIZE) \
TASK_NOTEST(MOTIONSENSE, motion_sense_task, NULL, VENTI_TASK_STACK_SIZE) \
TASK_NOTEST(CHIPSET, chipset_task, NULL, LARGER_TASK_STACK_SIZE) \

View File

@@ -352,9 +352,11 @@ int board_set_active_charge_port(int charge_port)
/**
* Set the charge limit based upon desired maximum.
*
* @param port Port number.
* @param supplier Charge supplier type.
* @param charge_ma Desired charge limit (mA).
*/
void board_set_charge_limit(int charge_ma)
void board_set_charge_limit(int port, int supplier, int charge_ma)
{
charge_set_input_current_limit(MAX(charge_ma,
CONFIG_CHARGER_INPUT_CURRENT));

View File

@@ -289,9 +289,11 @@ int board_set_active_charge_port(int charge_port)
/**
* Set the charge limit based upon desired maximum.
*
* @param port Port number.
* @param supplier Charge supplier type.
* @param charge_ma Desired charge limit (mA).
*/
void board_set_charge_limit(int charge_ma)
void board_set_charge_limit(int port, int supplier, int charge_ma)
{
charge_set_input_current_limit(MAX(charge_ma,
CONFIG_CHARGER_INPUT_CURRENT));

View File

@@ -323,9 +323,11 @@ int board_set_active_charge_port(int charge_port)
/**
* Set the charge limit based upon desired maximum.
*
* @param port Port number.
* @param supplier Charge supplier type.
* @param charge_ma Desired charge limit (mA).
*/
void board_set_charge_limit(int charge_ma)
void board_set_charge_limit(int port, int supplier, int charge_ma)
{
charge_set_input_current_limit(MAX(charge_ma,
CONFIG_CHARGER_INPUT_CURRENT));

View File

@@ -196,7 +196,7 @@ int board_set_active_charge_port(int charge_port)
return bd99955_select_input_port(bd99955_port);
}
void board_set_charge_limit(int charge_ma)
void board_set_charge_limit(int port, int supplier, int charge_ma)
{
charge_set_input_current_limit(MAX(charge_ma,
CONFIG_CHARGER_INPUT_CURRENT));

View File

@@ -165,7 +165,7 @@ int board_set_active_charge_port(int charge_port)
return EC_SUCCESS;
}
void board_set_charge_limit(int charge_ma)
void board_set_charge_limit(int port, int supplier, int charge_ma)
{
int rv;

View File

@@ -318,9 +318,11 @@ int board_set_active_charge_port(int charge_port)
/**
* Set the charge limit based upon desired maximum.
*
* @param port Port number.
* @param supplier Charge supplier type.
* @param charge_ma Desired charge limit (mA).
*/
void board_set_charge_limit(int charge_ma)
void board_set_charge_limit(int port, int supplier, int charge_ma)
{
charge_set_input_current_limit(MAX(charge_ma,
CONFIG_CHARGER_INPUT_CURRENT));

View File

@@ -363,9 +363,11 @@ int board_set_active_charge_port(int charge_port)
/**
* Set the charge limit based upon desired maximum.
*
* @param port Port number.
* @param supplier Charge supplier type.
* @param charge_ma Desired charge limit (mA).
*/
void board_set_charge_limit(int charge_ma)
void board_set_charge_limit(int port, int supplier, int charge_ma)
{
charge_set_input_current_limit(MAX(charge_ma,
CONFIG_CHARGER_INPUT_CURRENT));

View File

@@ -546,9 +546,11 @@ int board_set_active_charge_port(int charge_port)
/**
* Set the charge limit based upon desired maximum.
*
* @param port Port number.
* @param supplier Charge supplier type.
* @param charge_ma Desired charge limit (mA).
*/
void board_set_charge_limit(int charge_ma)
void board_set_charge_limit(int port, int supplier, int charge_ma)
{
int rv;

View File

@@ -276,7 +276,7 @@ enum usb_strings {
#define PD_PREFER_LOW_VOLTAGE
/* Set the charge current limit. */
void board_set_charge_limit(int charge_ma);
void board_set_charge_limit(int port, int supplier, int charge_ma);
/* PP1800 transition GPIO interrupt handler */
void pp1800_on_off_evt(enum gpio_signal signal);

View File

@@ -495,9 +495,11 @@ static int board_update_charge_limit(int charge_ma)
/**
* Set the charge limit based upon desired maximum.
*
* @param port Port number.
* @param supplier Charge supplier type.
* @param charge_ma Desired charge limit (mA).
*/
void board_set_charge_limit(int charge_ma)
void board_set_charge_limit(int port, int supplier, int charge_ma)
{
/* Update current limit and notify EC if it changed */
if (board_update_charge_limit(charge_ma))

View File

@@ -346,9 +346,11 @@ int board_set_active_charge_port(int charge_port)
/**
* Set the charge limit based upon desired maximum.
*
* @param port Port number.
* @param supplier Charge supplier type.
* @param charge_ma Desired charge limit (mA).
*/
void board_set_charge_limit(int charge_ma)
void board_set_charge_limit(int port, int supplier, int charge_ma)
{
charge_set_input_current_limit(MAX(charge_ma,
CONFIG_CHARGER_INPUT_CURRENT));

View File

@@ -305,9 +305,11 @@ int board_set_active_charge_port(int charge_port)
/**
* Set the charge limit based upon desired maximum.
*
* @param port Port number.
* @param supplier Charge supplier type.
* @param charge_ma Desired charge limit (mA).
*/
void board_set_charge_limit(int charge_ma)
void board_set_charge_limit(int port, int supplier, int charge_ma)
{
charge_set_input_current_limit(MAX(charge_ma,
CONFIG_CHARGER_INPUT_CURRENT));

View File

@@ -527,8 +527,9 @@ static void charge_manager_refresh(void)
/* Enable or disable charge ramp */
charger_set_hw_ramp(board_is_ramp_allowed(new_supplier));
#endif
board_set_charge_limit(new_charge_current);
#endif
board_set_charge_limit(new_port, new_supplier,
new_charge_current);
#endif /* HAS_TASK_CHG_RAMP */
CPRINTS("CL: p%d s%d i%d v%d", new_port, new_supplier,
new_charge_current, new_charge_voltage);
}
@@ -996,3 +997,18 @@ DECLARE_CONSOLE_COMMAND(chglim, command_external_power_limit,
"Set max charger current / voltage",
NULL);
#endif /* CONFIG_CHARGE_MANAGER_EXTERNAL_POWER_LIMIT */
#ifdef CONFIG_CMD_CHARGE_SUPPLIER_INFO
static int charge_supplier_info(int argc, char **argv)
{
ccprintf("port=%d, type=%d, cur=%dmA, vtg=%dmV\n",
charge_manager_get_active_charge_port(),
charge_supplier,
charge_current,
charge_voltage);
return 0;
}
DECLARE_CONSOLE_COMMAND(chgsup, charge_supplier_info,
NULL, "print chg supplier info", NULL);
#endif

View File

@@ -319,7 +319,8 @@ void chg_ramp_task(void)
active_icl = active_icl_new;
/* Set the input current limit */
board_set_charge_limit(chg_ramp_get_current_limit());
board_set_charge_limit(active_port, active_sup,
chg_ramp_get_current_limit());
if (ramp_st == CHG_RAMP_STABILIZE)
/*

View File

@@ -8,16 +8,28 @@
#include "battery.h"
#include "battery_smart.h"
#include "bd99955.h"
#include "charge_manager.h"
#include "charger.h"
#include "console.h"
#include "ec_commands.h"
#include "hooks.h"
#include "i2c.h"
#include "task.h"
#include "time.h"
#include "util.h"
#include "usb_charge.h"
#include "usb_pd.h"
#define OTPROM_LOAD_WAIT_RETRY 3
#define BD99955_CHARGE_PORT_COUNT 2
/* Console output macros */
#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args)
/* TODO: Add accurate timeout for detecting BC1.2 */
#define BC12_DETECT_RETRY 10
/* Charger parameters */
static const struct charger_info bd99955_charger_info = {
.name = CHARGER_NAME,
@@ -37,6 +49,14 @@ static enum bd99955_command charger_map_cmd = BD99955_INVALID_COMMAND;
static struct mutex bd99955_map_mutex;
#if defined(HAS_TASK_USB_CHG_P0) || defined(HAS_TASK_USB_CHG_P1)
/* USB switch */
static enum usb_switch usb_switch_state[BD99955_CHARGE_PORT_COUNT] = {
USB_SWITCH_DISCONNECT,
USB_SWITCH_DISCONNECT,
};
#endif
static inline int ch_raw_read16(int cmd, int *param,
enum bd99955_command map_cmd)
{
@@ -108,9 +128,34 @@ static int bd99955_charger_enable(int enable)
static int bd99955_por_reset(void)
{
return ch_raw_write16(BD99955_CMD_SYSTEM_CTRL_SET,
BD99955_CMD_SYSTEM_CTRL_SET_OTPLD |
BD99955_CMD_SYSTEM_CTRL_SET_ALLRST,
int rv;
int reg;
int i;
rv = ch_raw_write16(BD99955_CMD_SYSTEM_CTRL_SET,
BD99955_CMD_SYSTEM_CTRL_SET_OTPLD |
BD99955_CMD_SYSTEM_CTRL_SET_ALLRST,
BD99955_EXTENDED_COMMAND);
if (rv)
return rv;
/* Wait until OTPROM loading is finished */
for (i = 0; i < OTPROM_LOAD_WAIT_RETRY; i++) {
msleep(10);
rv = ch_raw_read16(BD99955_CMD_SYSTEM_STATUS, &reg,
BD99955_EXTENDED_COMMAND);
if (!rv && (reg & BD99955_CMD_SYSTEM_STATUS_OTPLD_STATE) &&
(reg & BD99955_CMD_SYSTEM_STATUS_ALLRST_STATE))
break;
}
if (rv)
return rv;
if (i == OTPROM_LOAD_WAIT_RETRY)
return EC_ERROR_TIMEOUT;
return ch_raw_write16(BD99955_CMD_SYSTEM_CTRL_SET, 0,
BD99955_EXTENDED_COMMAND);
}
@@ -131,6 +176,125 @@ static int bd99955_get_charger_op_status(int *status)
BD99955_EXTENDED_COMMAND);
}
#if defined(HAS_TASK_USB_CHG_P0) || defined(HAS_TASK_USB_CHG_P1)
static int bd99955_get_bc12_device_type(enum bd99955_charge_port port)
{
int rv;
int reg;
rv = ch_raw_read16((port == BD99955_CHARGE_PORT_VBUS) ?
BD99955_CMD_VBUS_UCD_STATUS :
BD99955_CMD_VCC_UCD_STATUS,
&reg, BD99955_EXTENDED_COMMAND);
if (rv)
return CHARGE_SUPPLIER_NONE;
switch (reg & BD99955_TYPE_MASK) {
case BD99955_TYPE_CDP:
return CHARGE_SUPPLIER_BC12_CDP;
case BD99955_TYPE_DCP:
return CHARGE_SUPPLIER_BC12_DCP;
case BD99955_TYPE_SDP:
return CHARGE_SUPPLIER_BC12_SDP;
case BD99955_TYPE_VBUS_OPEN:
case BD99955_TYPE_PUP_PORT:
case BD99955_TYPE_OPEN_PORT:
default:
return CHARGE_SUPPLIER_NONE;
}
}
static int bd99955_get_bc12_ilim(int charge_supplier)
{
switch (charge_supplier) {
case CHARGE_SUPPLIER_BC12_CDP:
return 1500;
case CHARGE_SUPPLIER_BC12_DCP:
return 2000;
case CHARGE_SUPPLIER_BC12_SDP:
return 900;
default:
return 500;
}
}
static int bd99955_enable_usb_switch(enum bd99955_charge_port port,
enum usb_switch setting)
{
int rv;
int reg;
int port_reg;
port_reg = (port == BD99955_CHARGE_PORT_VBUS) ?
BD99955_CMD_VBUS_UCD_SET : BD99955_CMD_VCC_UCD_SET;
rv = ch_raw_read16(port_reg, &reg, BD99955_EXTENDED_COMMAND);
if (rv)
return rv;
if (setting == USB_SWITCH_CONNECT)
reg |= BD99955_CMD_UCD_SET_USB_SW_EN;
else
reg &= ~BD99955_CMD_UCD_SET_USB_SW_EN;
return ch_raw_write16(port_reg, reg, BD99955_EXTENDED_COMMAND);
}
static int bd99955_bc12_detect(int port)
{
int i;
int bc12_type;
struct charge_port_info charge;
/*
* BC1.2 detection starts 100ms after VBUS/VCC attach and typically
* completes 312ms after VBUS/VCC attach.
*/
msleep(312);
for (i = 0; i < BC12_DETECT_RETRY; i++) {
/* get device type */
bc12_type = bd99955_get_bc12_device_type(port);
/* Detected BC1.2 */
if (bc12_type != CHARGE_SUPPLIER_NONE)
break;
/* TODO: Add accurate timeout for detecting BC1.2 */
msleep(100);
}
/* BC1.2 device attached */
if (bc12_type != CHARGE_SUPPLIER_NONE) {
/* Update charge manager */
charge.voltage = USB_CHARGER_VOLTAGE_MV;
charge.current = bd99955_get_bc12_ilim(bc12_type);
charge_manager_update_charge(bc12_type, port, &charge);
/* notify host of power info change */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
}
return bc12_type;
}
static void bd99955_bc12_detach(int port, int type)
{
struct charge_port_info charge = {
.voltage = USB_CHARGER_VOLTAGE_MV,
.current = 0,
};
/* Update charge manager */
charge_manager_update_charge(type, port, &charge);
/* Disable charging trigger by BC1.2 detection */
bd99955_bc12_enable_charging(port, 0);
/* notify host of power info change */
pd_send_host_event(PD_EVENT_POWER_CHANGE);
}
#endif /* defined(HAS_TASK_USB_CHG_P0) || defined(HAS_TASK_USB_CHG_P1) */
/* chip specific interfaces */
@@ -140,7 +304,6 @@ int charger_set_input_current(int input_current)
/* Input current step 32 mA */
input_current &= ~0x1F;
rv = ch_raw_write16(BD99955_CMD_IBUS_LIM_SET, input_current,
BD99955_BAT_CHG_COMMAND);
if (rv)
@@ -247,9 +410,7 @@ int charger_get_status(int *status)
*status |= CHARGER_POWER_FAIL;
/* Safety signal ranges & battery presence */
ch_status = (reg & BD99955_CMD_CHGOP_STATUS_BATTEMP0) |
((reg & BD99955_CMD_CHGOP_STATUS_BATTEMP1) << 1) |
((reg & BD99955_CMD_CHGOP_STATUS_BATTEMP2) << 2);
ch_status = (reg & BD99955_BATTTEMP_MASK) >> 8;
*status |= CHARGER_BATTERY_PRESENT;
@@ -346,31 +507,44 @@ static void bd99995_init(void)
int reg;
const struct battery_info *bi = battery_get_info();
/* Disable BC1.2 detection on VCC */
/* Enable BC1.2 detection on VCC */
if (ch_raw_read16(BD99955_CMD_VCC_UCD_SET, &reg,
BD99955_EXTENDED_COMMAND))
return;
reg &= ~BD99955_CMD_UCD_SET_USBDETEN;
reg |= BD99955_CMD_UCD_SET_USBDETEN;
reg &= ~BD99955_CMD_UCD_SET_USB_SW_EN;
ch_raw_write16(BD99955_CMD_VCC_UCD_SET, reg,
BD99955_EXTENDED_COMMAND);
/* Disable BC1.2 detection on VBUS */
/* Enable BC1.2 detection on VBUS */
if (ch_raw_read16(BD99955_CMD_VBUS_UCD_SET, &reg,
BD99955_EXTENDED_COMMAND))
return;
reg &= ~BD99955_CMD_UCD_SET_USBDETEN;
reg |= BD99955_CMD_UCD_SET_USBDETEN;
reg &= ~BD99955_CMD_UCD_SET_USB_SW_EN;
ch_raw_write16(BD99955_CMD_VBUS_UCD_SET, reg,
BD99955_EXTENDED_COMMAND);
/* Disable BC1.2 charge enable trigger */
/* Disable charging trigger by BC1.2 on VCC & VBUS. */
if (ch_raw_read16(BD99955_CMD_CHGOP_SET1, &reg,
BD99955_EXTENDED_COMMAND))
return;
reg |= (BD99955_CMD_CHGOP_SET1_VCC_BC_DISEN |
BD99955_CMD_CHGOP_SET1_VBUS_BC_DISEN);
reg |= (BD99955_CMD_CHGOP_SET1_SDP_CHG_TRIG_EN |
BD99955_CMD_CHGOP_SET1_SDP_CHG_TRIG |
BD99955_CMD_CHGOP_SET1_VBUS_BC_DISEN |
BD99955_CMD_CHGOP_SET1_VCC_BC_DISEN |
BD99955_CMD_CHGOP_SET1_ILIM_AUTO_DISEN);
ch_raw_write16(BD99955_CMD_CHGOP_SET1, reg,
BD99955_EXTENDED_COMMAND);
/* Enable BC1.2 USB charging and DC/DC converter */
if (ch_raw_read16(BD99955_CMD_CHGOP_SET2, &reg,
BD99955_EXTENDED_COMMAND))
return;
reg &= ~(BD99955_CMD_CHGOP_SET2_USB_SUS);
ch_raw_write16(BD99955_CMD_CHGOP_SET2, reg,
BD99955_EXTENDED_COMMAND);
/* Set battery OVP to 500 + maximum battery voltage */
ch_raw_write16(BD99955_CMD_VBATOVP_SET,
(bi->voltage_max + 500) & 0x7ff0,
@@ -449,6 +623,78 @@ int bd99955_select_input_port(enum bd99955_charge_port port)
BD99955_EXTENDED_COMMAND);
}
#if defined(HAS_TASK_USB_CHG_P0) || defined(HAS_TASK_USB_CHG_P1)
int bd99955_bc12_enable_charging(enum bd99955_charge_port port, int enable)
{
int rv;
int reg;
int mask_val;
/*
* For BC1.2, enable VBUS/VCC_BC_DISEN charging trigger by BC1.2
* detection and disable SDP_CHG_TRIG, SDP_CHG_TRIG_EN. Vice versa
* for USB-C.
*/
rv = ch_raw_read16(BD99955_CMD_CHGOP_SET1, &reg,
BD99955_EXTENDED_COMMAND);
if (rv)
return rv;
mask_val = (BD99955_CMD_CHGOP_SET1_SDP_CHG_TRIG_EN |
BD99955_CMD_CHGOP_SET1_SDP_CHG_TRIG |
((port == BD99955_CHARGE_PORT_VBUS) ?
BD99955_CMD_CHGOP_SET1_VBUS_BC_DISEN :
BD99955_CMD_CHGOP_SET1_VCC_BC_DISEN));
if (enable)
reg &= ~mask_val;
else
reg |= mask_val;
return ch_raw_write16(BD99955_CMD_CHGOP_SET1, reg,
BD99955_EXTENDED_COMMAND);
}
void usb_charger_set_switches(int port, enum usb_switch setting)
{
/* If switch is not changing then return */
if (setting == usb_switch_state[port] ||
pd_snk_is_vbus_provided(port))
return;
if (setting != USB_SWITCH_RESTORE)
usb_switch_state[port] = setting;
bd99955_enable_usb_switch(port, usb_switch_state[port]);
}
void usb_charger_task(void)
{
int port = (task_get_current() == TASK_ID_USB_CHG_P0 ? 0 : 1);
int bc12_type = CHARGE_SUPPLIER_NONE;
int vbus_provided;
while (1) {
vbus_provided = pd_snk_is_vbus_provided(port);
if (vbus_provided) {
/* Charger/sync attached */
bc12_type = bd99955_bc12_detect(port);
} else if (bc12_type != CHARGE_SUPPLIER_NONE &&
!vbus_provided) {
/* Charger/sync detached */
bd99955_bc12_detach(port, bc12_type);
bc12_type = CHARGE_SUPPLIER_NONE;
}
/* Wait for interrupt */
task_wait_event(-1);
}
}
#endif /* defined(HAS_TASK_USB_CHG_P0) || defined(HAS_TASK_USB_CHG_P1) */
/*** Console commands ***/
#ifdef CONFIG_CMD_CHARGER
static int read_bat(uint8_t cmd)
{

View File

@@ -58,6 +58,7 @@ enum bd99955_charge_port {
#define BD99955_CMD_CHGOP_STATUS_BATTEMP2 (1 << 10)
#define BD99955_CMD_CHGOP_STATUS_BATTEMP1 (1 << 9)
#define BD99955_CMD_CHGOP_STATUS_BATTEMP0 (1 << 8)
#define BD99955_BATTTEMP_MASK 0x700
#define BD99955_CMD_CHGOP_STATUS_BATTEMP_ROOMTEMP 0
#define BD99955_CMD_CHGOP_STATUS_BATTEMP_HOT1 1
#define BD99955_CMD_CHGOP_STATUS_BATTEMP_HOT2 2
@@ -81,11 +82,16 @@ enum bd99955_charge_port {
#define BD99955_CMD_VIN_CTRL_SET_VCC_EN (1 << 5)
#define BD99955_CMD_CHGOP_SET1 0x0B
#define BD99955_CMD_CHGOP_SET1_ILIM_AUTO_DISEN (1 << 13)
#define BD99955_CMD_CHGOP_SET1_VCC_BC_DISEN (1 << 11)
#define BD99955_CMD_CHGOP_SET1_VBUS_BC_DISEN (1 << 10)
#define BD99955_CMD_CHGOP_SET1_SDP_CHG_TRIG_EN (1 << 9)
#define BD99955_CMD_CHGOP_SET1_SDP_CHG_TRIG (1 << 8)
#define BD99955_CMD_CHGOP_SET2 0x0C
#define BD99955_CMD_CHGOP_SET2_BATT_LEARN (1 << 8)
#define BD99955_CMD_CHGOP_SET2_CHG_EN (1 << 7)
#define BD99955_CMD_CHGOP_SET2_USB_SUS (1 << 6)
#define BD99955_CMD_VBUSCLPS_TH_SET 0x0D
#define BD99955_CMD_VCCCLPS_TH_SET 0x0E
@@ -121,10 +127,39 @@ enum bd99955_charge_port {
#define BD99955_CMD_PMON_DACIN_VAL 0x26
#define BD99955_CMD_IOUT_DACIN_VAL 0x27
#define BD99955_CMD_VCC_UCD_SET 0x28
/* Bits for both VCC_UDC_SET and VBUS_UCD_SET regs */
/* Bits for both VCC_UCD_SET and VBUS_UCD_SET regs */
#define BD99955_CMD_UCD_SET_BCSRETRY (1 << 12)
#define BD99955_CMD_UCD_SET_USBDETEN (1 << 7)
#define BD99955_CMD_UCD_SET_USB_SW_EN (1 << 1)
#define BD99955_CMD_VCC_UCD_STATUS 0x29
/* Bits for both VCC_UCD_STATUS and VBUS_UCD_STATUS regs */
#define BD99955_CMD_UCD_STATUS_DCDFAIL (1 << 15)
#define BD99955_CMD_UCD_STATUS_CHGPORT1 (1 << 13)
#define BD99955_CMD_UCD_STATUS_CHGPORT0 (1 << 12)
#define BD99955_CMD_UCD_STATUS_PUPDET (1 << 11)
#define BD99955_CMD_UCD_STATUS_CHGDET (1 << 6)
#define BD99955_TYPE_VBUS_OPEN 0
#define BD99955_TYPE_SDP BD99955_CMD_UCD_STATUS_CHGPORT0
/*
* TODO: For CDP detection, from the datasheet CHGDET & CHGPORT[1] bits need
* to be high and rest need to be low. However following bits are high CHGDET,
* DCDFAIL, CHGPORT[1], CHGPORT[0] and rest low.
*/
#define BD99955_TYPE_CDP (BD99955_CMD_UCD_STATUS_CHGDET | \
BD99955_CMD_UCD_STATUS_CHGPORT1 | \
BD99955_CMD_UCD_STATUS_CHGPORT0 | \
BD99955_CMD_UCD_STATUS_DCDFAIL)
#define BD99955_TYPE_DCP (BD99955_CMD_UCD_STATUS_CHGDET | \
BD99955_CMD_UCD_STATUS_CHGPORT0 | \
BD99955_CMD_UCD_STATUS_CHGPORT1)
#define BD99955_TYPE_PUP_PORT (BD99955_CMD_UCD_STATUS_PUPDET | \
BD99955_CMD_UCD_STATUS_DCDFAIL | \
BD99955_CMD_UCD_STATUS_CHGPORT0)
#define BD99955_TYPE_OPEN_PORT (BD99955_CMD_UCD_STATUS_DCDFAIL | \
BD99955_CMD_UCD_STATUS_CHGPORT0)
#define BD99955_TYPE_MASK 0xB840
#define BD99955_CMD_VCC_IDD_STATUS 0x2A
#define BD99955_CMD_VCC_UCD_FCTRL_SET 0x2B
#define BD99955_CMD_VCC_UCD_FCTRL_EN 0x2C
@@ -138,6 +173,9 @@ enum bd99955_charge_port {
#define BD99955_CMD_IC_SET1 0x3A
#define BD99955_CMD_IC_SET2 0x3B
#define BD99955_CMD_SYSTEM_STATUS 0x3C
#define BD99955_CMD_SYSTEM_STATUS_OTPLD_STATE (1 << 1)
#define BD99955_CMD_SYSTEM_STATUS_ALLRST_STATE (1 << 0)
#define BD99955_CMD_SYSTEM_CTRL_SET 0x3D
#define BD99955_CMD_SYSTEM_CTRL_SET_OTPLD (1 << 1)
#define BD99955_CMD_SYSTEM_CTRL_SET_ALLRST (1 << 0)
@@ -213,5 +251,7 @@ enum bd99955_charge_port {
int bd99955_extpower_is_present(void);
/* Select input port from {VCC, VBUS, VCC&VBUS, NONE}. */
int bd99955_select_input_port(enum bd99955_charge_port port);
/* Enable/Disable charging triggered by BC1.2 */
int bd99955_bc12_enable_charging(enum bd99955_charge_port port, int enable);
#endif /* __CROS_EC_BD99955_H */

View File

@@ -100,6 +100,6 @@ void charge_manager_save_log(int port);
int board_set_active_charge_port(int charge_port);
/* Set the charge current limit. */
void board_set_charge_limit(int charge_ma);
void board_set_charge_limit(int port, int supplier, int charge_ma);
#endif /* __CROS_EC_CHARGE_MANAGER_H */

View File

@@ -524,6 +524,7 @@
#undef CONFIG_CMD_BATDEBUG
#define CONFIG_CMD_BATTFAKE
#define CONFIG_CMD_CHARGER
#define CONFIG_CMD_CHARGE_SUPPLIER_INFO
#undef CONFIG_CMD_CHGRAMP
#undef CONFIG_CMD_CLOCKGATES
#undef CONFIG_CMD_COMXTEST

View File

@@ -37,7 +37,7 @@ static int new_power_request[CONFIG_USB_PD_PORT_COUNT];
static int power_role[CONFIG_USB_PD_PORT_COUNT];
/* Callback functions called by CM on state change */
void board_set_charge_limit(int charge_ma)
void board_set_charge_limit(int port, int supplier, int charge_ma)
{
active_charge_limit = charge_ma;
}

View File

@@ -53,7 +53,7 @@ int board_is_vbus_too_low(enum chg_ramp_vbus_state ramp_state)
vbus_low_current_ma;
}
void board_set_charge_limit(int limit_ma)
void board_set_charge_limit(int port, int supplier, int limit_ma)
{
charge_limit_ma = limit_ma;
if (charge_limit_ma > overcurrent_current_ma)