<commit_before>/* Copyright 2015 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.
 */

/* Type-C port manager */

#include "anx74xx.h"
#include "ec_commands.h"
#include "ps8xxx.h"
#include "task.h"
#include "tcpci.h"
#include "tcpm.h"
#include "timer.h"
#include "usb_charge.h"
#include "usb_mux.h"
#include "usb_pd.h"
#include "usb_pd_tcpc.h"
#include "util.h"

static int tcpc_vbus[CONFIG_USB_PD_PORT_COUNT];

/* Save the selected rp value */
static int selected_rp[CONFIG_USB_PD_PORT_COUNT];

static int init_alert_mask(int port)
{
	uint16_t mask;

	/*
	 * Create mask of alert events that will cause the TCPC to
	 * signal the TCPM via the Alert# gpio line.
	 */
	mask = TCPC_REG_ALERT_TX_SUCCESS | TCPC_REG_ALERT_TX_FAILED |
		TCPC_REG_ALERT_TX_DISCARDED | TCPC_REG_ALERT_RX_STATUS |
		TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS
#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC
		| TCPC_REG_ALERT_POWER_STATUS
#endif
		;
	/* Set the alert mask in TCPC */
	return tcpc_write16(port, TCPC_REG_ALERT_MASK, mask);
}

static int clear_alert_mask(int port)
{
	return tcpc_write16(port, TCPC_REG_ALERT_MASK, 0);
}

static int init_power_status_mask(int port)
{
	uint8_t mask;
	int rv;

#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC
	mask = TCPC_REG_POWER_STATUS_VBUS_PRES;
#else
	mask = 0;
#endif
	rv = tcpc_write(port, TCPC_REG_POWER_STATUS_MASK , mask);

	return rv;
}

static int clear_power_status_mask(int port)
{
	return tcpc_write(port, TCPC_REG_POWER_STATUS_MASK, 0);
}

int tcpci_tcpm_get_cc(int port, int *cc1, int *cc2)
{
	int status;
	int rv;

	rv = tcpc_read(port, TCPC_REG_CC_STATUS, &status);

	/* If tcpc read fails, return error and CC as open */
	if (rv) {
		*cc1 = TYPEC_CC_VOLT_OPEN;
		*cc2 = TYPEC_CC_VOLT_OPEN;
		return rv;
	}

	*cc1 = TCPC_REG_CC_STATUS_CC1(status);
	*cc2 = TCPC_REG_CC_STATUS_CC2(status);

	/*
	 * If status is not open, then OR in termination to convert to
	 * enum tcpc_cc_voltage_status.
	 */
	if (*cc1 != TYPEC_CC_VOLT_OPEN)
		*cc1 |= TCPC_REG_CC_STATUS_TERM(status) << 2;
	if (*cc2 != TYPEC_CC_VOLT_OPEN)
		*cc2 |= TCPC_REG_CC_STATUS_TERM(status) << 2;

	return rv;
}

static int tcpci_tcpm_get_power_status(int port, int *status)
{
	return tcpc_read(port, TCPC_REG_POWER_STATUS, status);
}

int tcpci_tcpm_select_rp_value(int port, int rp)
{
	selected_rp[port] = rp;
	return EC_SUCCESS;
}

#ifdef CONFIG_USB_PD_DISCHARGE_TCPC
void tcpci_tcpc_discharge_vbus(int port, int enable)
{
	int reg;

	if (tcpc_read(port, TCPC_REG_POWER_CTRL, &reg))
		return;

	if (enable)
		reg |= TCPC_REG_POWER_CTRL_FORCE_DISCHARGE;
	else
		reg &= ~TCPC_REG_POWER_CTRL_FORCE_DISCHARGE;

	tcpc_write(port, TCPC_REG_POWER_CTRL, reg);
}
#endif

static int set_role_ctrl(int port, int toggle, int rp, int pull)
{
	return tcpc_write(port, TCPC_REG_ROLE_CTRL,
			  TCPC_REG_ROLE_CTRL_SET(toggle, rp, pull, pull));
}

int tcpci_tcpm_set_cc(int port, int pull)
{
	/* Set manual control, and set both CC lines to the same pull */
	return set_role_ctrl(port, 0, selected_rp[port], pull);
}

#ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE
int tcpci_tcpc_drp_toggle(int port, int enable)
{
	int rv;

	if (!enable) {
#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
		struct usb_mux *mux = &usb_muxes[port];
		if (mux->board_init)
			return mux->board_init(mux);
#endif
		return EC_SUCCESS;
	}
	/* Set auto drp toggle */
	rv = set_role_ctrl(port, 1, TYPEC_RP_USB, TYPEC_CC_OPEN);

	/* Set Look4Connection command */
	rv |= tcpc_write(port, TCPC_REG_COMMAND,
			 TCPC_REG_COMMAND_LOOK4CONNECTION);

#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
	rv |= tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_I2CIDLE);
#endif
	return rv;
}
#endif

int tcpci_tcpm_set_polarity(int port, int polarity)
{
	return tcpc_write(port, TCPC_REG_TCPC_CTRL,
			  TCPC_REG_TCPC_CTRL_SET(polarity));
}

#ifdef CONFIG_USBC_PPC
int tcpci_tcpm_set_snk_ctrl(int port, int enable)
{
	int cmd = enable ? TCPC_REG_COMMAND_SNK_CTRL_HIGH :
		TCPC_REG_COMMAND_SNK_CTRL_LOW;

	return tcpc_write(port, TCPC_REG_COMMAND, cmd);
}

int tcpci_tcpm_set_src_ctrl(int port, int enable)<commit_msg>tcpci: Change role control setting for auto-toggle enable<commit_after>/* Copyright 2015 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.
 */

/* Type-C port manager */

#include "anx74xx.h"
#include "ec_commands.h"
#include "ps8xxx.h"
#include "task.h"
#include "tcpci.h"
#include "tcpm.h"
#include "timer.h"
#include "usb_charge.h"
#include "usb_mux.h"
#include "usb_pd.h"
#include "usb_pd_tcpc.h"
#include "util.h"

static int tcpc_vbus[CONFIG_USB_PD_PORT_COUNT];

/* Save the selected rp value */
static int selected_rp[CONFIG_USB_PD_PORT_COUNT];

static int init_alert_mask(int port)
{
	uint16_t mask;

	/*
	 * Create mask of alert events that will cause the TCPC to
	 * signal the TCPM via the Alert# gpio line.
	 */
	mask = TCPC_REG_ALERT_TX_SUCCESS | TCPC_REG_ALERT_TX_FAILED |
		TCPC_REG_ALERT_TX_DISCARDED | TCPC_REG_ALERT_RX_STATUS |
		TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS
#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC
		| TCPC_REG_ALERT_POWER_STATUS
#endif
		;
	/* Set the alert mask in TCPC */
	return tcpc_write16(port, TCPC_REG_ALERT_MASK, mask);
}

static int clear_alert_mask(int port)
{
	return tcpc_write16(port, TCPC_REG_ALERT_MASK, 0);
}

static int init_power_status_mask(int port)
{
	uint8_t mask;
	int rv;

#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC
	mask = TCPC_REG_POWER_STATUS_VBUS_PRES;
#else
	mask = 0;
#endif
	rv = tcpc_write(port, TCPC_REG_POWER_STATUS_MASK , mask);

	return rv;
}

static int clear_power_status_mask(int port)
{
	return tcpc_write(port, TCPC_REG_POWER_STATUS_MASK, 0);
}

int tcpci_tcpm_get_cc(int port, int *cc1, int *cc2)
{
	int status;
	int rv;

	rv = tcpc_read(port, TCPC_REG_CC_STATUS, &status);

	/* If tcpc read fails, return error and CC as open */
	if (rv) {
		*cc1 = TYPEC_CC_VOLT_OPEN;
		*cc2 = TYPEC_CC_VOLT_OPEN;
		return rv;
	}

	*cc1 = TCPC_REG_CC_STATUS_CC1(status);
	*cc2 = TCPC_REG_CC_STATUS_CC2(status);

	/*
	 * If status is not open, then OR in termination to convert to
	 * enum tcpc_cc_voltage_status.
	 */
	if (*cc1 != TYPEC_CC_VOLT_OPEN)
		*cc1 |= TCPC_REG_CC_STATUS_TERM(status) << 2;
	if (*cc2 != TYPEC_CC_VOLT_OPEN)
		*cc2 |= TCPC_REG_CC_STATUS_TERM(status) << 2;

	return rv;
}

static int tcpci_tcpm_get_power_status(int port, int *status)
{
	return tcpc_read(port, TCPC_REG_POWER_STATUS, status);
}

int tcpci_tcpm_select_rp_value(int port, int rp)
{
	selected_rp[port] = rp;
	return EC_SUCCESS;
}

#ifdef CONFIG_USB_PD_DISCHARGE_TCPC
void tcpci_tcpc_discharge_vbus(int port, int enable)
{
	int reg;

	if (tcpc_read(port, TCPC_REG_POWER_CTRL, &reg))
		return;

	if (enable)
		reg |= TCPC_REG_POWER_CTRL_FORCE_DISCHARGE;
	else
		reg &= ~TCPC_REG_POWER_CTRL_FORCE_DISCHARGE;

	tcpc_write(port, TCPC_REG_POWER_CTRL, reg);
}
#endif

static int set_role_ctrl(int port, int toggle, int rp, int pull)
{
	return tcpc_write(port, TCPC_REG_ROLE_CTRL,
			  TCPC_REG_ROLE_CTRL_SET(toggle, rp, pull, pull));
}

int tcpci_tcpm_set_cc(int port, int pull)
{
	/* Set manual control, and set both CC lines to the same pull */
	return set_role_ctrl(port, 0, selected_rp[port], pull);
}

#ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE
int tcpci_tcpc_drp_toggle(int port, int enable)
{
	int rv;

	if (!enable) {
#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
		struct usb_mux *mux = &usb_muxes[port];
		if (mux->board_init)
			return mux->board_init(mux);
#endif
		return EC_SUCCESS;
	}
	/* Set auto drp toggle */
	rv = set_role_ctrl(port, 1, TYPEC_RP_USB, TYPEC_CC_RD);

	/* Set Look4Connection command */
	rv |= tcpc_write(port, TCPC_REG_COMMAND,
			 TCPC_REG_COMMAND_LOOK4CONNECTION);

#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
	rv |= tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_I2CIDLE);
#endif
	return rv;
}
#endif

int tcpci_tcpm_set_polarity(int port, int polarity)
{
	return tcpc_write(port, TCPC_REG_TCPC_CTRL,
			  TCPC_REG_TCPC_CTRL_SET(polarity));
}

#ifdef CONFIG_USBC_PPC
int tcpci_tcpm_set_snk_ctrl(int port, int enable)
{
	int cmd = enable ? TCPC_REG_COMMAND_SNK_CTRL_HIGH :
		TCPC_REG_COMMAND_SNK_CTRL_LOW;

	return tcpc_write(port, TCPC_REG_COMMAND, cmd);
}

int tcpci_tcpm_set_src_ctrl(int port, int enable)
{'fraction_non_alphanumeric': 0.09720885466794996, 'fraction_numerical': 0.008662175168431183, 'mean_word_length': 5.331302361005331, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7616697', 'n_tokens_mistral': 3574, 'n_tokens_neox': 3506, 'n_words': 764}