333 lines
8.1 KiB
C
333 lines
8.1 KiB
C
/*
|
|
* Copyright (c) 2022 The Chromium OS Authors
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef ZEPHYR_DRIVERS_USBC_DEVICE_UCPD_STM32_PRIV_H_
|
|
#define ZEPHYR_DRIVERS_USBC_DEVICE_UCPD_STM32_PRIV_H_
|
|
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/sys/util.h>
|
|
#include <zephyr/drivers/usb_c/usbc_tcpc.h>
|
|
#include <zephyr/drivers/pinctrl.h>
|
|
#include <stm32_ll_ucpd.h>
|
|
|
|
/**
|
|
* @brief The packet type(SOP*) consists of 2-bytes
|
|
*/
|
|
#define PACKET_TYPE_SIZE 2
|
|
|
|
/**
|
|
* @brief The message header consists of 2-bytes
|
|
*/
|
|
#define MSG_HEADER_SIZE 2
|
|
|
|
/**
|
|
* @brief USB PD message buffer length.
|
|
*/
|
|
#define UCPD_BUF_LEN (PD_MAX_EXTENDED_MSG_LEN + \
|
|
PACKET_TYPE_SIZE + \
|
|
MSG_HEADER_SIZE)
|
|
|
|
/**
|
|
* @brief UCPD alert mask used for enabling alerts
|
|
* used to receive a message
|
|
*/
|
|
#define UCPD_IMR_RX_INT_MASK (UCPD_IMR_RXNEIE | \
|
|
UCPD_IMR_RXORDDETIE | \
|
|
UCPD_IMR_RXHRSTDETIE | \
|
|
UCPD_IMR_RXOVRIE | \
|
|
UCPD_IMR_RXMSGENDIE)
|
|
/**
|
|
* @brief UCPD alert mask used for clearing alerts
|
|
* used to receive a message
|
|
*/
|
|
#define UCPD_ICR_RX_INT_MASK (UCPD_ICR_RXORDDETCF | \
|
|
UCPD_ICR_RXHRSTDETCF | \
|
|
UCPD_ICR_RXOVRCF | \
|
|
UCPD_ICR_RXMSGENDCF)
|
|
|
|
/**
|
|
* @brief UCPD alert mask used for enabling alerts
|
|
* used to transmit a message
|
|
*/
|
|
#define UCPD_IMR_TX_INT_MASK (UCPD_IMR_TXISIE | \
|
|
UCPD_IMR_TXMSGDISCIE | \
|
|
UCPD_IMR_TXMSGSENTIE | \
|
|
UCPD_IMR_TXMSGABTIE | \
|
|
UCPD_IMR_TXUNDIE)
|
|
|
|
/**
|
|
* @brief UCPD alert mask used for clearing alerts
|
|
* used to transmit a message
|
|
*/
|
|
#define UCPD_ICR_TX_INT_MASK (UCPD_ICR_TXMSGDISCCF | \
|
|
UCPD_ICR_TXMSGSENTCF | \
|
|
UCPD_ICR_TXMSGABTCF | \
|
|
UCPD_ICR_TXUNDCF)
|
|
|
|
/**
|
|
* @brief UCPD alert mask for all alerts
|
|
*/
|
|
#define UCPD_ICR_ALL_INT_MASK (UCPD_ICR_FRSEVTCF | \
|
|
UCPD_ICR_TYPECEVT2CF | \
|
|
UCPD_ICR_TYPECEVT1CF | \
|
|
UCPD_ICR_RXMSGENDCF | \
|
|
UCPD_ICR_RXOVRCF | \
|
|
UCPD_ICR_RXHRSTDETCF | \
|
|
UCPD_ICR_RXORDDETCF | \
|
|
UCPD_ICR_TXUNDCF | \
|
|
UCPD_ICR_HRSTSENTCF | \
|
|
UCPD_ICR_HRSTDISCCF | \
|
|
UCPD_ICR_TXMSGABTCF | \
|
|
UCPD_ICR_TXMSGSENTCF | \
|
|
UCPD_ICR_TXMSGDISCCF)
|
|
|
|
/**
|
|
* @brief For STM32G0X devices, this macro enables
|
|
* Dead Battery functionality
|
|
*/
|
|
#define UCPD_CR_DBATTEN BIT(15)
|
|
|
|
/**
|
|
* @brief Map UCPD ANASUB value to TCPC RP value
|
|
*
|
|
* @param r UCPD ANASUB value
|
|
*/
|
|
#define UCPD_ANASUB_TO_RP(r) ((r - 1) & 0x3)
|
|
|
|
/**
|
|
* @brief Map TCPC RP value to UCPD ANASUB value
|
|
*
|
|
* @param r TCPC RP value
|
|
*/
|
|
#define UCPD_RP_TO_ANASUB(r) ((r + 1) & 0x3)
|
|
|
|
/**
|
|
* @brief Create value for writing to UCPD CR ANASUBMOD
|
|
*/
|
|
#define STM32_UCPD_CR_ANASUBMODE_VAL(x) ((x) << UCPD_CR_ANASUBMODE_Pos)
|
|
|
|
/**
|
|
* @brief UCPD VSTATE CCx open value when in source mode
|
|
*/
|
|
#define STM32_UCPD_SR_VSTATE_OPEN 3
|
|
|
|
/**
|
|
* @brief UCPD VSTATE CCx RA value when in source mode
|
|
*/
|
|
#define STM32_UCPD_SR_VSTATE_RA 0
|
|
|
|
/**
|
|
* @brief PD message send retry count for Rev 2.0
|
|
*/
|
|
#define UCPD_N_RETRY_COUNT_REV20 3
|
|
|
|
/**
|
|
* @brief PD message send retry count for Rev 3.0
|
|
*/
|
|
#define UCPD_N_RETRY_COUNT_REV30 2
|
|
|
|
/**
|
|
* @brief Events for ucpd_alert_handler
|
|
*/
|
|
enum {
|
|
/* Request to send a goodCRC message */
|
|
UCPD_EVT_GOOD_CRC_REQ,
|
|
/* Request to send a power delivery message */
|
|
UCPD_EVT_TCPM_MSG_REQ,
|
|
/* Request to send a Hard Reset message */
|
|
UCPD_EVT_HR_REQ,
|
|
/* Transmission of power delivery message failed */
|
|
UCPD_EVT_TX_MSG_FAIL,
|
|
/* Transmission of power delivery message was discarded */
|
|
UCPD_EVT_TX_MSG_DISC,
|
|
/* Transmission of power delivery message was successful */
|
|
UCPD_EVT_TX_MSG_SUCCESS,
|
|
/* Transmission of Hard Reset message was successful */
|
|
UCPD_EVT_HR_DONE,
|
|
/* Transmission of Hard Reset message failed */
|
|
UCPD_EVT_HR_FAIL,
|
|
/* A goodCRC message was received */
|
|
UCPD_EVT_RX_GOOD_CRC,
|
|
/* A power delivery message was received */
|
|
UCPD_EVT_RX_MSG,
|
|
/* A CC event occurred */
|
|
UCPD_EVT_EVENT_CC,
|
|
/* A Hard Reset message was received */
|
|
UCPD_EVT_HARD_RESET_RECEIVED,
|
|
};
|
|
|
|
/**
|
|
* @brief GoodCRC message header roles
|
|
*/
|
|
struct msg_header_info {
|
|
/* Power Role */
|
|
enum tc_power_role pr;
|
|
/* Data Role */
|
|
enum tc_data_role dr;
|
|
};
|
|
|
|
/**
|
|
* @brief States for managing TX messages
|
|
*/
|
|
enum ucpd_state {
|
|
/* Idle state */
|
|
STATE_IDLE,
|
|
/* Transmitting a message state */
|
|
STATE_ACTIVE_TCPM,
|
|
/* Transmitting a goodCRC message state */
|
|
STATE_ACTIVE_CRC,
|
|
/* Transmitting a Hard Reset message state */
|
|
STATE_HARD_RESET,
|
|
/* Waiting for a goodCRC message state */
|
|
STATE_WAIT_CRC_ACK
|
|
};
|
|
|
|
/**
|
|
* @brief Tx messages are initiated either by the application or from
|
|
* the driver when a GoodCRC ack message needs to be sent.
|
|
*/
|
|
enum ucpd_tx_msg {
|
|
/* Default value for not sending a message */
|
|
TX_MSG_NONE = -1,
|
|
/* Message initiated from the application */
|
|
TX_MSG_TCPM = 0,
|
|
/* Message initiated from the driver */
|
|
TX_MSG_GOOD_CRC = 1,
|
|
/* Total number sources that can initiate a message */
|
|
TX_MSG_TOTAL = 2
|
|
};
|
|
|
|
/**
|
|
* @brief Message from application mask
|
|
*/
|
|
#define MSG_TCPM_MASK BIT(TX_MSG_TCPM)
|
|
|
|
/**
|
|
* @brief Message from driver mask
|
|
*/
|
|
#define MSG_GOOD_CRC_MASK BIT(TX_MSG_GOOD_CRC)
|
|
|
|
/**
|
|
* @brief Buffer for holding the received message
|
|
*/
|
|
union pd_buffer {
|
|
/* Power Delivery message header */
|
|
uint16_t header;
|
|
/* Power Deliver message data including the message header */
|
|
uint8_t msg[UCPD_BUF_LEN];
|
|
};
|
|
|
|
/**
|
|
* @brief Struct used for transmitting a power delivery message
|
|
*/
|
|
struct ucpd_tx_desc {
|
|
/* Type of the message */
|
|
enum pd_packet_type type;
|
|
/* Length of the message */
|
|
int msg_len;
|
|
/* Index of the current byte to transmit */
|
|
int msg_index;
|
|
/* Power Delivery message to transmit */
|
|
union pd_buffer data;
|
|
};
|
|
|
|
/**
|
|
* @brief Alert handler information
|
|
*/
|
|
struct alert_info {
|
|
/* Runtime device structure */
|
|
const struct device *dev;
|
|
/* Application supplied data that's passed to the
|
|
* application's alert handler callback
|
|
**/
|
|
void *data;
|
|
/* Application's alert handler callback */
|
|
tcpc_alert_handler_cb_t handler;
|
|
/*
|
|
* Kernel worker used to call the application's
|
|
* alert handler callback
|
|
*/
|
|
struct k_work work;
|
|
/* Event flags used in the kernel worker */
|
|
atomic_t evt;
|
|
};
|
|
|
|
/**
|
|
* @brief Driver config
|
|
*/
|
|
struct tcpc_config {
|
|
/* STM32 UCPC CC pin control */
|
|
const struct pinctrl_dev_config *ucpd_pcfg;
|
|
/* STM32 UCPD port */
|
|
UCPD_TypeDef *ucpd_port;
|
|
/* STM32 UCPD parameters */
|
|
LL_UCPD_InitTypeDef ucpd_params;
|
|
/* STM32 UCPD dead battery support */
|
|
bool ucpd_dead_battery;
|
|
};
|
|
|
|
/**
|
|
* @brief Driver data
|
|
*/
|
|
struct tcpc_data {
|
|
/* VCONN callback function */
|
|
tcpc_vconn_control_cb_t vconn_cb;
|
|
/* VCONN Discharge callback function */
|
|
tcpc_vconn_discharge_cb_t vconn_discharge_cb;
|
|
/* Alert information */
|
|
struct alert_info alert_info;
|
|
|
|
/* CC Rp value */
|
|
enum tc_rp_value rp;
|
|
|
|
/* PD Rx variables */
|
|
|
|
/* Number of RX bytes received */
|
|
int ucpd_rx_byte_count;
|
|
/* Buffer to hold the received bytes */
|
|
uint8_t ucpd_rx_buffer[UCPD_BUF_LEN];
|
|
/* GoodCRC message ID */
|
|
int ucpd_crc_id;
|
|
/* Flag to receive or ignore SOP Prime messages */
|
|
bool ucpd_rx_sop_prime_enabled;
|
|
/* Flag set to true when receiving a message */
|
|
bool ucpd_rx_msg_active;
|
|
/* Flag set to true when in RX BIST Mode */
|
|
bool ucpd_rx_bist_mode;
|
|
|
|
/* Tx message variables */
|
|
|
|
/* Buffers to hold messages ready for transmission */
|
|
struct ucpd_tx_desc ucpd_tx_buffers[TX_MSG_TOTAL];
|
|
/* Current buffer being transmitted */
|
|
struct ucpd_tx_desc *ucpd_tx_active_buffer;
|
|
/* Request to send a transmission message */
|
|
int ucpd_tx_request;
|
|
/* State of the TX state machine */
|
|
enum ucpd_state ucpd_tx_state;
|
|
/* Transmission message ID */
|
|
int msg_id_match;
|
|
/* Retry count on failure to transmit a message */
|
|
int tx_retry_count;
|
|
/* Max number of reties before giving up */
|
|
int tx_retry_max;
|
|
|
|
/* GoodCRC message Header */
|
|
struct msg_header_info msg_header;
|
|
/* Track VCONN on/off state */
|
|
bool ucpd_vconn_enable;
|
|
/* Track CC line that VCONN was active on */
|
|
enum tc_cc_polarity ucpd_vconn_cc;
|
|
|
|
/* Dead Battery active */
|
|
bool dead_battery_active;
|
|
|
|
/* Timer for amount of time to wait for receiving a GoodCRC */
|
|
struct k_timer goodcrc_rx_timer;
|
|
};
|
|
|
|
#endif /* ZEPHYR_DRIVERS_USBC_DEVICE_UCPD_STM32_PRIV_H_ */
|