Files
OpenCellular/common/usbc_ppc.c
Jett Rink f4602ec472 usbc: Moving PPC init after setting TCPC resistors.
We don't want the PPC to connect the CC lines from the
TCPC to the USB connector until the TCPC resistors are
set in a valid state (SINK initially).

If we connect the CC lines (happens in the ppc_init) before
setting the resistor values, some TCPC will be toggling the
CC line between Rp/Rd since it doesn't detect a cable yet.

In the dead battery charging case, connecting the toggling
CC lines to the charger can rail the CC lines to 3.3 V signaling
to the charger to disconnect Vbus, thus browning out the board.

BRANCH=none
BUG=b:71865251
TEST=Grunt powers on via usbc p0 with and without USB hub.

Change-Id: I8e78aa2af42075398fab89a2dccef5e7df27b260
Signed-off-by: Jett Rink <jettrink@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/882305
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Edward Hill <ecgh@chromium.org>
2018-01-25 19:23:47 -08:00

97 lines
2.1 KiB
C

/* Copyright 2017 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.
*/
/* USB-C Power Path Controller Common Code */
#include "common.h"
#include "console.h"
#include "hooks.h"
#include "usbc_ppc.h"
#include "util.h"
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
/* Simple wrappers to dispatch to the drivers. */
int ppc_init(int port)
{
int rv;
if (port >= ppc_cnt)
return EC_ERROR_INVAL;
rv = ppc_chips[port].drv->init(port);
if (rv)
CPRINTS("p%d: PPC init failed! (%d)", port, rv);
else
CPRINTS("p%d: PPC init'd.", port);
return rv;
}
int ppc_is_sourcing_vbus(int port)
{
if ((port < 0) || (port >= ppc_cnt)) {
CPRINTS("%s(%d) Invalid port!", __func__, port);
return 0;
}
return ppc_chips[port].drv->is_sourcing_vbus(port);
}
int ppc_set_vbus_source_current_limit(int port, enum tcpc_rp_value rp)
{
if ((port < 0) || (port >= ppc_cnt))
return EC_ERROR_INVAL;
return ppc_chips[port].drv->set_vbus_source_current_limit(port, rp);
}
int ppc_vbus_sink_enable(int port, int enable)
{
if ((port < 0) || (port >= ppc_cnt))
return EC_ERROR_INVAL;
return ppc_chips[port].drv->vbus_sink_enable(port, enable);
}
int ppc_vbus_source_enable(int port, int enable)
{
if ((port < 0) || (port >= ppc_cnt))
return EC_ERROR_INVAL;
return ppc_chips[port].drv->vbus_source_enable(port, enable);
}
#ifdef CONFIG_USB_PD_VBUS_DETECT_PPC
int ppc_is_vbus_present(int port, int *vbus_present)
{
if (port >= ppc_cnt)
return EC_ERROR_INVAL;
return ppc_chips[port].drv->is_vbus_present(port, vbus_present);
}
#endif /* defined(CONFIG_USB_PD_VBUS_DETECT_PPC) */
#ifdef CONFIG_CMD_PPC_DUMP
static int command_ppc_dump(int argc, char **argv)
{
int port;
if (argc < 2)
return EC_ERROR_PARAM_COUNT;
port = atoi(argv[1]);
if (port >= ppc_cnt)
return EC_ERROR_PARAM1;
return ppc_chips[port].drv->reg_dump(port);
}
DECLARE_CONSOLE_COMMAND(ppc_dump, command_ppc_dump, "<Type-C port>",
"dump the PPC regs");
#endif /* defined(CONFIG_CMD_PPC_DUMP) */