summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2017-08-10 13:12:30 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-08-11 20:10:20 -0700
commit79ae73477c1d6a84ce9c64eb82a183a163aa3646 (patch)
tree6afeec8aa404c0750d079a326712fc3ab39fd4aa
parent97fe22e8d559449cbd9df5cc2065f5ab5941830e (diff)
downloadchrome-ec-79ae73477c1d6a84ce9c64eb82a183a163aa3646.tar.gz
charge_manager: Consider port in source PDO.
When CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT is defined for a board, as its name implies, the board can source a higher current if there is only one port acting as a source. This commit fixes an issue with selecting the right source capability message to advertise. charge_manager_get_source_pdo() was simply checking if there was more than one sink connected, instead of checking if there were any *other* sinks connected. In the event that a sink was connected to a different port, we would advertise the max source PDO. BUG=b:64037926, b:35577509 BRANCH=gru,eve,reef TEST=Connect sink to port 1. Connect a AMA to port 0 that claims that VBUS isn't necessary. Start sending source caps, verify that the max PDO is not being advertised in the source caps. Change-Id: Ie4145ecaf98d5b9070ad3e8b139e5653685fa801 Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/610479 Commit-Ready: Aseda Aboagye <aaboagye@chromium.org> Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Shawn N <shawnn@chromium.org>
-rw-r--r--board/plankton/usb_pd_policy.c2
-rw-r--r--board/servo_v4/usb_pd_policy.c2
-rw-r--r--common/charge_manager.c24
-rw-r--r--common/usb_pd_policy.c4
-rw-r--r--common/usb_pd_protocol.c4
-rw-r--r--include/charge_manager.h5
-rw-r--r--include/usb_pd.h3
-rw-r--r--util/genvif.c2
8 files changed, 24 insertions, 22 deletions
diff --git a/board/plankton/usb_pd_policy.c b/board/plankton/usb_pd_policy.c
index 6db20d33cb..42dd5180f8 100644
--- a/board/plankton/usb_pd_policy.c
+++ b/board/plankton/usb_pd_policy.c
@@ -55,7 +55,7 @@ void board_set_source_cap(enum board_src_cap cap)
pd_src_pdo_idx = cap;
}
-int charge_manager_get_source_pdo(const uint32_t **src_pdo)
+int charge_manager_get_source_pdo(const uint32_t **src_pdo, const int port)
{
*src_pdo = pd_src_pdo;
return pd_src_pdo_cnts[pd_src_pdo_idx];
diff --git a/board/servo_v4/usb_pd_policy.c b/board/servo_v4/usb_pd_policy.c
index 019b35f763..011994a2c9 100644
--- a/board/servo_v4/usb_pd_policy.c
+++ b/board/servo_v4/usb_pd_policy.c
@@ -352,7 +352,7 @@ int board_select_rp_value(int port, int rp)
return pd_set_rp_rd(port, TYPEC_CC_RP, rp);
}
-int charge_manager_get_source_pdo(const uint32_t **src_pdo)
+int charge_manager_get_source_pdo(const uint32_t **src_pdo, const int port)
{
int pdo_cnt;
/*
diff --git a/common/charge_manager.c b/common/charge_manager.c
index 7b119da347..9d9226cb19 100644
--- a/common/charge_manager.c
+++ b/common/charge_manager.c
@@ -963,20 +963,20 @@ void charge_manager_source_port(int port, int enable)
}
}
-int charge_manager_get_source_pdo(const uint32_t **src_pdo)
+int charge_manager_get_source_pdo(const uint32_t **src_pdo, const int port)
{
- int p;
- int count = 0;
-
- /* count the number of connected sinks */
- for (p = 0; p < CONFIG_USB_PD_PORT_COUNT; p++)
- if (source_port_bitmap & (1 << p))
- count++;
-
- /* send the maximum current if we are sourcing only on one port */
- *src_pdo = count <= 1 ? pd_src_pdo_max : pd_src_pdo;
+ /* Are there any other connected sinks? */
+ if (source_port_bitmap & ~(1 << port)) {
+ *src_pdo = pd_src_pdo;
+ return pd_src_pdo_cnt;
+ }
- return count <= 1 ? pd_src_pdo_cnt : pd_src_pdo_max_cnt;
+ /*
+ * If not, send the maximum current since we're sourcing on only one
+ * port.
+ */
+ *src_pdo = pd_src_pdo_max;
+ return pd_src_pdo_max_cnt;
}
#endif /* CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT */
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c
index 62f9ecbfa5..cf58e7ff07 100644
--- a/common/usb_pd_policy.c
+++ b/common/usb_pd_policy.c
@@ -33,7 +33,7 @@
static int rw_flash_changed = 1;
-int pd_check_requested_voltage(uint32_t rdo)
+int pd_check_requested_voltage(uint32_t rdo, const int port)
{
int max_ma = rdo & 0x3FF;
int op_ma = (rdo >> 10) & 0x3FF;
@@ -43,7 +43,7 @@ int pd_check_requested_voltage(uint32_t rdo)
#if defined(CONFIG_USB_PD_DYNAMIC_SRC_CAP) || \
defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT)
const uint32_t *src_pdo;
- const int pdo_cnt = charge_manager_get_source_pdo(&src_pdo);
+ const int pdo_cnt = charge_manager_get_source_pdo(&src_pdo, port);
#else
const uint32_t *src_pdo = pd_src_pdo;
const int pdo_cnt = pd_src_pdo_cnt;
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 2f701e6bfc..0526aaaf65 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -441,7 +441,7 @@ static int send_source_cap(int port)
#if defined(CONFIG_USB_PD_DYNAMIC_SRC_CAP) || \
defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT)
const uint32_t *src_pdo;
- const int src_pdo_cnt = charge_manager_get_source_pdo(&src_pdo);
+ const int src_pdo_cnt = charge_manager_get_source_pdo(&src_pdo, port);
#else
const uint32_t *src_pdo = pd_src_pdo;
const int src_pdo_cnt = pd_src_pdo_cnt;
@@ -801,7 +801,7 @@ static void handle_data_request(int port, uint16_t head,
#endif /* CONFIG_USB_PD_DUAL_ROLE */
case PD_DATA_REQUEST:
if ((pd[port].power_role == PD_ROLE_SOURCE) && (cnt == 1))
- if (!pd_check_requested_voltage(payload[0])) {
+ if (!pd_check_requested_voltage(payload[0], port)) {
if (send_control(port, PD_CTRL_ACCEPT) < 0)
/*
* if we fail to send accept, do
diff --git a/include/charge_manager.h b/include/charge_manager.h
index 2137899a13..037723047c 100644
--- a/include/charge_manager.h
+++ b/include/charge_manager.h
@@ -161,10 +161,11 @@ void charge_manager_source_port(int port, int enable);
/**
* Get PD source power data objects.
*
- * @param src_pdo pointer to the data to return.
+ * @param src_pdo Pointer to the data to return.
+ * @param port Current port to evaluate against.
* @return number of PDOs returned.
*/
-int charge_manager_get_source_pdo(const uint32_t **src_pdo);
+int charge_manager_get_source_pdo(const uint32_t **src_pdo, const int port);
/* Board-level callback functions */
diff --git a/include/usb_pd.h b/include/usb_pd.h
index cefe8abe06..9deed54b88 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -942,9 +942,10 @@ int pd_is_valid_input_voltage(int mv);
* Request a new operating voltage.
*
* @param rdo Request Data Object with the selected operating point.
+ * @param port The port which the request came in on.
* @return EC_SUCCESS if we can get the requested voltage/OP, <0 else.
*/
-int pd_check_requested_voltage(uint32_t rdo);
+int pd_check_requested_voltage(uint32_t rdo, const int port);
/**
* Run board specific checks on request message
diff --git a/util/genvif.c b/util/genvif.c
index 6b3d685b37..865ae550df 100644
--- a/util/genvif.c
+++ b/util/genvif.c
@@ -48,7 +48,7 @@ enum system_image_copy_t system_get_image_copy(void)
static void init_src_pdos(void)
{
#ifdef CONFIG_USB_PD_DYNAMIC_SRC_CAP
- src_pdo_cnt = charge_manager_get_source_pdo(&src_pdo);
+ src_pdo_cnt = charge_manager_get_source_pdo(&src_pdo, 0);
#else
src_pdo_cnt = pd_src_pdo_cnt;
src_pdo = pd_src_pdo;