connectivity/usb/pd/ucds.html · connectivity/usb/pd/ucds.rst 공식 원문 ↗

Zephyr 3.7.0 · Connectivity · USB · Power Delivery

USB-C Device Stack

TCPC와 application 사이에서 Sink 또는 Source Power Delivery policy를 구성합니다.

Official pathconnectivity/usb/pd/ucds.html
Source fileconnectivity/usb/pd/ucds.rst
Source versionZephyr 3.7.0
TranslationFull · reviewed

본문 기준: Zephyr 3.7.0 LTS3 · 이후 유지보수 패치는 별도입니다.

Part 1

요약·해설

ChromeOS TCPM에서 이식한 USB-C stack을 사용해 devicetree port·VBUS node, application data, policy check·notification callback을 Sink와 Source 각각 구현하고 등록합니다.

Controller

TCPC

Roles

Sink · Source

Policy

Check · Notify · Data

Part 2

접을 수 있는 영어 원문 전체

영어 원문 전체 펼치기
원문 SHA-256 3FD34802559DC475D10F5A7170E54CA1C3CF0A0B53C11B9B1BDBEE3C93E1407B
.. _usbc_api:

USB-C device stack
##################

The USB-C device stack is a hardware independent interface between a
Type-C Port Controller (TCPC) and customer applications. It is a port of
the Google ChromeOS Type-C Port Manager (TCPM) stack.
It provides the following functionalities:

* Uses the APIs provided by the Type-C Port Controller drivers to interact with
  the Type-C Port Controller.
* Provides a programming interface that's used by a customer applications.
  The APIs is described in
  :zephyr_file:`include/zephyr/usb_c/usbc.h`

Currently the device stack supports implementation of Sink only and Source only
devices. Dual Role Power (DRP) devices are not yet supported.

:ref:`List<usbc-samples>` of samples for different purposes.

Implementing a Sink Type-C and Power Delivery USB-C device
**********************************************************

The configuration of a USB-C Device is done in the stack layer and devicetree.

The following devicetree, structures and callbacks need to be defined:

* Devicetree usb-c-connector node referencing a TCPC
* Devicetree vbus node referencing a VBUS measurement device
* User defined structure that encapsulates application specific data
* Policy callbacks

For example, for the Sample USB-C Sink application:

Each Physical Type-C port is represented in the devicetree by a usb-c-connector
compatible node:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/sink/boards/b_g474e_dpow1.overlay
   :language: dts
   :start-after: usbc.rst usbc-port start
   :end-before: usbc.rst usbc-port end
   :linenos:

VBUS is measured by a device that's referenced in the devicetree by a
usb-c-vbus-adc compatible node:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/sink/boards/b_g474e_dpow1.overlay
   :language: dts
   :start-after: usbc.rst vbus-voltage-divider-adc start
   :end-before: usbc.rst vbus-voltage-divider-adc end
   :linenos:


A user defined structure is defined and later registered with the subsystem and can
be accessed from callback through an API:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/sink/src/main.c
   :language: c
   :start-after: usbc.rst port data object start
   :end-before: usbc.rst port data object end
   :linenos:

These callbacks are used by the subsystem to set or get application specific data:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/sink/src/main.c
   :language: c
   :start-after: usbc.rst callbacks start
   :end-before: usbc.rst callbacks end
   :linenos:

This callback is used by the subsystem to query if a certain action can be taken:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/sink/src/main.c
   :language: c
   :start-after: usbc.rst check start
   :end-before: usbc.rst check end
   :linenos:

This callback is used by the subsystem to notify the application of an event:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/sink/src/main.c
   :language: c
   :start-after: usbc.rst notify start
   :end-before: usbc.rst notify end
   :linenos:

Registering the callbacks:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/sink/src/main.c
   :language: c
   :start-after: usbc.rst register start
   :end-before: usbc.rst register end
   :linenos:

Register the user defined structure:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/sink/src/main.c
   :language: c
   :start-after: usbc.rst user data start
   :end-before: usbc.rst user data end
   :linenos:

Start the USB-C subsystem:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/sink/src/main.c
   :language: c
   :start-after: usbc.rst usbc start
   :end-before: usbc.rst usbc end
   :linenos:

Implementing a Source Type-C and Power Delivery USB-C device
************************************************************

The configuration of a USB-C Device is done in the stack layer and devicetree.

Define the following devicetree, structures and callbacks:

* Devicetree ``usb-c-connector`` node referencing a TCPC
* Devicetree ``vbus`` node referencing a VBUS measurement device
* User defined structure that encapsulates application specific data
* Policy callbacks

For example, for the Sample USB-C Source application:

Each Physical Type-C port is represented in the devicetree by a ``usb-c-connector``
compatible node:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/source/boards/stm32g081b_eval.overlay
   :language: dts
   :start-after: usbc.rst usbc-port start
   :end-before: usbc.rst usbc-port end
   :linenos:

VBUS is measured by a device that's referenced in the devicetree by a
``usb-c-vbus-adc`` compatible node:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/source/boards/stm32g081b_eval.overlay
   :language: dts
   :start-after: usbc.rst vbus-voltage-divider-adc start
   :end-before: usbc.rst vbus-voltage-divider-adc end
   :linenos:


A user defined structure is defined and later registered with the subsystem and can
be accessed from callback through an API:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/source/src/main.c
   :language: c
   :start-after: usbc.rst port data object start
   :end-before: usbc.rst port data object end
   :linenos:

These callbacks are used by the subsystem to set or get application specific data:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/source/src/main.c
   :language: c
   :start-after: usbc.rst callbacks start
   :end-before: usbc.rst callbacks end
   :linenos:

This callback is used by the subsystem to query if a certain action can be taken:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/source/src/main.c
   :language: c
   :start-after: usbc.rst check start
   :end-before: usbc.rst check end
   :linenos:

This callback is used by the subsystem to notify the application of an event:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/source/src/main.c
   :language: c
   :start-after: usbc.rst notify start
   :end-before: usbc.rst notify end
   :linenos:

Registering the callbacks:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/source/src/main.c
   :language: c
   :start-after: usbc.rst register start
   :end-before: usbc.rst register end
   :linenos:

Register the user defined structure:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/source/src/main.c
   :language: c
   :start-after: usbc.rst user data start
   :end-before: usbc.rst user data end
   :linenos:

Start the USB-C subsystem:

.. literalinclude:: ../../../../../../samples/subsys/usb_c/source/src/main.c
   :language: c
   :start-after: usbc.rst usbc start
   :end-before: usbc.rst usbc end
   :linenos:

API reference
*************

.. doxygengroup:: _usbc_device_api

SINK callback reference
***********************

.. doxygengroup:: sink_callbacks

SOURCE callback reference
*************************

.. doxygengroup:: source_callbacks

Part 3

한국어 전문 번역

USB-C device stack

USB-C device stack은 Type-C Port Controller(TCPC)와 사용자 application 사이의 hardware 독립 interface입니다. Google ChromeOS Type-C Port Manager(TCPM) stack을 이식한 것입니다.

다음 기능을 제공합니다.

  • Type-C Port Controller driver가 제공하는 API를 사용해 TCPC와 상호작용합니다.
  • 사용자 application이 이용하는 programming interface를 제공합니다. API는 include/zephyr/usb_c/usbc.h에 기술되어 있습니다.

현재 device stack은 Sink-only와 Source-only device 구현을 지원합니다. Dual Role Power(DRP) device는 아직 지원하지 않습니다.

용도별 USB-C sample 목록을 참고할 수 있습니다.

Sink Type-C 및 Power Delivery USB-C device 구현

USB-C device configuration은 stack layer와 devicetree에서 수행합니다.

다음 devicetree node, structure와 callback을 정의해야 합니다.

  • TCPC를 참조하는 devicetree usb-c-connector node
  • VBUS 측정 device를 참조하는 devicetree vbus node
  • Application 전용 data를 담는 사용자 정의 structure
  • Policy callback

USB-C Sink sample application을 예로 설명합니다.

각 physical Type-C port는 devicetree의 usb-c-connector compatible node로 표현합니다.

		port1: usbc-port@1 {
			compatible = "usb-c-connector";
			reg = <1>;
			tcpc = <&ucpd1>;
			vbus = <&vbus1>;
			power-role = "sink";
			sink-pdos = <PDO_FIXED(5000, 100, 0)>;
		};

VBUS는 devicetree의 usb-c-vbus-adc compatible node가 참조하는 device로 측정합니다.

	vbus1: vbus {
		compatible = "zephyr,usb-c-vbus-adc";
		io-channels = <&adc2 8>;
		output-ohms = <49900>;
		full-ohms = <(330000 + 49900)>;
	};

사용자 정의 structure를 만들고 이후 subsystem에 등록합니다. Callback은 API를 통해 이 structure에 접근할 수 있습니다.

/**
 * @brief A structure that encapsulates Port data.
 */
static struct port0_data_t {
	/** Sink Capabilities */
	uint32_t snk_caps[DT_PROP_LEN(USBC_PORT0_NODE, sink_pdos)];
	/** Number of Sink Capabilities */
	int snk_cap_cnt;
	/** Source Capabilities */
	uint32_t src_caps[PDO_MAX_DATA_OBJECTS];
	/** Number of Source Capabilities */
	int src_cap_cnt;
	/* Power Supply Ready flag */
	atomic_t ps_ready;
} port0_data = {
	.snk_caps = {DT_FOREACH_PROP_ELEM(USBC_PORT0_NODE, sink_pdos, SINK_PDO)},
	.snk_cap_cnt = DT_PROP_LEN(USBC_PORT0_NODE, sink_pdos),
	.src_caps = {0},
	.src_cap_cnt = 0,
	.ps_ready = 0
};

Subsystem은 다음 callback을 사용해 application 전용 data를 설정하거나 가져옵니다.

static int port0_policy_cb_get_snk_cap(const struct device *dev,
					    uint32_t **pdos,
					    int *num_pdos)
{
	struct port0_data_t *dpm_data = usbc_get_dpm_data(dev);

	*pdos = dpm_data->snk_caps;
	*num_pdos = dpm_data->snk_cap_cnt;

	return 0;
}

static void port0_policy_cb_set_src_cap(const struct device *dev,
					     const uint32_t *pdos,
					     const int num_pdos)
{
	struct port0_data_t *dpm_data;
	int num;
	int i;

	dpm_data = usbc_get_dpm_data(dev);

	num = num_pdos;
	if (num > PDO_MAX_DATA_OBJECTS) {
		num = PDO_MAX_DATA_OBJECTS;
	}

	for (i = 0; i < num; i++) {
		dpm_data->src_caps[i] = *(pdos + i);
	}

	dpm_data->src_cap_cnt = num;
}

static uint32_t port0_policy_cb_get_rdo(const struct device *dev)
{
	struct port0_data_t *dpm_data = usbc_get_dpm_data(dev);

	return build_rdo(dpm_data);
}

Subsystem은 다음 callback으로 특정 action을 수행해도 되는지 조회합니다.

bool port0_policy_check(const struct device *dev,
			const enum usbc_policy_check_t policy_check)
{
	switch (policy_check) {
	case CHECK_POWER_ROLE_SWAP:
		/* Reject power role swaps */
		return false;
	case CHECK_DATA_ROLE_SWAP_TO_DFP:
		/* Reject data role swap to DFP */
		return false;
	case CHECK_DATA_ROLE_SWAP_TO_UFP:
		/* Accept data role swap to UFP */
		return true;
	case CHECK_SNK_AT_DEFAULT_LEVEL:
		/* This device is always at the default power level */
		return true;
	default:
		/* Reject all other policy checks */
		return false;

	}
}

Subsystem은 다음 callback으로 event를 application에 알립니다.

static void port0_notify(const struct device *dev,
			      const enum usbc_policy_notify_t policy_notify)
{
	struct port0_data_t *dpm_data = usbc_get_dpm_data(dev);

	switch (policy_notify) {
	case PROTOCOL_ERROR:
		break;
	case MSG_DISCARDED:
		break;
	case MSG_ACCEPT_RECEIVED:
		break;
	case MSG_REJECTED_RECEIVED:
		break;
	case MSG_NOT_SUPPORTED_RECEIVED:
		break;
	case TRANSITION_PS:
		atomic_set_bit(&dpm_data->ps_ready, 0);
		break;
	case PD_CONNECTED:
		break;
	case NOT_PD_CONNECTED:
		break;
	case POWER_CHANGE_0A0:
		LOG_INF("PWR 0A");
		break;
	case POWER_CHANGE_DEF:
		LOG_INF("PWR DEF");
		break;
	case POWER_CHANGE_1A5:
		LOG_INF("PWR 1A5");
		break;
	case POWER_CHANGE_3A0:
		LOG_INF("PWR 3A0");
		break;
	case DATA_ROLE_IS_UFP:
		break;
	case DATA_ROLE_IS_DFP:
		break;
	case PORT_PARTNER_NOT_RESPONSIVE:
		LOG_INF("Port Partner not PD Capable");
		break;
	case SNK_TRANSITION_TO_DEFAULT:
		break;
	case HARD_RESET_RECEIVED:
		break;
	case SENDER_RESPONSE_TIMEOUT:
		break;
	case SOURCE_CAPABILITIES_RECEIVED:
		break;
	}
}

Policy callback을 등록합니다.

	/* Register USB-C Callbacks */

	/* Register Policy Check callback */
	usbc_set_policy_cb_check(usbc_port0, port0_policy_check);
	/* Register Policy Notify callback */
	usbc_set_policy_cb_notify(usbc_port0, port0_notify);
	/* Register Policy Get Sink Capabilities callback */
	usbc_set_policy_cb_get_snk_cap(usbc_port0, port0_policy_cb_get_snk_cap);
	/* Register Policy Set Source Capabilities callback */
	usbc_set_policy_cb_set_src_cap(usbc_port0, port0_policy_cb_set_src_cap);
	/* Register Policy Get Request Data Object callback */
	usbc_set_policy_cb_get_rdo(usbc_port0, port0_policy_cb_get_rdo);

사용자 정의 structure를 subsystem에 등록합니다.

	/* Set Application port data object. This object is passed to the policy callbacks */
	port0_data.ps_ready = ATOMIC_INIT(0);
	usbc_set_dpm_data(usbc_port0, &port0_data);

USB-C subsystem을 시작합니다.

	/* Start the USB-C Subsystem */
	usbc_start(usbc_port0);

Source Type-C 및 Power Delivery USB-C device 구현

USB-C device configuration은 stack layer와 devicetree에서 수행합니다.

다음 devicetree node, structure와 callback을 정의합니다.

  • TCPC를 참조하는 devicetree usb-c-connector node
  • VBUS 측정 device를 참조하는 devicetree vbus node
  • Application 전용 data를 담는 사용자 정의 structure
  • Policy callback

USB-C Source sample application을 예로 설명합니다.

각 physical Type-C port는 devicetree의 usb-c-connector compatible node로 표현합니다.

		port1: usbc-port@1 {
			compatible = "usb-c-connector";
			reg = <1>;
			tcpc = <&ucpd1>;
			vbus = <&vbus1>;
			power-role = "source";
			typec-power-opmode = "3.0A";
			source-pdos = <PDO_FIXED(5000, 100, 0) PDO_FIXED(9000, 100, 0) PDO_FIXED(15000, 100, 0)>;
		};

VBUS는 devicetree의 usb-c-vbus-adc compatible node가 참조하는 device로 측정합니다.

	vbus1: vbus {
		compatible = "zephyr,usb-c-vbus-adc";
		io-channels = <&adc1 9>;
		output-ohms = <49900>;
		full-ohms = <(330000 + 49900)>;

		/* Pin B13 is used to control VBUS Discharge for Port1 */
		discharge-gpios = <&gpiob 13 GPIO_ACTIVE_HIGH>;
	};

사용자 정의 structure를 만들고 이후 subsystem에 등록합니다. Callback은 API를 통해 이 structure에 접근할 수 있습니다.

/**
 * @brief A structure that encapsulates Port data.
 */
static struct port0_data_t {
	/** Source Capabilities */
	uint32_t src_caps[DT_PROP_LEN(USBC_PORT0_NODE, source_pdos)];
	/** Number of Source Capabilities */
	int src_cap_cnt;
	/** CC Rp value */
	int rp;
	/** Sink Request RDO */
	union pd_rdo sink_request;
	/** Requested Object Pos */
	int obj_pos;
	/** VCONN CC line*/
	enum tc_cc_polarity vconn_pol;
	/** True if power supply is ready */
	bool ps_ready;
	/** True if power supply should transition to a new level */
	bool ps_tran_start;
	/** Log Sink Requested RDO to console */
	atomic_t show_sink_request;
} port0_data = {
	.rp = DT_ENUM_IDX(USBC_PORT0_NODE, typec_power_opmode),
	.src_caps = {DT_FOREACH_PROP_ELEM(USBC_PORT0_NODE, source_pdos, SOURCE_PDO)},
	.src_cap_cnt = DT_PROP_LEN(USBC_PORT0_NODE, source_pdos),
};

Subsystem은 다음 callback을 사용해 application 전용 data를 설정하거나 가져옵니다.

/**
 * @brief PE calls this function when it needs to set the Rp on CC
 */
int port0_policy_cb_get_src_rp(const struct device *dev,
			       enum tc_rp_value *rp)
{
	struct port0_data_t *dpm_data = usbc_get_dpm_data(dev);

	*rp = dpm_data->rp;

	return 0;
}

/**
 * @brief PE calls this function to Enable (5V) or Disable (0V) the
 *	  Power Supply
 */
int port0_policy_cb_src_en(const struct device *dev, bool en)
{
	source_ctrl_set(en ? SOURCE_5V : SOURCE_0V);

	return 0;
}

/**
 * @brief PE calls this function to Enable or Disable VCONN
 */
int port0_policy_cb_vconn_en(const struct device *dev, enum tc_cc_polarity pol, bool en)
{
	struct port0_data_t *dpm_data = usbc_get_dpm_data(dev);

	dpm_data->vconn_pol = pol;

	if (en == false) {
		/* Disable VCONN on CC1 and CC2 */
		vconn_ctrl_set(VCONN_OFF);
	} else if (pol == TC_POLARITY_CC1) {
		/* set VCONN on CC1 */
		vconn_ctrl_set(VCONN1_ON);
	} else {
		/* set VCONN on CC2 */
		vconn_ctrl_set(VCONN2_ON);
	}

	return 0;
}

/**
 * @brief PE calls this function to get the Source Caps that will be sent
 *	  to the Sink
 */
int port0_policy_cb_get_src_caps(const struct device *dev,
			const uint32_t **pdos, uint32_t *num_pdos)
{
	struct port0_data_t *dpm_data = usbc_get_dpm_data(dev);

	*pdos = dpm_data->src_caps;
	*num_pdos = dpm_data->src_cap_cnt;

	return 0;
}

/**
 * @brief PE calls this function to verify that a Sink's request if valid
 */
static enum usbc_snk_req_reply_t port0_policy_cb_check_sink_request(const struct device *dev,
					const uint32_t request_msg)
{
	struct port0_data_t *dpm_data = usbc_get_dpm_data(dev);
	union pd_fixed_supply_pdo_source pdo;
	uint32_t obj_pos;
	uint32_t op_current;

	dpm_data->sink_request.raw_value = request_msg;
	obj_pos = dpm_data->sink_request.fixed.object_pos;
	op_current =
		PD_CONVERT_FIXED_PDO_CURRENT_TO_MA(dpm_data->sink_request.fixed.operating_current);

	if (obj_pos == 0 || obj_pos > dpm_data->src_cap_cnt) {
		return SNK_REQUEST_REJECT;
	}

	pdo.raw_value = dpm_data->src_caps[obj_pos - 1];

	if (dpm_data->sink_request.fixed.operating_current > pdo.max_current) {
		return SNK_REQUEST_REJECT;
	}

	dpm_data->obj_pos = obj_pos;

	atomic_set_bit(&port0_data.show_sink_request, 0);

	/*
	 * Clear PS ready. This will be set to true after PS is ready after
	 * it transitions to the new level.
	 */
	port0_data.ps_ready = false;

	return SNK_REQUEST_VALID;
}

/**
 * @brief PE calls this function to check if the Power Supply is at the requested
 *	  level
 */
static bool port0_policy_cb_is_ps_ready(const struct device *dev)
{
	struct port0_data_t *dpm_data = usbc_get_dpm_data(dev);


	/* Return true to inform that the Power Supply is ready */
	return dpm_data->ps_ready;
}

/**
 * @brief PE calls this function to check if the Present Contract is still
 *	  valid
 */
static bool port0_policy_cb_present_contract_is_valid(const struct device *dev,
					const uint32_t present_contract)
{
	struct port0_data_t *dpm_data = usbc_get_dpm_data(dev);
	union pd_fixed_supply_pdo_source pdo;
	union pd_rdo request;
	uint32_t obj_pos;
	uint32_t op_current;

	request.raw_value = present_contract;
	obj_pos = request.fixed.object_pos;
	op_current = PD_CONVERT_FIXED_PDO_CURRENT_TO_MA(request.fixed.operating_current);

	if (obj_pos == 0 || obj_pos > dpm_data->src_cap_cnt) {
		return false;
	}

	pdo.raw_value = dpm_data->src_caps[obj_pos - 1];

	if (request.fixed.operating_current > pdo.max_current) {
		return false;
	}

	return true;
}

Subsystem은 다음 callback으로 특정 action을 수행해도 되는지 조회합니다.

bool port0_policy_check(const struct device *dev,
			const enum usbc_policy_check_t policy_check)
{
	struct port0_data_t *dpm_data = usbc_get_dpm_data(dev);

	switch (policy_check) {
	case CHECK_POWER_ROLE_SWAP:
		/* Reject power role swaps */
		return false;
	case CHECK_DATA_ROLE_SWAP_TO_DFP:
		/* Accept data role swap to DFP */
		return true;
	case CHECK_DATA_ROLE_SWAP_TO_UFP:
		/* Reject data role swap to UFP */
		return false;
	case CHECK_SRC_PS_AT_DEFAULT_LEVEL:
		/*
		 * This check is sent from the PE_SRC_Transition_to_default
		 * state and requires the following:
		 *	1: Vconn should be turned ON
		 *	2: Return TRUE when Power Supply is at default level
		 */

		/* Power on VCONN */
		vconn_ctrl_set(dpm_data->vconn_pol);

		/* PS should be at default level after receiving a Hard Reset */
		return true;
	default:
		/* Reject all other policy checks */
		return false;

	}
}

Subsystem은 다음 callback으로 event를 application에 알립니다.

static void port0_notify(const struct device *dev,
			      const enum usbc_policy_notify_t policy_notify)
{
	struct port0_data_t *dpm_data = usbc_get_dpm_data(dev);

	switch (policy_notify) {
	case PROTOCOL_ERROR:
		break;
	case MSG_DISCARDED:
		break;
	case MSG_ACCEPT_RECEIVED:
		break;
	case MSG_REJECTED_RECEIVED:
		break;
	case MSG_NOT_SUPPORTED_RECEIVED:
		break;
	case TRANSITION_PS:
		dpm_data->ps_tran_start = true;
		break;
	case PD_CONNECTED:
		break;
	case NOT_PD_CONNECTED:
		break;
	case DATA_ROLE_IS_UFP:
		break;
	case DATA_ROLE_IS_DFP:
		break;
	case PORT_PARTNER_NOT_RESPONSIVE:
		LOG_INF("Port Partner not PD Capable");
		break;
	case HARD_RESET_RECEIVED:
		/*
		 * This notification is sent from the PE_SRC_Transition_to_default
		 * state and requires the following:
		 *	1: Vconn should be turned OFF
		 *	2: Reset of the local hardware
		 */

		/* Power off VCONN */
		vconn_ctrl_set(VCONN_OFF);
		/* Transition PS to Default level */
		source_ctrl_set(SOURCE_5V);
		break;
	default:
	}
}

Policy callback을 등록합니다.

	/* Register USB-C Callbacks */

	/* Register Policy Check callback */
	usbc_set_policy_cb_check(usbc_port0, port0_policy_check);
	/* Register Policy Notify callback */
	usbc_set_policy_cb_notify(usbc_port0, port0_notify);
	/* Register Policy callback to set the Rp on CC lines */
	usbc_set_policy_cb_get_src_rp(usbc_port0, port0_policy_cb_get_src_rp);
	/* Register Policy callback to enable or disable power supply */
	usbc_set_policy_cb_src_en(usbc_port0, port0_policy_cb_src_en);
	/* Register Policy callback to enable or disable vconn */
	usbc_set_vconn_control_cb(usbc_port0, port0_policy_cb_vconn_en);
	/* Register Policy callback to send the source caps to the sink */
	usbc_set_policy_cb_get_src_caps(usbc_port0, port0_policy_cb_get_src_caps);
	/* Register Policy callback to check if the sink request is valid */
	usbc_set_policy_cb_check_sink_request(usbc_port0, port0_policy_cb_check_sink_request);
	/* Register Policy callback to check if the power supply is ready */
	usbc_set_policy_cb_is_ps_ready(usbc_port0, port0_policy_cb_is_ps_ready);
	/* Register Policy callback to check if Present Contract is still valid */
	usbc_set_policy_cb_present_contract_is_valid(usbc_port0,
				port0_policy_cb_present_contract_is_valid);

사용자 정의 structure를 subsystem에 등록합니다.

	/* Set Application port data object. This object is passed to the policy callbacks */
	usbc_set_dpm_data(usbc_port0, &port0_data);

USB-C subsystem을 시작합니다.

	/* Start the USB-C Subsystem */
	usbc_start(usbc_port0);

API reference

USB-C device stack API reference는 Doxygen group _usbc_device_api에서 제공합니다.

Sink callback reference

Sink policy callback reference는 Doxygen group sink_callbacks에서 제공합니다.

Source callback reference

Source policy callback reference는 Doxygen group source_callbacks에서 제공합니다.

Source

출처

영어 원문에는 문단, 문서 지시문, 표, 코드, 코드 심벌, 경로를 그대로 보존했습니다.