mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 17:11:42 +00:00
pd: treat externally powered dualrole devices as dedicated chargers
Treat externally powered dualrole devices as dedicated chargers. This allows us to default to consuming power from externally powered dualrole devices and cancels a charger override when one is attached. BUG=chrome-os-partner:38785 BRANCH=samus TEST=tested with third-party dualrole device that can be externally powered. also tested with another samus that was hard-coded with externally powered bit set, and deleted it's policy for power swapping. when this externally-powered samus is plugged into a samus running this CL, we always charge from the externally-powered samus. Change-Id: I850eba668e86d311d9353aa3881fc3a518409630 Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/263331 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
committed by
ChromeOS Commit Bot
parent
077f7c8b47
commit
2d2d1e15cf
@@ -91,11 +91,11 @@ void pd_execute_data_swap(int port, int data_role)
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
void pd_check_pr_role(int port, int pr_role, int partner_pr_swap)
|
||||
void pd_check_pr_role(int port, int pr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
void pd_check_dr_role(int port, int dr_role, int partner_dr_swap)
|
||||
void pd_check_dr_role(int port, int dr_role, int flags)
|
||||
{
|
||||
}
|
||||
/* ----------------- Vendor Defined Messages ------------------ */
|
||||
|
||||
@@ -130,11 +130,11 @@ void pd_execute_data_swap(int port, int data_role)
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
void pd_check_pr_role(int port, int pr_role, int partner_pr_swap)
|
||||
void pd_check_pr_role(int port, int pr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
void pd_check_dr_role(int port, int dr_role, int partner_dr_swap)
|
||||
void pd_check_dr_role(int port, int dr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -117,11 +117,11 @@ void pd_execute_data_swap(int port, int data_role)
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
void pd_check_pr_role(int port, int pr_role, int partner_pr_swap)
|
||||
void pd_check_pr_role(int port, int pr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
void pd_check_dr_role(int port, int dr_role, int partner_dr_swap)
|
||||
void pd_check_dr_role(int port, int dr_role, int flags)
|
||||
{
|
||||
}
|
||||
/* ----------------- Vendor Defined Messages ------------------ */
|
||||
|
||||
@@ -91,11 +91,11 @@ void pd_execute_data_swap(int port, int data_role)
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
void pd_check_pr_role(int port, int pr_role, int partner_pr_swap)
|
||||
void pd_check_pr_role(int port, int pr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
void pd_check_dr_role(int port, int dr_role, int partner_dr_swap)
|
||||
void pd_check_dr_role(int port, int dr_role, int flags)
|
||||
{
|
||||
}
|
||||
/* ----------------- Vendor Defined Messages ------------------ */
|
||||
|
||||
@@ -116,11 +116,11 @@ void pd_execute_data_swap(int port, int data_role)
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
void pd_check_pr_role(int port, int pr_role, int partner_pr_swap)
|
||||
void pd_check_pr_role(int port, int pr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
void pd_check_dr_role(int port, int dr_role, int partner_dr_swap)
|
||||
void pd_check_dr_role(int port, int dr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -101,11 +101,11 @@ void pd_execute_data_swap(int port, int data_role)
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
void pd_check_pr_role(int port, int pr_role, int partner_pr_swap)
|
||||
void pd_check_pr_role(int port, int pr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
void pd_check_dr_role(int port, int dr_role, int partner_dr_swap)
|
||||
void pd_check_dr_role(int port, int dr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -143,14 +143,15 @@ void pd_execute_data_swap(int port, int data_role)
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
void pd_check_pr_role(int port, int pr_role, int partner_pr_swap)
|
||||
void pd_check_pr_role(int port, int pr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
void pd_check_dr_role(int port, int dr_role, int partner_dr_swap)
|
||||
void pd_check_dr_role(int port, int dr_role, int flags)
|
||||
{
|
||||
/* If Plankton is in USB hub mode, always act as UFP */
|
||||
if (board_in_hub_mode() && dr_role == PD_ROLE_DFP && partner_dr_swap)
|
||||
if (board_in_hub_mode() && dr_role == PD_ROLE_DFP &&
|
||||
(flags & PD_FLAGS_PARTNER_DR_DATA))
|
||||
pd_request_data_swap(port);
|
||||
}
|
||||
|
||||
|
||||
@@ -119,11 +119,11 @@ int pd_check_data_swap(int port, int data_role)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void pd_check_pr_role(int port, int pr_role, int partner_pr_swap)
|
||||
void pd_check_pr_role(int port, int pr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
void pd_check_dr_role(int port, int dr_role, int partner_dr_swap)
|
||||
void pd_check_dr_role(int port, int dr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -157,18 +157,30 @@ void pd_execute_data_swap(int port, int data_role)
|
||||
set_usb_switches(port, (data_role == PD_ROLE_UFP));
|
||||
}
|
||||
|
||||
void pd_check_pr_role(int port, int pr_role, int partner_pr_swap)
|
||||
void pd_check_pr_role(int port, int pr_role, int flags)
|
||||
{
|
||||
/* If sink, and dual role toggling is on, then switch to source */
|
||||
if (partner_pr_swap && pr_role == PD_ROLE_SINK &&
|
||||
pd_get_dual_role() == PD_DRP_TOGGLE_ON)
|
||||
pd_request_power_swap(port);
|
||||
/*
|
||||
* If partner is dual-role power and dualrole toggling is on, consider
|
||||
* if a power swap is necessary.
|
||||
*/
|
||||
if ((flags & PD_FLAGS_PARTNER_DR_POWER) &&
|
||||
pd_get_dual_role() == PD_DRP_TOGGLE_ON) {
|
||||
/*
|
||||
* If we are a sink and partner is not externally powered, then
|
||||
* swap to become a source. If we are source and partner is
|
||||
* externally powered, swap to become a sink.
|
||||
*/
|
||||
int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER;
|
||||
if ((!partner_extpower && pr_role == PD_ROLE_SINK) ||
|
||||
(partner_extpower && pr_role == PD_ROLE_SOURCE))
|
||||
pd_request_power_swap(port);
|
||||
}
|
||||
}
|
||||
|
||||
void pd_check_dr_role(int port, int dr_role, int partner_dr_swap)
|
||||
void pd_check_dr_role(int port, int dr_role, int flags)
|
||||
{
|
||||
/* If UFP, try to switch to DFP */
|
||||
if (partner_dr_swap && dr_role == PD_ROLE_UFP)
|
||||
if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP)
|
||||
pd_request_data_swap(port);
|
||||
}
|
||||
/* ----------------- Vendor Defined Messages ------------------ */
|
||||
|
||||
@@ -106,11 +106,11 @@ int pd_check_data_swap(int port, int data_role)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void pd_check_pr_role(int port, int pr_role, int partner_pr_swap)
|
||||
void pd_check_pr_role(int port, int pr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
void pd_check_dr_role(int port, int dr_role, int partner_dr_swap)
|
||||
void pd_check_dr_role(int port, int dr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -299,14 +299,14 @@ void pd_execute_data_swap(int port, int data_role)
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
void pd_check_pr_role(int port, int pr_role, int partner_pr_swap)
|
||||
void pd_check_pr_role(int port, int pr_role, int flags)
|
||||
{
|
||||
}
|
||||
|
||||
void pd_check_dr_role(int port, int dr_role, int partner_dr_swap)
|
||||
void pd_check_dr_role(int port, int dr_role, int flags)
|
||||
{
|
||||
/* If DFP, try to switch to UFP */
|
||||
if (partner_dr_swap && dr_role == PD_ROLE_DFP)
|
||||
if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_DFP)
|
||||
pd_request_data_swap(port);
|
||||
}
|
||||
|
||||
|
||||
@@ -217,28 +217,6 @@ static uint32_t pd_src_caps[PD_PORT_COUNT][PDO_MAX_OBJECTS];
|
||||
static int pd_src_cap_cnt[PD_PORT_COUNT];
|
||||
#endif
|
||||
|
||||
#define PD_FLAGS_PING_ENABLED (1 << 0) /* SRC_READY pings enabled */
|
||||
#define PD_FLAGS_PARTNER_DR_POWER (1 << 1) /* port partner is dualrole power */
|
||||
#define PD_FLAGS_PARTNER_DR_DATA (1 << 2) /* port partner is dualrole data */
|
||||
#define PD_FLAGS_DATA_SWAPPED (1 << 3) /* data swap complete */
|
||||
#define PD_FLAGS_SNK_CAP_RECVD (1 << 4) /* sink capabilities received */
|
||||
#define PD_FLAGS_GET_SNK_CAP_SENT (1 << 5) /* get sink cap sent */
|
||||
#define PD_FLAGS_EXPLICIT_CONTRACT (1 << 6) /* explicit pwr contract in place */
|
||||
#define PD_FLAGS_SFT_RST_DIS_COMM (1 << 7) /* disable comms after soft reset */
|
||||
#define PD_FLAGS_PREVIOUS_PD_CONN (1 << 8) /* previously PD connected */
|
||||
#define PD_FLAGS_CHECK_PR_ROLE (1 << 9) /* check power role in READY */
|
||||
#define PD_FLAGS_CHECK_DR_ROLE (1 << 10)/* check data role in READY */
|
||||
/* Flags to clear on a disconnect */
|
||||
#define PD_FLAGS_RESET_ON_DISCONNECT_MASK (PD_FLAGS_PARTNER_DR_POWER | \
|
||||
PD_FLAGS_PARTNER_DR_DATA | \
|
||||
PD_FLAGS_DATA_SWAPPED | \
|
||||
PD_FLAGS_SNK_CAP_RECVD | \
|
||||
PD_FLAGS_GET_SNK_CAP_SENT | \
|
||||
PD_FLAGS_EXPLICIT_CONTRACT | \
|
||||
PD_FLAGS_PREVIOUS_PD_CONN | \
|
||||
PD_FLAGS_CHECK_PR_ROLE | \
|
||||
PD_FLAGS_CHECK_DR_ROLE)
|
||||
|
||||
static struct pd_protocol {
|
||||
/* current port power role (SOURCE or SINK) */
|
||||
uint8_t power_role;
|
||||
@@ -967,24 +945,39 @@ static void pd_send_request_msg(int port, int always_send_request)
|
||||
static void pd_update_pdo_flags(int port, uint32_t pdo)
|
||||
{
|
||||
/* can only parse PDO flags if type is fixed */
|
||||
if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_FIXED) {
|
||||
if (pdo & PDO_FIXED_DUAL_ROLE) {
|
||||
pd[port].flags |= PD_FLAGS_PARTNER_DR_POWER;
|
||||
#ifdef CONFIG_CHARGE_MANAGER
|
||||
charge_manager_update_dualrole(port, CAP_DUALROLE);
|
||||
#endif
|
||||
} else {
|
||||
pd[port].flags &= ~PD_FLAGS_PARTNER_DR_POWER;
|
||||
#ifdef CONFIG_CHARGE_MANAGER
|
||||
charge_manager_update_dualrole(port, CAP_DEDICATED);
|
||||
#endif
|
||||
}
|
||||
if ((pdo & PDO_TYPE_MASK) != PDO_TYPE_FIXED)
|
||||
return;
|
||||
|
||||
if (pdo & PDO_FIXED_DATA_SWAP)
|
||||
pd[port].flags |= PD_FLAGS_PARTNER_DR_DATA;
|
||||
else
|
||||
pd[port].flags &= ~PD_FLAGS_PARTNER_DR_DATA;
|
||||
#ifdef CONFIG_USB_PD_DUAL_ROLE
|
||||
if (pdo & PDO_FIXED_DUAL_ROLE)
|
||||
pd[port].flags |= PD_FLAGS_PARTNER_DR_POWER;
|
||||
else
|
||||
pd[port].flags &= ~PD_FLAGS_PARTNER_DR_POWER;
|
||||
|
||||
if (pdo & PDO_FIXED_EXTERNAL)
|
||||
pd[port].flags |= PD_FLAGS_PARTNER_EXTPOWER;
|
||||
else
|
||||
pd[port].flags &= ~PD_FLAGS_PARTNER_EXTPOWER;
|
||||
#endif
|
||||
|
||||
if (pdo & PDO_FIXED_DATA_SWAP)
|
||||
pd[port].flags |= PD_FLAGS_PARTNER_DR_DATA;
|
||||
else
|
||||
pd[port].flags &= ~PD_FLAGS_PARTNER_DR_DATA;
|
||||
|
||||
#ifdef CONFIG_CHARGE_MANAGER
|
||||
/*
|
||||
* If partner supports power swap and is NOT externally powered, then
|
||||
* treat this as a dualrole device. Otherwise, treat this as a
|
||||
* dedicated charger.
|
||||
*/
|
||||
if ((pd[port].flags & PD_FLAGS_PARTNER_DR_POWER) &&
|
||||
!(pd[port].flags & PD_FLAGS_PARTNER_EXTPOWER)) {
|
||||
charge_manager_update_dualrole(port, CAP_DUALROLE);
|
||||
} else {
|
||||
charge_manager_update_dualrole(port, CAP_DEDICATED);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void handle_data_request(int port, uint16_t head,
|
||||
@@ -2129,8 +2122,7 @@ void pd_task(void)
|
||||
/* Check power role policy, which may trigger a swap */
|
||||
if (pd[port].flags & PD_FLAGS_CHECK_PR_ROLE) {
|
||||
pd_check_pr_role(port, PD_ROLE_SOURCE,
|
||||
pd[port].flags &
|
||||
PD_FLAGS_PARTNER_DR_POWER);
|
||||
pd[port].flags);
|
||||
pd[port].flags &= ~PD_FLAGS_CHECK_PR_ROLE;
|
||||
break;
|
||||
}
|
||||
@@ -2138,8 +2130,7 @@ void pd_task(void)
|
||||
/* Check data role policy, which may trigger a swap */
|
||||
if (pd[port].flags & PD_FLAGS_CHECK_DR_ROLE) {
|
||||
pd_check_dr_role(port, pd[port].data_role,
|
||||
pd[port].flags &
|
||||
PD_FLAGS_PARTNER_DR_DATA);
|
||||
pd[port].flags);
|
||||
pd[port].flags &= ~PD_FLAGS_CHECK_DR_ROLE;
|
||||
break;
|
||||
}
|
||||
@@ -2496,8 +2487,7 @@ void pd_task(void)
|
||||
/* Check power role policy, which may trigger a swap */
|
||||
if (pd[port].flags & PD_FLAGS_CHECK_PR_ROLE) {
|
||||
pd_check_pr_role(port, PD_ROLE_SINK,
|
||||
pd[port].flags &
|
||||
PD_FLAGS_PARTNER_DR_POWER);
|
||||
pd[port].flags);
|
||||
pd[port].flags &= ~PD_FLAGS_CHECK_PR_ROLE;
|
||||
break;
|
||||
}
|
||||
@@ -2505,8 +2495,7 @@ void pd_task(void)
|
||||
/* Check data role policy, which may trigger a swap */
|
||||
if (pd[port].flags & PD_FLAGS_CHECK_DR_ROLE) {
|
||||
pd_check_dr_role(port, pd[port].data_role,
|
||||
pd[port].flags &
|
||||
PD_FLAGS_PARTNER_DR_DATA);
|
||||
pd[port].flags);
|
||||
pd[port].flags &= ~PD_FLAGS_CHECK_DR_ROLE;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -630,6 +630,31 @@ enum pd_states {
|
||||
PD_STATE_COUNT,
|
||||
};
|
||||
|
||||
#define PD_FLAGS_PING_ENABLED (1 << 0) /* SRC_READY pings enabled */
|
||||
#define PD_FLAGS_PARTNER_DR_POWER (1 << 1) /* port partner is dualrole power */
|
||||
#define PD_FLAGS_PARTNER_DR_DATA (1 << 2) /* port partner is dualrole data */
|
||||
#define PD_FLAGS_DATA_SWAPPED (1 << 3) /* data swap complete */
|
||||
#define PD_FLAGS_SNK_CAP_RECVD (1 << 4) /* sink capabilities received */
|
||||
#define PD_FLAGS_GET_SNK_CAP_SENT (1 << 5) /* get sink cap sent */
|
||||
#define PD_FLAGS_EXPLICIT_CONTRACT (1 << 6) /* explicit pwr contract in place */
|
||||
#define PD_FLAGS_SFT_RST_DIS_COMM (1 << 7) /* disable comms after soft reset */
|
||||
#define PD_FLAGS_PREVIOUS_PD_CONN (1 << 8) /* previously PD connected */
|
||||
#define PD_FLAGS_CHECK_PR_ROLE (1 << 9) /* check power role in READY */
|
||||
#define PD_FLAGS_CHECK_DR_ROLE (1 << 10)/* check data role in READY */
|
||||
#define PD_FLAGS_PARTNER_EXTPOWER (1 << 11)/* port partner has external pwr */
|
||||
/* Flags to clear on a disconnect */
|
||||
#define PD_FLAGS_RESET_ON_DISCONNECT_MASK (PD_FLAGS_PARTNER_DR_POWER | \
|
||||
PD_FLAGS_PARTNER_DR_DATA | \
|
||||
PD_FLAGS_DATA_SWAPPED | \
|
||||
PD_FLAGS_SNK_CAP_RECVD | \
|
||||
PD_FLAGS_GET_SNK_CAP_SENT | \
|
||||
PD_FLAGS_EXPLICIT_CONTRACT | \
|
||||
PD_FLAGS_PREVIOUS_PD_CONN | \
|
||||
PD_FLAGS_CHECK_PR_ROLE | \
|
||||
PD_FLAGS_CHECK_DR_ROLE | \
|
||||
PD_FLAGS_PARTNER_EXTPOWER)
|
||||
|
||||
|
||||
enum pd_cc_states {
|
||||
PD_CC_NONE,
|
||||
|
||||
@@ -883,18 +908,18 @@ int pd_check_data_swap(int port, int data_role);
|
||||
*
|
||||
* @param port USB-C port number
|
||||
* @param pr_role Our power role
|
||||
* @param partner_pr_swap Partner supports PR_SWAP
|
||||
* @param flags PD flags
|
||||
*/
|
||||
void pd_check_pr_role(int port, int pr_role, int partner_pr_swap);
|
||||
void pd_check_pr_role(int port, int pr_role, int flags);
|
||||
|
||||
/**
|
||||
* Check current data role for potential data swap
|
||||
*
|
||||
* @param port USB-C port number
|
||||
* @param dr_role Our data role
|
||||
* @param partner_dr_swap Partner supports DR_SWAP
|
||||
* @param flags PD flags
|
||||
*/
|
||||
void pd_check_dr_role(int port, int dr_role, int partner_dr_swap);
|
||||
void pd_check_dr_role(int port, int dr_role, int flags);
|
||||
|
||||
/**
|
||||
* Execute data swap.
|
||||
|
||||
Reference in New Issue
Block a user