summaryrefslogtreecommitdiff
path: root/zephyr/include/emul/tcpc
diff options
context:
space:
mode:
Diffstat (limited to 'zephyr/include/emul/tcpc')
-rw-r--r--zephyr/include/emul/tcpc/emul_ps8xxx.h141
-rw-r--r--zephyr/include/emul/tcpc/emul_tcpci.h323
-rw-r--r--zephyr/include/emul/tcpc/emul_tcpci_partner_common.h161
-rw-r--r--zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h65
-rw-r--r--zephyr/include/emul/tcpc/emul_tcpci_partner_src.h106
5 files changed, 796 insertions, 0 deletions
diff --git a/zephyr/include/emul/tcpc/emul_ps8xxx.h b/zephyr/include/emul/tcpc/emul_ps8xxx.h
new file mode 100644
index 0000000000..110def22ec
--- /dev/null
+++ b/zephyr/include/emul/tcpc/emul_ps8xxx.h
@@ -0,0 +1,141 @@
+/* Copyright 2021 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.
+ */
+
+/**
+ * @file
+ *
+ * @brief Backend API for PS8xxx emulator
+ */
+
+#ifndef __EMUL_PS8XXX_H
+#define __EMUL_PS8XXX_H
+
+#include <emul.h>
+#include <drivers/i2c.h>
+#include <drivers/i2c_emul.h>
+
+/**
+ * @brief PS8xxx emulator backend API
+ * @defgroup ps8xxx_emul PS8xxx emulator
+ * @{
+ *
+ * PS8xxx emulator is extension for the TCPCI emulator. It is able to emulate
+ * PS8805 and PS8815 devices. It registers "hidden" I2C devices with the I2C
+ * emulation controller.
+ * Application may alter emulator state:
+ *
+ * - call @ref ps8xxx_emul_set_product_id to select which device is emulated
+ * (PS8805 or PS8815)
+ * - call @ref ps8xxx_emul_get_tcpci to get TCPCI emulator pointer that is used
+ * as base for PS8xxx emulator. The pointer can be used in tcpci_emul_*
+ * functions.
+ * - call @ref ps8xxx_emul_get_i2c_emul to get "hidden" I2C device (port 0, 1
+ * or GPIO)
+ * - call @ref ps8xxx_emul_set_chip_rev to set PS8805 chip revision
+ * - call @ref ps8xxx_emul_set_hw_rev to set PS8815 HW revision
+ * - call @ref ps8xxx_emul_set_gpio_ctrl to set GPIO control register
+ */
+
+/** Types of "hidden" I2C devices */
+enum ps8xxx_emul_port {
+ PS8XXX_EMUL_PORT_0,
+ PS8XXX_EMUL_PORT_1,
+ PS8XXX_EMUL_PORT_GPIO,
+ PS8XXX_EMUL_PORT_INVAL,
+};
+
+/* For now all devices supported by this emulator has the same FW rev reg */
+#define PS8XXX_REG_FW_REV 0x82
+
+/**
+ * @brief Get pointer to specific "hidden" I2C device
+ *
+ * @param emul Pointer to PS8xxx emulator
+ * @param port Select which "hidden" I2C device should be obtained
+ *
+ * @return NULL if given "hidden" I2C device cannot be found
+ * @return pointer to "hidden" I2C device
+ */
+struct i2c_emul *ps8xxx_emul_get_i2c_emul(const struct emul *emul,
+ enum ps8xxx_emul_port port);
+
+/**
+ * @brief Get pointer to TCPCI emulator that is base for PS8xxx emulator
+ *
+ * @param emul Pointer to PS8xxx emulator
+ *
+ * @return pointer to TCPCI emulator
+ */
+const struct emul *ps8xxx_emul_get_tcpci(const struct emul *emul);
+
+/**
+ * @brief Set value of chip revision register on PS8805
+ *
+ * @param emul Pointer to PS8xxx emulator
+ * @param chip_rev Value to be set
+ */
+void ps8xxx_emul_set_chip_rev(const struct emul *emul, uint8_t chip_rev);
+
+/**
+ * @brief Set value of HW revision register on PS8815
+ *
+ * @param emul Pointer to PS8xxx emulator
+ * @param hw_rev Value to be set
+ */
+void ps8xxx_emul_set_hw_rev(const struct emul *emul, uint16_t hw_rev);
+
+/**
+ * @brief Set value of GPIO control register
+ *
+ * @param emul Pointer to PS8xxx emulator
+ * @param gpio_ctrl Value to be set
+ */
+void ps8xxx_emul_set_gpio_ctrl(const struct emul *emul, uint8_t gpio_ctrl);
+
+/**
+ * @brief Get value of GPIO control register
+ *
+ * @param emul Pointer to PS8xxx emulator
+ *
+ * @return Value of GPIO control register
+ */
+uint8_t ps8xxx_emul_get_gpio_ctrl(const struct emul *emul);
+
+/**
+ * @brief Get value of mux usb DCI configuration register
+ *
+ * @param emul Pointer to PS8xxx emulator
+ *
+ * @return Value of mux usb DCI configuration register
+ */
+uint8_t ps8xxx_emul_get_dci_cfg(const struct emul *emul);
+
+/**
+ * @brief Set product ID of emulated PS8xxx device. This change behaviour
+ * of emulator to mimic that device. Currently supported are PS8805 and
+ * PS8815
+ *
+ * @param emul Pointer to PS8xxx emulator
+ * @param product_id Value to be set
+ *
+ * @return 0 on success
+ * @return -EINVAL when unsupported product ID is selected
+ */
+int ps8xxx_emul_set_product_id(const struct emul *emul, uint16_t product_id);
+
+/**
+ * @brief Get product ID of emulated PS8xxx device
+ *
+ * @param emul Pointer to PS8xxx emulator
+ *
+ * @return Product ID of emulated PS8xxx device
+ */
+uint16_t ps8xxx_emul_get_product_id(const struct emul *emul);
+
+/**
+ * @}
+ */
+
+#endif /* __EMUL_PS8XXX */
diff --git a/zephyr/include/emul/tcpc/emul_tcpci.h b/zephyr/include/emul/tcpc/emul_tcpci.h
new file mode 100644
index 0000000000..3a5a3047d7
--- /dev/null
+++ b/zephyr/include/emul/tcpc/emul_tcpci.h
@@ -0,0 +1,323 @@
+/* Copyright 2021 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.
+ */
+
+/**
+ * @file
+ *
+ * @brief Backend API for TCPCI emulator
+ */
+
+#ifndef __EMUL_TCPCI_H
+#define __EMUL_TCPCI_H
+
+#include <emul.h>
+#include <drivers/i2c.h>
+#include <drivers/i2c_emul.h>
+#include <usb_pd_tcpm.h>
+
+/**
+ * @brief TCPCI emulator backend API
+ * @defgroup tcpci_emul TCPCI emulator
+ * @{
+ *
+ * TCPCI emulator supports access to its registers using I2C messages.
+ * It follows Type-C Port Controller Interface Specification. It is possible
+ * to use this emulator as base for implementation of specific TCPC emulator
+ * which follows TCPCI specification. Emulator allows to set callbacks
+ * on change of CC status or transmitting message to implement partner emulator.
+ * There is also callback used to inform about alert line state change.
+ * Application may alter emulator state:
+ *
+ * - call @ref tcpci_emul_set_reg and @ref tcpci_emul_get_reg to set and get
+ * value of TCPCI registers
+ * - call functions from emul_common_i2c.h to setup custom handlers for I2C
+ * messages
+ * - call @ref tcpci_emul_add_rx_msg to setup received SOP messages
+ * - call @ref tcpci_emul_get_tx_msg to examine sended message
+ * - call @ref tcpci_emul_set_rev to set revision of emulated TCPCI
+ */
+
+/** SOP message structure */
+struct tcpci_emul_msg {
+ /** Pointer to buffer for header and message */
+ uint8_t *buf;
+ /** Number of bytes in buf */
+ int cnt;
+ /** Type of message (SOP, SOP', etc) */
+ uint8_t type;
+ /** Index used to mark accessed byte */
+ int idx;
+ /** Pointer to optional second message */
+ struct tcpci_emul_msg *next;
+};
+
+/**
+ * @brief Function type that is used by TCPCI emulator to provide information
+ * about alert line state
+ *
+ * @param emul Pointer to emulator
+ * @param alert State of alert line (false - low, true - high)
+ * @param data Pointer to custom function data
+ */
+typedef void (*tcpci_emul_alert_state_func)(const struct emul *emul, bool alert,
+ void *data);
+
+/** Response from TCPCI specific device operations */
+enum tcpci_emul_ops_resp {
+ TCPCI_EMUL_CONTINUE = 0,
+ TCPCI_EMUL_DONE,
+ TCPCI_EMUL_ERROR
+};
+
+/** Revisions supported by TCPCI emaluator */
+enum tcpci_emul_rev {
+ TCPCI_EMUL_REV1_0_VER1_0 = 0,
+ TCPCI_EMUL_REV2_0_VER1_1
+};
+
+/** Status of TX message send to TCPCI emulator partner */
+enum tcpci_emul_tx_status {
+ TCPCI_EMUL_TX_SUCCESS,
+ TCPCI_EMUL_TX_DISCARDED,
+ TCPCI_EMUL_TX_FAILED
+};
+
+/** TCPCI specific device operations. Not all of them need to be implemented. */
+struct tcpci_emul_dev_ops {
+ /**
+ * @brief Function called for each byte of read message
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param ops Pointer to device operations structure
+ * @param reg First byte of last write message
+ * @param val Pointer where byte to read should be stored
+ * @param bytes Number of bytes already readded
+ *
+ * @return TCPCI_EMUL_CONTINUE to continue with default handler
+ * @return TCPCI_EMUL_DONE to immedietly return success
+ * @return TCPCI_EMUL_ERROR to immedietly return error
+ */
+ enum tcpci_emul_ops_resp (*read_byte)(const struct emul *emul,
+ const struct tcpci_emul_dev_ops *ops,
+ int reg, uint8_t *val, int bytes);
+
+ /**
+ * @brief Function called for each byte of write message
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param ops Pointer to device operations structure
+ * @param reg First byte of write message
+ * @param val Received byte of write message
+ * @param bytes Number of bytes already received
+ *
+ * @return TCPCI_EMUL_CONTINUE to continue with default handler
+ * @return TCPCI_EMUL_DONE to immedietly return success
+ * @return TCPCI_EMUL_ERROR to immedietly return error
+ */
+ enum tcpci_emul_ops_resp (*write_byte)(const struct emul *emul,
+ const struct tcpci_emul_dev_ops *ops,
+ int reg, uint8_t val, int bytes);
+
+ /**
+ * @brief Function called on the end of write message
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param ops Pointer to device operations structure
+ * @param reg Register which is written
+ * @param msg_len Length of handled I2C message
+ *
+ * @return TCPCI_EMUL_CONTINUE to continue with default handler
+ * @return TCPCI_EMUL_DONE to immedietly return success
+ * @return TCPCI_EMUL_ERROR to immedietly return error
+ */
+ enum tcpci_emul_ops_resp (*handle_write)(const struct emul *emul,
+ const struct tcpci_emul_dev_ops *ops,
+ int reg, int msg_len);
+
+ /**
+ * @brief Function called on reset
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param ops Pointer to device operations structure
+ */
+ void (*reset)(const struct emul *emul, struct tcpci_emul_dev_ops *ops);
+};
+
+/** TCPCI partner operations. Not all of them need to be implemented. */
+struct tcpci_emul_partner_ops {
+ /**
+ * @brief Function called when TCPM wants to transmit message to partner
+ * connected to TCPCI
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param ops Pointer to partner operations structure
+ * @param tx_msg Pointer to TX message buffer
+ * @param type Type of message
+ * @param retry Count of retries
+ */
+ void (*transmit)(const struct emul *emul,
+ const struct tcpci_emul_partner_ops *ops,
+ const struct tcpci_emul_msg *tx_msg,
+ enum tcpci_msg_type type,
+ int retry);
+
+ /**
+ * @brief Function called when control settings change to allow partner
+ * to react
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param ops Pointer to partner operations structure
+ */
+ void (*control_change)(const struct emul *emul,
+ const struct tcpci_emul_partner_ops *ops);
+
+ /**
+ * @brief Function called when TCPM consumes message send by partner
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param ops Pointer to partner operations structure
+ * @param rx_msg Message that was consumed by TCPM
+ */
+ void (*rx_consumed)(const struct emul *emul,
+ const struct tcpci_emul_partner_ops *ops,
+ const struct tcpci_emul_msg *rx_msg);
+};
+
+/**
+ * @brief Get i2c_emul for TCPCI emulator
+ *
+ * @param emul Pointer to TCPCI emulator
+ *
+ * @return Pointer to I2C TCPCI emulator
+ */
+struct i2c_emul *tcpci_emul_get_i2c_emul(const struct emul *emul);
+
+/**
+ * @brief Set value of given register of TCPCI
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param reg Register address which value will be changed
+ * @param val New value of the register
+ *
+ * @return 0 on success
+ * @return -EINVAL when register is out of range defined in TCPCI specification
+ */
+int tcpci_emul_set_reg(const struct emul *emul, int reg, uint16_t val);
+
+/**
+ * @brief Get value of given register of TCPCI
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param reg Register address
+ * @param val Pointer where value should be stored
+ *
+ * @return 0 on success
+ * @return -EINVAL when register is out of range defined in TCPCI specification
+ * or val is NULL
+ */
+int tcpci_emul_get_reg(const struct emul *emul, int reg, uint16_t *val);
+
+/**
+ * @brief Add up to two SOP RX messages
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param rx_msg Pointer to message that is added
+ * @param alert Select if alert register should be updated
+ *
+ * @return 0 on success
+ * @return -EINVAL on error (too long message or adding third message)
+ */
+int tcpci_emul_add_rx_msg(const struct emul *emul,
+ struct tcpci_emul_msg *rx_msg, bool alert);
+
+/**
+ * @brief Get SOP TX message to examine what was sended by TCPM
+ *
+ * @param emul Pointer to TCPCI emulator
+ *
+ * @return Pointer to TX message
+ */
+struct tcpci_emul_msg *tcpci_emul_get_tx_msg(const struct emul *emul);
+
+/**
+ * @brief Set TCPCI revision in PD_INT_REV register
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param rev Requested revision
+ */
+void tcpci_emul_set_rev(const struct emul *emul, enum tcpci_emul_rev rev);
+
+/**
+ * @brief Set callbacks for specific TCPC device emulator
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param dev_ops Pointer to callbacks
+ */
+void tcpci_emul_set_dev_ops(const struct emul *emul,
+ struct tcpci_emul_dev_ops *dev_ops);
+
+/**
+ * @brief Set callback which is called when alert register is changed
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param alert_callback Pointer to callback
+ * @param alert_callback_data Pointer to data passed to callback as an argument
+ */
+void tcpci_emul_set_alert_callback(const struct emul *emul,
+ tcpci_emul_alert_state_func alert_callback,
+ void *alert_callback_data);
+
+/**
+ * @brief Set callbacks for port partner device emulator
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param partner Pointer to callbacks
+ */
+void tcpci_emul_set_partner_ops(const struct emul *emul,
+ struct tcpci_emul_partner_ops *partner);
+
+/**
+ * @brief Emulate connection of specific device to emulated TCPCI
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param partner_power_role Power role of connected partner (sink or source)
+ * @param partner_cc1 Voltage on partner CC1 line (usually Rd or Rp)
+ * @param partner_cc2 Voltage on partner CC2 line (usually open or Ra if active
+ * cable is emulated)
+ * @param polarity Polarity of plug. If POLARITY_CC1 then partner_cc1 is
+ * connected to TCPCI CC1 line. Otherwise partner_cc1 is
+ * connected to TCPCI CC2 line.
+ *
+ * @return 0 on success
+ * @return negative on error
+ */
+int tcpci_emul_connect_partner(const struct emul *emul,
+ enum pd_power_role partner_power_role,
+ enum tcpc_cc_voltage_status partner_cc1,
+ enum tcpc_cc_voltage_status partner_cc2,
+ enum tcpc_cc_polarity polarity);
+
+/** @brief Emulate the disconnection of the partner device to emulated TCPCI
+ *
+ * @param emul Pointer to TCPCI emulator
+ *
+ * @return 0 on success
+ */
+int tcpci_emul_disconnect_partner(const struct emul *emul);
+
+/**
+ * @brief Allows port partner to select if message was received correctly
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param status Status of sended message
+ */
+void tcpci_emul_partner_msg_status(const struct emul *emul,
+ enum tcpci_emul_tx_status status);
+
+/**
+ * @}
+ */
+
+#endif /* __EMUL_TCPCI */
diff --git a/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h b/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h
new file mode 100644
index 0000000000..0275161d73
--- /dev/null
+++ b/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h
@@ -0,0 +1,161 @@
+/* Copyright 2021 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.
+ */
+
+/**
+ * @file
+ *
+ * @brief Common code used by TCPCI partner device emulators
+ */
+
+#ifndef __EMUL_TCPCI_PARTNER_COMMON_H
+#define __EMUL_TCPCI_PARTNER_COMMON_H
+
+#include <emul.h>
+#include "emul/tcpc/emul_tcpci.h"
+
+#include "ec_commands.h"
+#include "usb_pd.h"
+
+/**
+ * @brief Common code used by TCPCI partner device emulators
+ * @defgroup tcpci_partner Common code for TCPCI partner device emulators
+ * @{
+ *
+ * Common code for TCPCI partner device emulators allows to send SOP messages
+ * in generic way using optional delay.
+ */
+
+/** Common data for TCPCI partner device emulators */
+struct tcpci_partner_data {
+ /** Work used to send message with delay */
+ struct k_work_delayable delayed_send;
+ /** Pointer to connected TCPCI emulator */
+ const struct emul *tcpci_emul;
+ /** Queue for delayed messages */
+ sys_slist_t to_send;
+ /** Mutex for to_send queue */
+ struct k_mutex to_send_mutex;
+ /** Next SOP message id */
+ int msg_id;
+ /** Power role (used in message header) */
+ enum pd_power_role power_role;
+ /** Data role (used in message header) */
+ enum pd_data_role data_role;
+ /** Revision (used in message header) */
+ enum pd_rev_type rev;
+};
+
+/** Structure of message used by TCPCI partner emulator */
+struct tcpci_partner_msg {
+ /** Reserved for sys_slist_* usage */
+ sys_snode_t node;
+ /** TCPCI emulator message */
+ struct tcpci_emul_msg msg;
+ /** Time when message should be sent if message is delayed */
+ uint64_t time;
+ /** Type of the message */
+ int type;
+ /** Number of data objects */
+ int data_objects;
+};
+
+/**
+ * @brief Initialise common TCPCI partner emulator. Need to be called before
+ * any other function.
+ *
+ * @param data Pointer to USB-C charger emulator
+ */
+void tcpci_partner_init(struct tcpci_partner_data *data);
+
+/**
+ * @brief Allocate message with space for header and given number of data
+ * objects. Type of message is set to TCPCI_MSG_SOP by default.
+ *
+ * @param data_objects Number of data objects in message
+ *
+ * @return Pointer to new message on success
+ * @return NULL on error
+ */
+struct tcpci_partner_msg *tcpci_partner_alloc_msg(int data_objects);
+
+/**
+ * @brief Free message's memory
+ *
+ * @param msg Pointer to message
+ */
+void tcpci_partner_free_msg(struct tcpci_partner_msg *msg);
+
+/**
+ * @brief Set header of the message
+ *
+ * @param data Pointer to TCPCI partner emulator
+ * @param msg Pointer to message
+ */
+void tcpci_partner_set_header(struct tcpci_partner_data *data,
+ struct tcpci_partner_msg *msg);
+
+/**
+ * @brief Send message to TCPCI emulator or schedule message. On error message
+ * is freed.
+ *
+ * @param data Pointer to TCPCI partner emulator
+ * @param msg Pointer to message to send
+ * @param delay Optional delay
+ *
+ * @return 0 on success
+ * @return negative on failure
+ */
+int tcpci_partner_send_msg(struct tcpci_partner_data *data,
+ struct tcpci_partner_msg *msg, uint64_t delay);
+
+/**
+ * @brief Send control message with optional delay
+ *
+ * @param data Pointer to TCPCI partner emulator
+ * @param type Type of message
+ * @param delay Optional delay
+ *
+ * @return 0 on success
+ * @return -ENOMEM when there is no free memory for message
+ * @return negative on failure
+ */
+int tcpci_partner_send_control_msg(struct tcpci_partner_data *data,
+ enum pd_ctrl_msg_type type,
+ uint64_t delay);
+
+/**
+ * @brief Send data message with optional delay. Data objects are copied to
+ * message.
+ *
+ * @param data Pointer to TCPCI partner emulator
+ * @param type Type of message
+ * @param data_obj Pointer to array of data objects
+ * @param data_obj_num Number of data objects
+ * @param delay Optional delay
+ *
+ * @return 0 on success
+ * @return -ENOMEM when there is no free memory for message
+ * @return negative on failure
+ */
+int tcpci_partner_send_data_msg(struct tcpci_partner_data *data,
+ enum pd_data_msg_type type,
+ uint32_t *data_obj, int data_obj_num,
+ uint64_t delay);
+
+/**
+ * @brief Remove all messages that are in delayed message queue
+ *
+ * @param data Pointer to TCPCI partner emulator
+ *
+ * @return 0 on success
+ * @return negative on failure
+ */
+int tcpci_partner_clear_msg_queue(struct tcpci_partner_data *data);
+
+/**
+ * @}
+ */
+
+#endif /* __EMUL_TCPCI_PARTNER_COMMON_H */
diff --git a/zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h b/zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h
new file mode 100644
index 0000000000..7e2482a4ad
--- /dev/null
+++ b/zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h
@@ -0,0 +1,65 @@
+/* Copyright 2021 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.
+ */
+
+/**
+ * @file
+ *
+ * @brief Backend API for USB-C sink device emulator
+ */
+
+#ifndef __EMUL_TCPCI_PARTNER_SNK_H
+#define __EMUL_TCPCI_PARTNER_SNK_H
+
+#include <emul.h>
+#include "emul/tcpc/emul_tcpci_partner_common.h"
+#include "emul/tcpc/emul_tcpci.h"
+#include "usb_pd.h"
+
+/**
+ * @brief USB-C sink device emulator backend API
+ * @defgroup tcpci_snk_emul USB-C sink device emulator
+ * @{
+ *
+ * USB-C sink device emulator can be attached to TCPCI emulator. It is able to
+ * respond to some TCPM messages. It always attach as sink and present
+ * sink capabilities constructed from given PDOs.
+ */
+
+/** Structure describing sink device emulator */
+struct tcpci_snk_emul_data {
+ /** Common TCPCI partner data */
+ struct tcpci_partner_data common_data;
+ /** Operations used by TCPCI emulator */
+ struct tcpci_emul_partner_ops ops;
+ /** Power data objects returned in sink capabilities message */
+ uint32_t pdo[PDO_MAX_OBJECTS];
+};
+
+/**
+ * @brief Initialise USB-C sink device emulator. Need to be called before
+ * any other function.
+ *
+ * @param data Pointer to USB-C sink device emulator
+ */
+
+void tcpci_snk_emul_init(struct tcpci_snk_emul_data *data);
+
+/**
+ * @brief Connect emulated device to TCPCI
+ *
+ * @param data Pointer to USB-C sink device emulator
+ * @param tcpci_emul Pointer to TCPCI emulator to connect
+ *
+ * @return 0 on success
+ * @return negative on TCPCI connect error
+ */
+int tcpci_snk_emul_connect_to_tcpci(struct tcpci_snk_emul_data *data,
+ const struct emul *tcpci_emul);
+
+/**
+ * @}
+ */
+
+#endif /* __EMUL_TCPCI_PARTNER_SNK_H */
diff --git a/zephyr/include/emul/tcpc/emul_tcpci_partner_src.h b/zephyr/include/emul/tcpc/emul_tcpci_partner_src.h
new file mode 100644
index 0000000000..549afb5cc0
--- /dev/null
+++ b/zephyr/include/emul/tcpc/emul_tcpci_partner_src.h
@@ -0,0 +1,106 @@
+/* Copyright 2021 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.
+ */
+
+/**
+ * @file
+ *
+ * @brief Backend API for USB-C source device emulator
+ */
+
+#ifndef __EMUL_TCPCI_PARTNER_SRC_H
+#define __EMUL_TCPCI_PARTNER_SRC_H
+
+#include <emul.h>
+#include "emul/tcpc/emul_tcpci_partner_common.h"
+#include "emul/tcpc/emul_tcpci.h"
+#include "usb_pd.h"
+
+/**
+ * @brief USB-C source device emulator backend API
+ * @defgroup tcpci_src_emul USB-C source device emulator
+ * @{
+ *
+ * USB-C source device emulator can be attached to TCPCI emulator. It is able to
+ * respond to some TCPM messages. It always attach as source and present
+ * source capabilities constructed from given PDOs.
+ */
+
+/** Structure describing source device emulator */
+struct tcpci_src_emul_data {
+ /** Common TCPCI partner data */
+ struct tcpci_partner_data common_data;
+ /** Operations used by TCPCI emulator */
+ struct tcpci_emul_partner_ops ops;
+ /** Power data objects returned in source capabilities message */
+ uint32_t pdo[PDO_MAX_OBJECTS];
+};
+
+/** Return values of @ref tcpci_src_emul_check_pdos function */
+enum check_pdos_res {
+ TCPCI_SRC_EMUL_CHECK_PDO_OK = 0,
+ TCPCI_SRC_EMUL_FIRST_PDO_NO_FIXED_5V,
+ TCPCI_SRC_EMUL_FIXED_VOLT_REPEATED,
+ TCPCI_SRC_EMUL_FIXED_VOLT_NOT_IN_ORDER,
+ TCPCI_SRC_EMUL_NON_FIRST_PDO_FIXED_FLAGS,
+ TCPCI_SRC_EMUL_BATT_VOLT_REPEATED,
+ TCPCI_SRC_EMUL_BATT_VOLT_NOT_IN_ORDER,
+ TCPCI_SRC_EMUL_VAR_VOLT_REPEATED,
+ TCPCI_SRC_EMUL_VAR_VOLT_NOT_IN_ORDER,
+ TCPCI_SRC_EMUL_PDO_AFTER_ZERO,
+};
+
+/**
+ * @brief Initialise USB-C source device emulator. Need to be called before
+ * any other function.
+ *
+ * @param data Pointer to USB-C source device emulator
+ */
+void tcpci_src_emul_init(struct tcpci_src_emul_data *data);
+
+/**
+ * @brief Connect emulated device to TCPCI
+ *
+ * @param data Pointer to USB-C source device emulator
+ * @param tcpci_emul Poinetr to TCPCI emulator to connect
+ *
+ * @return 0 on success
+ * @return negative on TCPCI connect error or send source capabilities error
+ */
+int tcpci_src_emul_connect_to_tcpci(struct tcpci_src_emul_data *data,
+ const struct emul *tcpci_emul);
+
+/**
+ * @brief Check if PDOs of given source device emulator are in correct order
+ *
+ * @param data Pointer to USB-C source device emulator
+ *
+ * @return TCPCI_SRC_EMUL_CHECK_PDO_OK if PDOs are correct
+ * @return TCPCI_SRC_EMUL_FIRST_PDO_NO_FIXED_5V if first PDO is not
+ * fixed type 5V
+ * @return TCPCI_SRC_EMUL_FIXED_VOLT_REPEATED if two or more fixed type PDOs
+ * have the same voltage
+ * @return TCPCI_SRC_EMUL_FIXED_VOLT_NOT_IN_ORDER if fixed PDO with higher
+ * voltage is before the one with lower voltage
+ * @return TCPCI_SRC_EMUL_NON_FIRST_PDO_FIXED_FLAGS if PDO different than first
+ * has some flags set
+ * @return TCPCI_SRC_EMUL_BATT_VOLT_REPEATED if two or more battery type PDOs
+ * have the same min and max voltage
+ * @return TCPCI_SRC_EMUL_BATT_VOLT_NOT_IN_ORDER if battery PDO with higher
+ * voltage is before the one with lower voltage
+ * @return TCPCI_SRC_EMUL_VAR_VOLT_REPEATED if two or more variable type PDOs
+ * have the same min and max voltage
+ * @return TCPCI_SRC_EMUL_VAR_VOLT_NOT_IN_ORDER if variable PDO with higher
+ * voltage is before the one with lower voltage
+ * @return TCPCI_SRC_EMUL_PDO_AFTER_ZERO if PDOs of different types are not in
+ * correct order (fixed, battery, variable) or non-zero PDO is placed
+ * after zero PDO
+ */
+enum check_pdos_res tcpci_src_emul_check_pdos(struct tcpci_src_emul_data *data);
+
+/**
+ * @}
+ */
+
+#endif /* __EMUL_TCPCI_PARTNER_SRC_H */