Files
OpenCellular/board/host/usb_pd_policy.c
Alec Berg e39f43ed2d samus: pd: on PD connection, if sink, ask for power swap
For samus, on PD connection or on resume to S0, if we are a sink,
and the other side supports PR_SWAP, then attempt a power swap.

This adds callback functions into board policy file to check
and issue power or data swaps if required by the product.

BUG=chrome-os-partner:31195
BRANCH=samus
TEST=connect samus to zinger and make sure zinger always ends up
as SRC-UFP.

connect samus to samus with both in S0 and see that
they swap power roles once and not data roles.

connect one samus in S0 to one samus in S5 and see that the one
in S5 is sink. then when you boot the one in S5 it switches to a
source.

connect samus to samus with both in S0. do chgoverride 1 on one
side to start charging from the other samus. then on the same
side, turn off the machine (S5) and resume (S0), and see that it
is still charging from the other samus (ie has not switched roles
to source).

Change-Id: Ifab2465fccef77448ac4771a3c2de1c867cbbec4
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/238302
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
2015-01-07 02:32:38 +00:00

110 lines
2.2 KiB
C

/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "common.h"
#include "console.h"
#include "usb_pd.h"
#include "util.h"
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP)
const uint32_t pd_src_pdo[] = {
PDO_FIXED(5000, 900, PDO_FIXED_FLAGS),
};
const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
const uint32_t pd_snk_pdo[] = {
PDO_FIXED(5000, 500, PDO_FIXED_FLAGS),
PDO_BATT(5000, 20000, 15000),
PDO_VAR(5000, 20000, 3000),
};
const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
int pd_check_requested_voltage(uint32_t rdo)
{
int max_ma = rdo & 0x3FF;
int op_ma = (rdo >> 10) & 0x3FF;
int idx = rdo >> 28;
uint32_t pdo;
uint32_t pdo_ma;
if (!idx || idx > pd_src_pdo_cnt)
return EC_ERROR_INVAL; /* Invalid index */
/* check current ... */
pdo = pd_src_pdo[idx - 1];
pdo_ma = (pdo & 0x3ff);
if (op_ma > pdo_ma)
return EC_ERROR_INVAL; /* too much op current */
if (max_ma > pdo_ma)
return EC_ERROR_INVAL; /* too much max current */
CPRINTF("Requested %d V %d mA (for %d/%d mA)\n",
((pdo >> 10) & 0x3ff) * 50, (pdo & 0x3ff) * 10,
((rdo >> 10) & 0x3ff) * 10, (rdo & 0x3ff) * 10);
return EC_SUCCESS;
}
void pd_transition_voltage(int idx)
{
/* Not implemented */
}
int pd_set_power_supply_ready(int port)
{
/* Not implemented */
return EC_SUCCESS;
}
void pd_power_supply_reset(int port)
{
/* Not implemented */
}
void pd_set_input_current_limit(int port, uint32_t max_ma,
uint32_t supply_voltage)
{
/* Not implemented */
}
int pd_board_checks(void)
{
return EC_SUCCESS;
}
int pd_check_power_swap(int port)
{
/* Always allow power swap */
return 1;
}
int pd_check_data_swap(int port, int data_role)
{
/* Always allow data swap */
return 1;
}
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_dr_role(int port, int dr_role, int partner_dr_swap)
{
}
int pd_custom_vdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
{
return 0;
}