mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-29 01:50:53 +00:00
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:
committed by
chrome-bot
parent
f4e617e118
commit
313355302b
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
/*
|
||||
|
||||
@@ -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, ®,
|
||||
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,
|
||||
®, 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, ®, 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, ®,
|
||||
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, ®,
|
||||
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, ®,
|
||||
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, ®,
|
||||
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, ®,
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user