diff --git a/drivers/usb_c/tcpc/CMakeLists.txt b/drivers/usb_c/tcpc/CMakeLists.txt index 7bf2ff781c94307..d1a428fceb07834 100644 --- a/drivers/usb_c/tcpc/CMakeLists.txt +++ b/drivers/usb_c/tcpc/CMakeLists.txt @@ -7,3 +7,4 @@ zephyr_library_sources_ifdef(CONFIG_USBC_TCPC_STM32 ucpd_stm32.c) zephyr_library_sources_ifdef(CONFIG_USBC_TCPC_NUMAKER ucpd_numaker.c) zephyr_library_sources_ifdef(CONFIG_USBC_TCPC_TCPCI tcpci.c) zephyr_library_sources_ifdef(CONFIG_USBC_TCPC_PS8XXX ps8xxx.c) +zephyr_library_sources_ifdef(CONFIG_USBC_TCPC_RT1715 rt1715.c) diff --git a/drivers/usb_c/tcpc/Kconfig b/drivers/usb_c/tcpc/Kconfig index b4fdd64f090833f..3b1a9ccc2840ab2 100644 --- a/drivers/usb_c/tcpc/Kconfig +++ b/drivers/usb_c/tcpc/Kconfig @@ -29,6 +29,7 @@ source "drivers/usb_c/tcpc/Kconfig.tcpc_stm32" source "drivers/usb_c/tcpc/Kconfig.tcpc_numaker" source "drivers/usb_c/tcpc/Kconfig.tcpc_tcpci" source "drivers/usb_c/tcpc/Kconfig.tcpc_ps8xxx" +source "drivers/usb_c/tcpc/Kconfig.tcpc_rt1715" module = USBC module-str = usbc diff --git a/drivers/usb_c/tcpc/Kconfig.tcpc_rt1715 b/drivers/usb_c/tcpc/Kconfig.tcpc_rt1715 new file mode 100644 index 000000000000000..2bce559590f2e4f --- /dev/null +++ b/drivers/usb_c/tcpc/Kconfig.tcpc_rt1715 @@ -0,0 +1,28 @@ +# USB-C RT1715 TCPC configuration options + +# Copyright (c) 2024 Jianxiong Gu +# SPDX-License-Identifier: Apache-2.0 + +config USBC_TCPC_RT1715 + bool "USB-C TCPC device controller driver" + select USBC_TCPC_TCPCI + default y + depends on DT_HAS_RICHTEK_RT1715_ENABLED + help + Enable USB-C TCPC support for the Richtek RT1715 + +if USBC_TCPC_RT1715 + +config USBC_TCPC_RT1715_INIT_DELAY + int "RT1715 init delay" + default 25 + help + Delay between each try of the TCPC initialization + +config USBC_TCPC_RT1715_INIT_RETRIES + int "RT1715 init retries" + default 10 + help + Number of initialization tries that will be performed + +endif diff --git a/drivers/usb_c/tcpc/rt1715.c b/drivers/usb_c/tcpc/rt1715.c new file mode 100644 index 000000000000000..183ec51e13249cd --- /dev/null +++ b/drivers/usb_c/tcpc/rt1715.c @@ -0,0 +1,712 @@ +/* + * Copyright (c) 2024 Jianxiong Gu + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "rt1715.h" + +#define DT_DRV_COMPAT richtek_rt1715 +LOG_MODULE_REGISTER(rt1715, CONFIG_USBC_LOG_LEVEL); + +/** Data structure for device instances */ +struct rt1715_data { + /** Device structure used to retrieve it in k_work functions */ + const struct device *const dev; + /** Delayable work item for chip initialization */ + struct k_work_delayable init_dwork; + /** Initialization retries counter */ + int init_retries; + /** Boolean value if chip was successfully initialized */ + bool initialized; + + /** Callback for alert GPIO */ + struct gpio_callback alert_cb; + /** Work item for alert handling out of interrupt context */ + struct k_work alert_work; + + /** Boolean value if there is a message pending */ + bool msg_pending; + /** One-slot Rx FIFO */ + struct pd_msg rx_msg; + + /** Alert handler set by USB-C stack */ + tcpc_alert_handler_cb_t alert_handler; + /** Alert handler data set by USB-C stack */ + void *alert_handler_data; + + /** VCONN discharge callback set by USB-C stack */ + tcpc_vconn_discharge_cb_t vconn_discharge_cb; + /** VCONN discharge callback data set by USB-C stack */ + tcpc_vconn_control_cb_t vconn_cb; + /** Polarity of CC lines for PD and VCONN */ + enum tc_cc_polarity cc_polarity; + + /** Boolean value if there was a change on the CC lines since last check */ + bool cc_changed; + /** State of CC1 line */ + enum tc_cc_voltage_state cc1; + /** State of CC2 line */ + enum tc_cc_voltage_state cc2; + + /* Flag to receive or ignore SOP Prime messages */ + bool rx_sop_prime_enable; +}; + +/** Configuration structure for device instances */ +struct rt1715_cfg { + /** I2C bus and address used for communication */ + const struct i2c_dt_spec bus; + /** GPIO specification for alert pin */ + const struct gpio_dt_spec alert_gpio; + /** GPIO specification for VCONN power control pin */ + const struct gpio_dt_spec vconn_ctrl_gpio; + /** GPIO specification for VCONN discharge control pin */ + const struct gpio_dt_spec vconn_disc_gpio; + /** Maximum number of packet retransmissions done by TCPC */ + const uint8_t transmit_retries; +}; + +static int tcpci_init_alert_mask(const struct device *dev) +{ + const struct rt1715_cfg *cfg = dev->config; + + uint16_t mask = TCPC_REG_ALERT_TX_COMPLETE | TCPC_REG_ALERT_RX_STATUS | + TCPC_REG_ALERT_RX_HARD_RST | TCPC_REG_ALERT_CC_STATUS | + TCPC_REG_ALERT_POWER_STATUS | TCPC_REG_ALERT_FAULT | + TCPC_REG_ALERT_RX_BUF_OVF; + + return tcpci_tcpm_mask_status_register(&cfg->bus, TCPC_ALERT_STATUS, mask); +} + +static int rt1715_tcpc_init(const struct device *dev) +{ + struct rt1715_data *data = dev->data; + + if (!data->initialized) { + if (data->init_retries > CONFIG_USBC_TCPC_RT1715_INIT_RETRIES) { + LOG_ERR("TCPC was not initialized correctly"); + return -EIO; + } + + return -EAGAIN; + } + + data->rx_sop_prime_enable = false; + data->msg_pending = false; + memset(&data->rx_msg, 0x00, sizeof(data->rx_msg)); + + LOG_INF("RT1715 TCPC initialized"); + return 0; +} + +static int rt1715_tcpc_get_cc(const struct device *dev, enum tc_cc_voltage_state *cc1, + enum tc_cc_voltage_state *cc2) +{ + const struct rt1715_cfg *cfg = dev->config; + struct rt1715_data *data = dev->data; + int ret; + + if (!data->initialized) { + return -EIO; + } + + if (IS_ENABLED(CONFIG_USBC_CSM_SINK_ONLY) && !data->cc_changed) { + *cc1 = data->cc1; + *cc2 = data->cc2; + + return 0; + } + + data->cc_changed = false; + + ret = tcpci_tcpm_get_cc(&cfg->bus, cc1, cc2); + + if (IS_ENABLED(CONFIG_USBC_CSM_SINK_ONLY) || *cc1 != data->cc1 || *cc2 != data->cc2) { + LOG_DBG("CC changed values: %d->%d, %d->%d", data->cc1, *cc1, data->cc2, *cc2); + data->cc1 = *cc1; + data->cc2 = *cc2; + } + + return ret; +} + +static int rt1715_tcpc_select_rp_value(const struct device *dev, enum tc_rp_value rp) +{ + const struct rt1715_cfg *cfg = dev->config; + struct rt1715_data *data = dev->data; + + data->cc_changed = true; + + return tcpci_tcpm_select_rp_value(&cfg->bus, rp); +} + +static int rt1715_tcpc_get_rp_value(const struct device *dev, enum tc_rp_value *rp) +{ + const struct rt1715_cfg *cfg = dev->config; + + return tcpci_tcpm_get_rp_value(&cfg->bus, rp); +} + +static int rt1715_tcpc_set_cc(const struct device *dev, enum tc_cc_pull pull) +{ + const struct rt1715_cfg *cfg = dev->config; + struct rt1715_data *data = dev->data; + + if (!data->initialized) { + return -EIO; + } + + data->cc_changed = true; + + return tcpci_tcpm_set_cc(&cfg->bus, pull); +} + +static void rt1715_tcpc_set_vconn_discharge_cb(const struct device *dev, + tcpc_vconn_discharge_cb_t cb) +{ + struct rt1715_data *data = dev->data; + + data->vconn_discharge_cb = cb; +} + +static void rt1715_tcpc_set_vconn_cb(const struct device *dev, tcpc_vconn_control_cb_t vconn_cb) +{ + struct rt1715_data *data = dev->data; + + data->vconn_cb = vconn_cb; +} + +static int rt1715_tcpc_vconn_discharge(const struct device *dev, bool enable) +{ + const struct rt1715_cfg *cfg = dev->config; + + if (cfg->vconn_disc_gpio.port == NULL) { + /* RT1715 does not have built-in VCONN discharge path */ + LOG_ERR("VCONN discharge GPIO is not defined"); + return -EIO; + } + + return gpio_pin_set_dt(&cfg->vconn_disc_gpio, enable); +} + +static int rt1715_tcpc_set_vconn(const struct device *dev, bool enable) +{ + const struct rt1715_cfg *cfg = dev->config; + struct rt1715_data *data = dev->data; + int ret; + + if (!data->initialized) { + return -EIO; + } + + if (enable == true && cfg->vconn_ctrl_gpio.port != NULL) { + /* Enable external VCONN power supply */ + gpio_pin_set_dt(&cfg->vconn_ctrl_gpio, true); + } + + data->cc_changed = true; + ret = tcpci_tcpm_set_vconn(&cfg->bus, enable); + + if (ret != 0) { + return ret; + } + + if (enable == false && cfg->vconn_ctrl_gpio.port != NULL) { + /* Disable external VCONN power supply */ + gpio_pin_set_dt(&cfg->vconn_ctrl_gpio, false); + } + + if (data->vconn_cb != NULL) { + ret = data->vconn_cb(dev, data->cc_polarity, enable); + } + + return ret; +} + +static int rt1715_tcpc_set_roles(const struct device *dev, enum tc_power_role power_role, + enum tc_data_role data_role) +{ + const struct rt1715_cfg *cfg = dev->config; + + return tcpci_tcpm_set_roles(&cfg->bus, PD_REV30, power_role, data_role); +} + +static int rt1715_tcpc_get_rx_pending_msg(const struct device *dev, struct pd_msg *msg) +{ + struct rt1715_data *data = dev->data; + + /* Rx message pending? */ + if (!data->msg_pending) { + return -ENODATA; + } + + /* Query status only? */ + if (msg == NULL) { + return 0; + } + + /* Dequeue Rx FIFO */ + *msg = data->rx_msg; + data->msg_pending = false; + + /* Indicate Rx message returned */ + return 1; +} + +static int rt1715_tcpc_rx_fifo_enqueue(const struct device *dev) +{ + const struct rt1715_cfg *const cfg = dev->config; + struct rt1715_data *data = dev->data; + uint8_t rxbcnt; + uint8_t rxftype; + uint16_t rxhead; + uint8_t rx_data_size; + struct pd_msg *msg = &data->rx_msg; + int ret = 0; + + ret |= tcpci_read_reg8(&cfg->bus, TCPC_REG_RX_BUFFER, &rxbcnt); + ret |= tcpci_read_reg8(&cfg->bus, TCPC_REG_RX_BUFFER + 1, &rxftype); + ret |= tcpci_read_reg16(&cfg->bus, TCPC_REG_RX_BUFFER + 2, &rxhead); + if (ret != 0) { + return ret; + } + + /* rxbcnt = 1 (frame type) + 2 (Message Header) + Rx data byte count */ + if (rxbcnt < 3) { + LOG_ERR("Invalid RXBCNT: %d", rxbcnt); + return -EIO; + } + rx_data_size = rxbcnt - 3; + + /* Not support Unchunked Extended Message exceeding PD_CONVERT_PD_HEADER_COUNT_TO_BYTES */ + if (rx_data_size > (PD_MAX_EXTENDED_MSG_LEGACY_LEN + 2)) { + LOG_ERR("Not support Unchunked Extended Message exceeding " + "PD_CONVERT_PD_HEADER_COUNT_TO_BYTES: %d", + rx_data_size); + return -EIO; + } + + /* Rx frame type */ + msg->type = rxftype; + + /* Rx header */ + msg->header.raw_value = (uint16_t)rxhead; + + /* Rx data size */ + msg->len = rx_data_size; + + /* Rx data */ + if (rx_data_size > 0) { + ret = i2c_burst_read_dt(&cfg->bus, TCPC_REG_RX_BUFFER + 4, msg->data, rx_data_size); + if (ret) { + LOG_ERR("Failed to read Rx data: %d", ret); + } + } + + return ret; +} + +static int rt1715_tcpc_set_rx_enable(const struct device *dev, bool enable) +{ + const struct rt1715_cfg *cfg = dev->config; + struct rt1715_data *data = dev->data; + + if (enable == false) { + return tcpci_tcpm_set_rx_type(&cfg->bus, 0); + } + + if (data->rx_sop_prime_enable) { + return tcpci_tcpm_set_rx_type(&cfg->bus, + TCPC_REG_RX_DETECT_SOP_SOPP_SOPPP_HRST_MASK); + } else { + return tcpci_tcpm_set_rx_type(&cfg->bus, TCPC_REG_RX_DETECT_SOP_HRST_MASK); + } +} + +static int rt1715_tcpc_set_cc_polarity(const struct device *dev, enum tc_cc_polarity polarity) +{ + const struct rt1715_cfg *cfg = dev->config; + struct rt1715_data *data = dev->data; + int ret; + + if (!data->initialized) { + return -EIO; + } + + ret = tcpci_tcpm_set_cc_polarity(&cfg->bus, polarity); + + if (ret != 0) { + return ret; + } + + data->cc_changed = true; + data->cc_polarity = polarity; + return 0; +} + +static int rt1715_tcpc_transmit_data(const struct device *dev, struct pd_msg *msg) +{ + const struct rt1715_cfg *cfg = dev->config; + + return tcpci_tcpm_transmit_data(&cfg->bus, msg, cfg->transmit_retries); +} + +static int rt1715_tcpc_dump_std_reg(const struct device *dev) +{ + const struct rt1715_cfg *cfg = dev->config; + + LOG_INF("TCPC %s:%s registers:", cfg->bus.bus->name, dev->name); + + return tcpci_tcpm_dump_std_reg(&cfg->bus); +} + +void rt1715_tcpc_alert_handler_cb(const struct device *dev, void *data, enum tcpc_alert alert) +{ +} + +static int rt1715_tcpc_get_status_register(const struct device *dev, enum tcpc_status_reg reg, + uint32_t *status) +{ + const struct rt1715_cfg *cfg = dev->config; + + if (reg == TCPC_VENDOR_DEFINED_STATUS) { + return tcpci_read_reg8(&cfg->bus, RT1715_REG_RT_INT, (uint8_t *)status); + } + + return tcpci_tcpm_get_status_register(&cfg->bus, reg, (uint16_t *)status); +} + +static int rt1715_tcpc_clear_status_register(const struct device *dev, enum tcpc_status_reg reg, + uint32_t mask) +{ + const struct rt1715_cfg *cfg = dev->config; + + if (reg == TCPC_VENDOR_DEFINED_STATUS) { + return tcpci_write_reg8(&cfg->bus, RT1715_REG_RT_INT, (uint8_t)mask); + } + + return tcpci_tcpm_clear_status_register(&cfg->bus, reg, (uint16_t)mask); +} + +static int rt1715_tcpc_mask_status_register(const struct device *dev, enum tcpc_status_reg reg, + uint32_t mask) +{ + const struct rt1715_cfg *cfg = dev->config; + + if (reg == TCPC_VENDOR_DEFINED_STATUS) { + return tcpci_write_reg8(&cfg->bus, RT1715_REG_RT_INT_MASK, (uint8_t)mask); + } + + return tcpci_tcpm_mask_status_register(&cfg->bus, reg, (uint16_t)mask); +} + +static int rt1715_tcpc_set_drp_toggle(const struct device *dev, bool enable) +{ + const struct rt1715_cfg *cfg = dev->config; + + return tcpci_tcpm_set_drp_toggle(&cfg->bus, enable); +} + +static int rt1715_tcpc_get_chip_info(const struct device *dev, struct tcpc_chip_info *chip_info) +{ + const struct rt1715_cfg *cfg = dev->config; + + if (chip_info == NULL) { + return -EIO; + } + + chip_info->fw_version_number = 0; + chip_info->min_req_fw_version_number = 0; + + return tcpci_tcpm_get_chip_info(&cfg->bus, chip_info); +} + +static int rt1715_tcpc_set_low_power_mode(const struct device *dev, bool enable) +{ + const struct rt1715_cfg *cfg = dev->config; + int ret; + + ret = tcpci_write_reg8(&cfg->bus, RT1715_REG_SYS_WAKEUP, RT1715_REG_SYS_WAKEUP_EN); + if (ret < 0) { + return ret; + } + + return tcpci_update_reg8(&cfg->bus, RT1715_REG_SYS_CTRL_1, + RT1715_REG_SYS_CTRL_1_BMCIO_LP_EN, + enable ? RT1715_REG_SYS_CTRL_1_BMCIO_LP_EN : 0); +} + +static int rt1715_tcpc_sop_prime_enable(const struct device *dev, bool enable) +{ + struct rt1715_data *data = dev->data; + + data->rx_sop_prime_enable = enable; + + return 0; +} + +static int rt1715_tcpc_set_bist_test_mode(const struct device *dev, bool enable) +{ + const struct rt1715_cfg *cfg = dev->config; + + return tcpci_tcpm_set_bist_test_mode(&cfg->bus, enable); +} + +static int rt1715_tcpc_set_alert_handler_cb(const struct device *dev, + tcpc_alert_handler_cb_t handler, void *handler_data) +{ + struct rt1715_data *data = dev->data; + + if (data->alert_handler == handler && data->alert_handler_data == handler_data) { + return 0; + } + + data->alert_handler = handler; + data->alert_handler_data = handler_data; + + return 0; +} + +static const struct tcpc_driver_api rt1715_driver_api = { + .init = rt1715_tcpc_init, + .get_cc = rt1715_tcpc_get_cc, + .select_rp_value = rt1715_tcpc_select_rp_value, + .get_rp_value = rt1715_tcpc_get_rp_value, + .set_cc = rt1715_tcpc_set_cc, + .set_vconn_discharge_cb = rt1715_tcpc_set_vconn_discharge_cb, + .set_vconn_cb = rt1715_tcpc_set_vconn_cb, + .vconn_discharge = rt1715_tcpc_vconn_discharge, + .set_vconn = rt1715_tcpc_set_vconn, + .set_roles = rt1715_tcpc_set_roles, + .get_rx_pending_msg = rt1715_tcpc_get_rx_pending_msg, + .set_rx_enable = rt1715_tcpc_set_rx_enable, + .set_cc_polarity = rt1715_tcpc_set_cc_polarity, + .transmit_data = rt1715_tcpc_transmit_data, + .dump_std_reg = rt1715_tcpc_dump_std_reg, + .alert_handler_cb = rt1715_tcpc_alert_handler_cb, + .get_status_register = rt1715_tcpc_get_status_register, + .clear_status_register = rt1715_tcpc_clear_status_register, + .mask_status_register = rt1715_tcpc_mask_status_register, + .set_drp_toggle = rt1715_tcpc_set_drp_toggle, + .get_chip_info = rt1715_tcpc_get_chip_info, + .set_low_power_mode = rt1715_tcpc_set_low_power_mode, + .sop_prime_enable = rt1715_tcpc_sop_prime_enable, + .set_bist_test_mode = rt1715_tcpc_set_bist_test_mode, + .set_alert_handler_cb = rt1715_tcpc_set_alert_handler_cb, +}; + +void rt1715_alert_cb(const struct device *port, struct gpio_callback *cb, gpio_port_pins_t pins) +{ + struct rt1715_data *data = CONTAINER_OF(cb, struct rt1715_data, alert_cb); + + k_work_submit(&data->alert_work); +} + +void rt1715_alert_work_cb(struct k_work *work) +{ + struct rt1715_data *data = CONTAINER_OF(work, struct rt1715_data, alert_work); + const struct device *dev = data->dev; + const struct rt1715_cfg *cfg = dev->config; + uint16_t alert_reg = 0; + uint16_t clear_flags = 0; + + if (!data->initialized) { + return; + } + + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_ALERT_STATUS, &alert_reg); + + while (alert_reg != 0) { + enum tcpc_alert alert_type = tcpci_alert_reg_to_enum(alert_reg); + + if (alert_type == TCPC_ALERT_HARD_RESET_RECEIVED) { + LOG_DBG("hard rst received"); + tcpci_init_alert_mask(dev); + data->cc_changed = true; + } else if (alert_type == TCPC_ALERT_FAULT_STATUS) { + uint8_t fault; + + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_FAULT_STATUS, + (uint16_t *)&fault); + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_FAULT_STATUS, + (uint16_t)fault); + + LOG_DBG("fault: %02x", fault); + } else if (alert_type == TCPC_ALERT_EXTENDED_STATUS) { + uint8_t ext_status; + + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_EXTENDED_STATUS, + (uint16_t *)&ext_status); + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_EXTENDED_STATUS, + (uint16_t)ext_status); + + data->cc_changed = true; + LOG_DBG("ext status: %02x", ext_status); + } else if (alert_type == TCPC_ALERT_POWER_STATUS) { + uint8_t pwr_status; + + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_POWER_STATUS, + (uint16_t *)&pwr_status); + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_POWER_STATUS, + (uint16_t)pwr_status); + + LOG_DBG("power status: %02x", pwr_status); + } else if (alert_type == TCPC_ALERT_EXTENDED) { + uint8_t alert_status; + + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_EXTENDED_ALERT_STATUS, + (uint16_t *)&alert_status); + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_EXTENDED_ALERT_STATUS, + (uint16_t)alert_status); + + LOG_DBG("ext alert: %02x", alert_status); + } else if (alert_type == TCPC_ALERT_MSG_STATUS) { + data->msg_pending = true; + rt1715_tcpc_rx_fifo_enqueue(dev); + + LOG_DBG("MSG pending"); + } else if (alert_type == TCPC_ALERT_CC_STATUS) { + data->cc_changed = true; + } + + if (data->alert_handler != NULL) { + data->alert_handler(dev, data->alert_handler_data, alert_type); + } + + clear_flags |= BIT(alert_type); + alert_reg &= ~BIT(alert_type); + } + + tcpci_tcpm_clear_status_register(&cfg->bus, TCPC_ALERT_STATUS, clear_flags); + tcpci_tcpm_get_status_register(&cfg->bus, TCPC_ALERT_STATUS, &alert_reg); + + /* If alert_reg is not 0 or the interrupt signal is still active */ + if ((alert_reg != 0) || gpio_pin_get_dt(&cfg->alert_gpio)) { + k_work_submit(work); + } +} + +void rt1715_init_work_cb(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct rt1715_data *data = CONTAINER_OF(dwork, struct rt1715_data, init_dwork); + + const struct rt1715_cfg *cfg = data->dev->config; + uint8_t power_reg = 0; + struct tcpc_chip_info chip_info; + int res; + + LOG_INF("Initializing RT1715 chip: %s", data->dev->name); + + /* Resets the chip */ + tcpci_write_reg8(&cfg->bus, RT1715_REG_SW_RST, RT1715_REG_SW_RST_EN); + k_msleep(5); + + res = tcpci_tcpm_get_status_register(&cfg->bus, TCPC_POWER_STATUS, (uint16_t *)&power_reg); + if (res != 0 || (power_reg & TCPC_REG_POWER_STATUS_UNINIT)) { + data->init_retries++; + + if (data->init_retries > CONFIG_USBC_TCPC_RT1715_INIT_RETRIES) { + LOG_ERR("Chip didn't respond"); + return; + } + + LOG_DBG("Postpone chip initialization %d", data->init_retries); + k_work_schedule_for_queue(&k_sys_work_q, &data->init_dwork, + K_MSEC(CONFIG_USBC_TCPC_RT1715_INIT_DELAY)); + + return; + } + + rt1715_tcpc_get_chip_info(data->dev, &chip_info); + LOG_INF("Initialized chip is: %04x:%04x:%04x", chip_info.vendor_id, chip_info.product_id, + chip_info.device_id); + + /* Exit shutdown mode */ + tcpci_update_reg8(&cfg->bus, RT1715_REG_LP_CTRL, RT1715_REG_LP_CTRL_SHUTDOWN_OFF, + RT1715_REG_LP_CTRL_SHUTDOWN_OFF); + + /* Enable ext messages */ + tcpci_update_reg8(&cfg->bus, RT1715_REG_LP_CTRL, RT1715_REG_LP_CTRL_ENEXTMSG, + RT1715_REG_LP_CTRL_ENEXTMSG); + + /* Disable idle mode */ + tcpci_update_reg8(&cfg->bus, RT1715_REG_LP_CTRL, RT1715_REG_LP_CTRL_AUTOIDLE_EN, 0); + + /* Initialize alert interrupt */ + gpio_pin_configure_dt(&cfg->alert_gpio, GPIO_INPUT); + + gpio_init_callback(&data->alert_cb, rt1715_alert_cb, BIT(cfg->alert_gpio.pin)); + gpio_add_callback(cfg->alert_gpio.port, &data->alert_cb); + gpio_pin_interrupt_configure_dt(&cfg->alert_gpio, GPIO_INT_EDGE_TO_ACTIVE); + + tcpci_init_alert_mask(data->dev); + data->initialized = true; + + /* Disable the vconn and open CC lines to reinitialize the communication with partner */ + rt1715_tcpc_set_vconn(data->dev, false); + rt1715_tcpc_set_cc(data->dev, TC_CC_OPEN); + + /* Check and clear any alert set after initialization */ + k_work_submit(&data->alert_work); +} + +static int rt1715_dev_init(const struct device *dev) +{ + const struct rt1715_cfg *cfg = dev->config; + struct rt1715_data *data = dev->data; + + if (!device_is_ready(cfg->bus.bus)) { + return -EIO; + } + + k_work_init_delayable(&data->init_dwork, rt1715_init_work_cb); + k_work_schedule_for_queue(&k_sys_work_q, &data->init_dwork, + K_MSEC(CONFIG_USBC_TCPC_RT1715_INIT_DELAY)); + + k_work_init(&data->alert_work, rt1715_alert_work_cb); + + return 0; +} + +#define RT1715_DRIVER_DATA_INIT(node) \ + { \ + .dev = DEVICE_DT_GET(node), \ + .init_retries = 0, \ + .cc_changed = true, \ + } + +#define VCONN_CTRL_GPIO(node) \ + .vconn_ctrl_gpio = COND_CODE_1(DT_INST_NODE_HAS_PROP(node, vconn_ctrl_gpios), \ + (GPIO_DT_SPEC_INST_GET(node, vconn_ctrl_gpios)), ({0})) + +#define VCONN_DISC_GPIO(node) \ + .vconn_disc_gpio = COND_CODE_1(DT_INST_NODE_HAS_PROP(node, vconn_disc_gpios), \ + (GPIO_DT_SPEC_INST_GET(node, vconn_disc_gpios)), ({0})) + +#define RT1715_DRIVER_CFG_INIT(node) \ + { \ + .bus = I2C_DT_SPEC_GET(node), \ + .alert_gpio = GPIO_DT_SPEC_GET(node, irq_gpios), \ + .transmit_retries = DT_PROP(node, transmit_retries), \ + VCONN_CTRL_GPIO(node), \ + VCONN_DISC_GPIO(node), \ + } + +#define RT1715_DRIVER_INIT(inst) \ + static struct rt1715_data drv_data_rt1715##inst = \ + RT1715_DRIVER_DATA_INIT(DT_DRV_INST(inst)); \ + static struct rt1715_cfg drv_cfg_rt1715##inst = RT1715_DRIVER_CFG_INIT(DT_DRV_INST(inst)); \ + DEVICE_DT_INST_DEFINE(inst, &rt1715_dev_init, NULL, &drv_data_rt1715##inst, \ + &drv_cfg_rt1715##inst, POST_KERNEL, CONFIG_USBC_TCPC_INIT_PRIORITY, \ + &rt1715_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(RT1715_DRIVER_INIT) diff --git a/drivers/usb_c/tcpc/rt1715.h b/drivers/usb_c/tcpc/rt1715.h new file mode 100644 index 000000000000000..823aa5f5326aad8 --- /dev/null +++ b/drivers/usb_c/tcpc/rt1715.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2024 Jianxiong Gu + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_USBC_TCPC_RT1715_H_ +#define ZEPHYR_DRIVERS_USBC_TCPC_RT1715_H_ + +#define RT1715_REG_SYS_CTRL_1 0x90 +/** VCONN OVP occurs and discharge path turn-on */ +#define RT1715_REG_SYS_CTRL_1_VCONN_DISCHARGE_EN BIT(5) +/** Low power mode Rd or Rp */ +#define RT1715_REG_SYS_CTRL_1_BMCIO_LPR_PRD BIT(4) +/** Low power mode enable */ +#define RT1715_REG_SYS_CTRL_1_BMCIO_LP_EN BIT(3) +/** BMCIO BandGap enable */ +#define RT1715_REG_SYS_CTRL_1_BMCIO_BG_EN BIT(2) +/** VBUS detection enable */ +#define RT1715_REG_SYS_CTRL_1_VBUS_DETECT_EN BIT(1) +/** 24M oscillator for BMC communication */ +#define RT1715_REG_SYS_CTRL_1_BMCIO_OSC_EN BIT(0) + +#define RT1715_REG_OCP 0x93 +/** VCONN over-current control selection */ +#define RT1715_REG_OCP_BMCIO_VCON_OCP GENMASK(7, 5) +#define RT1715_VCON_OCP_200MA (0 << 5) +#define RT1715_VCON_OCP_300MA (1 << 5) +#define RT1715_VCON_OCP_400MA (2 << 5) +#define RT1715_VCON_OCP_500MA (3 << 5) +#define RT1715_VCON_OCP_600MA (4 << 5) + +#define RT1715_REG_RT_ST 0x97 +/** If VBUS under 0.8V */ +#define RT1715_REG_RT_ST_VBUS_80 BIT(1) + +#define RT1715_REG_RT_INT 0x98 +/** Ra detach */ +#define RT1715_REG_RT_INT_RA_DETACH BIT(5) +/** VBUS under 0.8V */ +#define RT1715_REG_RT_INT_VBUS_80 BIT(1) +/** Low power mode exited */ +#define RT1715_REG_RT_INT_WAKEUP BIT(0) + +#define RT1715_REG_RT_INT_MASK 0x99 + +#define RT1715_REG_LP_CTRL 0x9B +/** Clock_300K divided from Clock_24M */ +#define RT1715_REG_LP_CTRL_CK_300K_SEL BIT(7) +/** Non-Shutdown mode */ +#define RT1715_REG_LP_CTRL_SHUTDOWN_OFF BIT(5) +/** Enable PD3.0 Extended message */ +#define RT1715_REG_LP_CTRL_ENEXTMSG BIT(4) +/** Auto enter idle mode enable */ +#define RT1715_REG_LP_CTRL_AUTOIDLE_EN BIT(3) +/** Enter idle mode timeout time */ +#define RT1715_REG_LP_CTRL_AUTOIDLE_TIMEOUT GENMASK(2, 0) +#define RT1715_AUTOIDLE_TIMEOUT_96P0_MS 7 +#define RT1715_AUTOIDLE_TIMEOUT_83P2_MS 6 +#define RT1715_AUTOIDLE_TIMEOUT_70P4_MS 5 +#define RT1715_AUTOIDLE_TIMEOUT_57P6_MS 4 +#define RT1715_AUTOIDLE_TIMEOUT_44P8_MS 3 +#define RT1715_AUTOIDLE_TIMEOUT_32P0_MS 2 +#define RT1715_AUTOIDLE_TIMEOUT_19P2_MS 1 +#define RT1715_AUTOIDLE_TIMEOUT_6P4_MS 0 + +#define RT1715_REG_SYS_WAKEUP 0x9F +/** Wakeup function enable */ +#define RT1715_REG_SYS_WAKEUP_EN BIT(7) + +#define RT1715_REG_SW_RST 0xA0 +/** Write 1 to trigger software reset */ +#define RT1715_REG_SW_RST_EN BIT(0) + +#define RT1715_REG_DRP_CTRL_1 0xA2 +/** + * The period a DRP will complete a Source to Sink and back advertisement. + * (Period = TDRP * 6.4 + 51.2ms) + */ +#define RT1715_REG_DRP_CTRL_1_TDRP GENMASK(3, 0) + +#define RT1715_REG_DRP_CTRL_2 0xA3 +/** + * The percent of time that a DRP will advertise Source during tDRP. + * (DUTY = (DCSRCDRP[9:0] + 1) / 1024) + */ +#define RT1715_REG_DRP_CTRL_2_DCSRCDRP GENMASK(9, 0) + +#endif /* ZEPHYR_DRIVERS_USBC_TCPC_UCPD_NUMAKER_H_ */ diff --git a/drivers/usb_c/tcpc/tcpci.c b/drivers/usb_c/tcpc/tcpci.c index ffac0bc8195db46..5b1ad5d07fbe5c1 100644 --- a/drivers/usb_c/tcpc/tcpci.c +++ b/drivers/usb_c/tcpc/tcpci.c @@ -446,3 +446,265 @@ int tcpci_tcpm_get_cc(const struct i2c_dt_spec *bus, enum tc_cc_voltage_state *c return 0; } + +int tcpci_tcpm_get_chip_info(const struct i2c_dt_spec *bus, struct tcpc_chip_info *chip_info) +{ + int ret; + + if (chip_info == NULL) { + return -EIO; + } + + ret = tcpci_read_reg16(bus, TCPC_REG_VENDOR_ID, &chip_info->vendor_id); + if (ret != 0) { + return ret; + } + + ret = tcpci_read_reg16(bus, TCPC_REG_PRODUCT_ID, &chip_info->product_id); + if (ret != 0) { + return ret; + } + + return tcpci_read_reg16(bus, TCPC_REG_BCD_DEV, &chip_info->device_id); +} + +int tcpci_tcpm_dump_std_reg(const struct i2c_dt_spec *bus) +{ + uint16_t value; + + for (unsigned int a = 0; a < TCPCI_STD_REGS_SIZE; a++) { + switch (tcpci_std_regs[a].size) { + case 1: + tcpci_read_reg8(bus, tcpci_std_regs[a].addr, (uint8_t *)&value); + LOG_INF("- %-30s(0x%02x) = 0x%02x", tcpci_std_regs[a].name, + tcpci_std_regs[a].addr, (uint8_t)value); + break; + case 2: + tcpci_read_reg16(bus, tcpci_std_regs[a].addr, &value); + LOG_INF("- %-30s(0x%02x) = 0x%04x", tcpci_std_regs[a].name, + tcpci_std_regs[a].addr, value); + break; + } + } + + return 0; +} + +int tcpci_tcpm_set_bist_test_mode(const struct i2c_dt_spec *bus, bool enable) +{ + return tcpci_update_reg8(bus, TCPC_REG_TCPC_CTRL, TCPC_REG_TCPC_CTRL_BIST_TEST_MODE, + enable ? TCPC_REG_TCPC_CTRL_BIST_TEST_MODE : 0); +} + +int tcpci_tcpm_transmit_data(const struct i2c_dt_spec *bus, struct pd_msg *msg, + const uint8_t retries) +{ + int reg = TCPC_REG_TX_BUFFER; + int rv; + int cnt = 4 * msg->header.number_of_data_objects; + + /* If not SOP* transmission, just write to the transmit register */ + if (msg->header.message_type >= NUM_SOP_STAR_TYPES) { + /* + * Per TCPCI spec, do not specify retry (although the TCPC + * should ignore retry field for these 3 types). + */ + return tcpci_write_reg8( + bus, TCPC_REG_TRANSMIT, + TCPC_REG_TRANSMIT_SET_WITHOUT_RETRY(msg->header.message_type)); + } + + if (cnt > 0) { + reg = TCPC_REG_TX_BUFFER; + /* TX_BYTE_CNT includes extra bytes for message header */ + cnt += sizeof(msg->header.raw_value); + + struct i2c_msg buf[3]; + + uint8_t tmp[2] = {TCPC_REG_TX_BUFFER, cnt}; + + buf[0].buf = tmp; + buf[0].len = 2; + buf[0].flags = I2C_MSG_WRITE; + + buf[1].buf = (uint8_t *)&msg->header.raw_value; + buf[1].len = sizeof(msg->header.raw_value); + buf[1].flags = I2C_MSG_WRITE; + + buf[2].buf = (uint8_t *)msg->data; + buf[2].len = msg->len; + buf[2].flags = I2C_MSG_WRITE | I2C_MSG_STOP; + + if (cnt > sizeof(msg->header.raw_value)) { + rv = i2c_transfer(bus->bus, buf, 3, bus->addr); + } else { + buf[1].flags |= I2C_MSG_STOP; + rv = i2c_transfer(bus->bus, buf, 2, bus->addr); + } + + /* If tcpc write fails, return error */ + if (rv) { + return rv; + } + } + + /* + * We always retry in TCPC hardware since the TCPM is too slow to + * respond within tRetry (~195 usec). + * + * The retry count used is dependent on the maximum PD revision + * supported at build time. + */ + rv = tcpci_write_reg8(bus, TCPC_REG_TRANSMIT, + TCPC_REG_TRANSMIT_SET_WITH_RETRY(retries, msg->type)); + + return rv; +} + +int tcpci_tcpm_select_rp_value(const struct i2c_dt_spec *bus, enum tc_rp_value rp) +{ + return tcpci_update_reg8(bus, TCPC_REG_ROLE_CTRL, TCPC_REG_ROLE_CTRL_RP_MASK, + TCPC_REG_ROLE_CTRL_SET(0, rp, 0, 0)); +} + +int tcpci_tcpm_get_rp_value(const struct i2c_dt_spec *bus, enum tc_rp_value *rp) +{ + uint8_t reg_value = 0; + int ret; + + ret = tcpci_read_reg8(bus, TCPC_REG_ROLE_CTRL, ®_value); + *rp = TCPC_REG_ROLE_CTRL_RP(reg_value); + + return ret; +} + +int tcpci_tcpm_set_cc(const struct i2c_dt_spec *bus, enum tc_cc_pull pull) +{ + return tcpci_update_reg8(bus, TCPC_REG_ROLE_CTRL, + TCPC_REG_ROLE_CTRL_CC1_MASK | TCPC_REG_ROLE_CTRL_CC2_MASK, + TCPC_REG_ROLE_CTRL_SET(0, 0, pull, pull)); +} + +int tcpci_tcpm_set_vconn(const struct i2c_dt_spec *bus, bool enable) +{ + return tcpci_update_reg8(bus, TCPC_REG_POWER_CTRL, TCPC_REG_POWER_CTRL_VCONN_EN, + enable ? TCPC_REG_POWER_CTRL_VCONN_EN : 0); +} + +int tcpci_tcpm_set_roles(const struct i2c_dt_spec *bus, enum pd_rev_type pd_rev, + enum tc_power_role power_role, enum tc_data_role data_role) +{ + return tcpci_update_reg8(bus, TCPC_REG_MSG_HDR_INFO, TCPC_REG_MSG_HDR_INFO_ROLES_MASK, + TCPC_REG_MSG_HDR_INFO_SET(pd_rev, data_role, power_role)); +} + +int tcpci_tcpm_set_drp_toggle(const struct i2c_dt_spec *bus, bool enable) +{ + return tcpci_update_reg8(bus, TCPC_REG_ROLE_CTRL, TCPC_REG_ROLE_CTRL_DRP_MASK, + TCPC_REG_ROLE_CTRL_SET(enable, 0, 0, 0)); +} + +int tcpci_tcpm_set_rx_type(const struct i2c_dt_spec *bus, uint8_t rx_type) +{ + return tcpci_write_reg8(bus, TCPC_REG_RX_DETECT, rx_type); +} + +int tcpci_tcpm_set_cc_polarity(const struct i2c_dt_spec *bus, enum tc_cc_polarity polarity) +{ + return tcpci_update_reg8( + bus, TCPC_REG_TCPC_CTRL, TCPC_REG_TCPC_CTRL_PLUG_ORIENTATION, + (polarity == TC_POLARITY_CC1) ? 0 : TCPC_REG_TCPC_CTRL_PLUG_ORIENTATION); +} + +int tcpci_tcpm_get_status_register(const struct i2c_dt_spec *bus, enum tcpc_status_reg reg, + uint16_t *status) +{ + switch (reg) { + case TCPC_ALERT_STATUS: + return tcpci_read_reg16(bus, TCPC_REG_ALERT, status); + case TCPC_CC_STATUS: + return tcpci_read_reg16(bus, TCPC_REG_CC_STATUS, status); + case TCPC_POWER_STATUS: + return tcpci_read_reg8(bus, TCPC_REG_POWER_STATUS, (uint8_t *)status); + case TCPC_FAULT_STATUS: + return tcpci_read_reg8(bus, TCPC_REG_FAULT_STATUS, (uint8_t *)status); + case TCPC_EXTENDED_STATUS: + return tcpci_read_reg8(bus, TCPC_REG_EXT_STATUS, (uint8_t *)status); + case TCPC_EXTENDED_ALERT_STATUS: + return tcpci_read_reg8(bus, TCPC_REG_ALERT_EXT, (uint8_t *)status); + default: + LOG_ERR("Not a TCPCI-specified reg address"); + return -EINVAL; + } +} + +int tcpci_tcpm_clear_status_register(const struct i2c_dt_spec *bus, enum tcpc_status_reg reg, + uint16_t mask) +{ + switch (reg) { + case TCPC_ALERT_STATUS: + return tcpci_write_reg16(bus, TCPC_REG_ALERT, mask); + case TCPC_CC_STATUS: + return tcpci_write_reg16(bus, TCPC_REG_CC_STATUS, mask); + case TCPC_POWER_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_POWER_STATUS, (uint8_t)mask); + case TCPC_FAULT_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_FAULT_STATUS, (uint8_t)mask); + case TCPC_EXTENDED_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_EXT_STATUS, (uint8_t)mask); + case TCPC_EXTENDED_ALERT_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_ALERT_EXT, (uint8_t)mask); + default: + LOG_ERR("Not a TCPCI-specified reg address"); + return -EINVAL; + } +} + +int tcpci_tcpm_mask_status_register(const struct i2c_dt_spec *bus, enum tcpc_status_reg reg, + uint16_t mask) +{ + switch (reg) { + case TCPC_ALERT_STATUS: + return tcpci_write_reg16(bus, TCPC_REG_ALERT_MASK, mask); + case TCPC_CC_STATUS: + LOG_ERR("CC_STATUS does not have a corresponding mask register"); + return -EINVAL; + case TCPC_POWER_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_POWER_STATUS_MASK, (uint8_t)mask); + case TCPC_FAULT_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_FAULT_STATUS_MASK, (uint8_t)mask); + case TCPC_EXTENDED_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_EXT_STATUS_MASK, (uint8_t)mask); + case TCPC_EXTENDED_ALERT_STATUS: + return tcpci_write_reg8(bus, TCPC_REG_ALERT_EXT_MASK, (uint8_t)mask); + default: + LOG_ERR("Not a TCPCI-specified reg address"); + return -EINVAL; + } +} + +int tcpci_get_snk_ctrl(const struct i2c_dt_spec *bus) +{ + uint8_t pwrsts; + int ret; + + ret = tcpci_read_reg8(bus, TCPC_REG_POWER_STATUS, &pwrsts); + if (ret != 0) { + return ret; + } + + return (pwrsts & TCPC_REG_POWER_STATUS_SINKING_VBUS) ? true : false; +} + +int tcpci_get_src_ctrl(const struct i2c_dt_spec *bus) +{ + uint8_t pwrsts; + int ret; + + ret = tcpci_read_reg8(bus, TCPC_REG_POWER_STATUS, &pwrsts); + if (ret != 0) { + return ret; + } + + return (pwrsts & TCPC_REG_POWER_STATUS_SOURCING_VBUS) ? true : false; +} diff --git a/dts/bindings/tcpc/richtek,rt1715.yaml b/dts/bindings/tcpc/richtek,rt1715.yaml new file mode 100644 index 000000000000000..14b12a8904ffad9 --- /dev/null +++ b/dts/bindings/tcpc/richtek,rt1715.yaml @@ -0,0 +1,76 @@ +# Copyright (c) 2024 Jianxiong Gu +# SPDX-License-Identifier: Apache-2.0 + +description: | + The Richtek RT1715 is a Type-C Port Controller (TCPC) chip. + + Example: + + ports { + #address-cells = <1>; + #size-cells = <0>; + port0: usbc-port@0 { + compatible = "usb-c-connector"; + reg = <0>; + tcpc = <&rt1715_tcpc0>; + vbus = <&vbus0>; + power-role = "sink"; + sink-pdos = ; + }; + }; + + vbus0: vbus { + compatible = "zephyr,usb-c-vbus-adc"; + status = "okay"; + io-channels = <&adc 2>; + output-ohms = <10000>; + full-ohms = <(100000 + 10000)>; + }; + + i2c1 { + status = "okay"; + clock-frequency = ; + rt1715_tcpc0: rt1715@4e { + compatible = "richtek,rt1715"; + reg = <0x4e>; + irq-gpios = <&gpio0 16 GPIO_ACTIVE_LOW>; + status = "okay"; + transmit-retries = <2>; + }; + }; + +compatible: "richtek,rt1715" + +include: [base.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + irq-gpios: + type: phandle-array + required: true + description: | + Interrupt GPIO pin connected from the chip. + + transmit-retries: + type: int + required: true + default: 2 + description: | + Maximum number of packet retransmissions done by TCPC. Valid values are <0, 3>. + This value is used to fill the Retry Counter part of the TCPCI Transmit register. + + vconn-ctrl-gpios: + type: phandle-array + description: | + GPIO pin for VCONN control. RT1715 does not have built-in VCONN power supply. If the + state of the VCONN power supply need to be toggled, this pin and a switchable power + supply are required. + + vconn-disc-gpios: + type: phandle-array + description: | + GPIO pin for VCONN discharge control. RT1715 does not have VCONN discharge capability. + If VCONN discharge is not needed, this pin does not need to be defined in the device + tree. Otherwise, this pin and a discharge path are required. diff --git a/include/zephyr/drivers/usb_c/tcpci_priv.h b/include/zephyr/drivers/usb_c/tcpci_priv.h index 8c5d67f59e3b48c..aad4fb80bbeac95 100644 --- a/include/zephyr/drivers/usb_c/tcpci_priv.h +++ b/include/zephyr/drivers/usb_c/tcpci_priv.h @@ -108,12 +108,158 @@ enum tcpc_alert tcpci_alert_reg_to_enum(uint16_t reg); * representing voltages state and partner detection status. * * @param bus I2C bus - * @param cc1 pointer to variable where detected CC1 voltage state will be stored - * @param cc2 pointer to variable where detected CC2 voltage state will be stored + * @param cc1 Pointer to variable where detected CC1 voltage state will be stored + * @param cc2 Pointer to variable where detected CC2 voltage state will be stored * @return -EINVAL if cc1 or cc2 pointer is NULL * @return int Status of I2C operation, 0 in case of success */ int tcpci_tcpm_get_cc(const struct i2c_dt_spec *bus, enum tc_cc_voltage_state *cc1, enum tc_cc_voltage_state *cc2); +/** + * @brief Function to retrieve information about the TCPCI chip. + * + * @param bus I2C bus + * @param chip_info Pointer to the structure where the chip information will be stored + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_get_chip_info(const struct i2c_dt_spec *bus, struct tcpc_chip_info *chip_info); + +/** + * @brief Function to dump the standard TCPCI registers. + * + * @param bus I2C bus + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_dump_std_reg(const struct i2c_dt_spec *bus); + +/** + * @brief Function to enable or disable the BIST (Built-In Self-Test) mode. + * + * @param bus I2C bus + * @param enable Boolean flag to enable (true) or disable (false) BIST mode + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_set_bist_test_mode(const struct i2c_dt_spec *bus, bool enable); + +/** + * @brief Function to transmit a PD (Power Delivery) message. The message is transmitted + * with a specified number of retries in case of failure. + * + * @param bus I2C bus + * @param msg Pointer to the PD message structure to be transmitted + * @param retries Number of retries in case of transmission failure + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_transmit_data(const struct i2c_dt_spec *bus, struct pd_msg *msg, + const uint8_t retries); + +/** + * @brief Function to select the Rp (Pull-up Resistor) value. + * + * @param bus I2C bus + * @param rp Enum representing the Rp value to be set + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_select_rp_value(const struct i2c_dt_spec *bus, enum tc_rp_value rp); + +/** + * @brief Function to get the currently selected Rp value. + * + * @param bus I2C bus + * @param rp Pointer to the variable where the Rp value will be stored + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_get_rp_value(const struct i2c_dt_spec *bus, enum tc_rp_value *rp); + +/** + * @brief Function to set the CC pull resistor and set the role as either Source or Sink. + * + * @param bus I2C bus + * @param pull Enum representing the CC pull resistor to be set + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_set_cc(const struct i2c_dt_spec *bus, enum tc_cc_pull pull); + +/** + * @brief Function to enable or disable TCPC auto dual role toggle. + * + * @param bus I2C bus + * @param enable Boolean flag to enable (true) or disable (false) DRP toggle mode + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_set_drp_toggle(const struct i2c_dt_spec *bus, bool enable); + +/** + * @brief Function to set the power and data role of the PD message header. + * + * @param bus I2C bus + * @param pd_rev Enum representing the USB−PD Specification Revision to be set + * @param power_role Enum representing the power role to be set + * @param data_role Enum representing the data role to be set + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_set_roles(const struct i2c_dt_spec *bus, enum pd_rev_type pd_rev, + enum tc_power_role power_role, enum tc_data_role data_role); + +/** + * @brief Function to set the RX type. + * + * @param bus I2C bus + * @param type Value representing the RX type to be set + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_set_rx_type(const struct i2c_dt_spec *bus, uint8_t type); + +/** + * @brief Function to set the polarity of the CC lines. + * + * @param bus I2C bus + * @param polarity Enum representing the CC polarity to be set + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_set_cc_polarity(const struct i2c_dt_spec *bus, enum tc_cc_polarity polarity); + +/** + * @brief Function to enable or disable VCONN. + * + * @param bus I2C bus + * @param enable Boolean flag to enable (true) or disable (false) VCONN + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_set_vconn(const struct i2c_dt_spec *bus, bool enable); + +/** + * @brief Function to get the status of a specific TCPCI status register. + * + * @param bus I2C bus + * @param reg Enum representing the status register to be read + * @param status Pointer to the variable where the status will be stored + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_get_status_register(const struct i2c_dt_spec *bus, enum tcpc_status_reg reg, + uint16_t *status); + +/** + * @brief Function to clear specific bits in a TCPCI status register. + * + * @param bus I2C bus + * @param reg Enum representing the status register to be cleared + * @param mask Bitmask specifying which bits to clear + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_clear_status_register(const struct i2c_dt_spec *bus, enum tcpc_status_reg reg, + uint16_t mask); + +/** + * @brief Function to set the mask of a TCPCI status register. + * + * @param bus I2C bus + * @param reg Enum representing the status register to be masked + * @param mask Bitmask specifying which bits to mask + * @return int Status of I2C operation, 0 in case of success + */ +int tcpci_tcpm_mask_status_register(const struct i2c_dt_spec *bus, enum tcpc_status_reg reg, + uint16_t mask); + #endif /* ZEPHYR_INCLUDE_DRIVERS_USBC_TCPCI_PRIV_H_ */ diff --git a/include/zephyr/drivers/usb_c/usbc_tcpc.h b/include/zephyr/drivers/usb_c/usbc_tcpc.h index 232906d710e5860..7f5f6ec81444dc8 100644 --- a/include/zephyr/drivers/usb_c/usbc_tcpc.h +++ b/include/zephyr/drivers/usb_c/usbc_tcpc.h @@ -83,6 +83,8 @@ enum tcpc_alert { * @brief TCPC Status register */ enum tcpc_status_reg { + /** The Altert register */ + TCPC_ALERT_STATUS, /** The CC Status register */ TCPC_CC_STATUS, /** The Power Status register */ @@ -118,17 +120,17 @@ struct tcpc_chip_info { }; }; -typedef int (*tcpc_vconn_control_cb_t)(const struct device *dev, - enum tc_cc_polarity pol, bool enable); -typedef int (*tcpc_vconn_discharge_cb_t)(const struct device *dev, - enum tc_cc_polarity pol, bool enable); +typedef int (*tcpc_vconn_control_cb_t)(const struct device *dev, enum tc_cc_polarity pol, + bool enable); +typedef int (*tcpc_vconn_discharge_cb_t)(const struct device *dev, enum tc_cc_polarity pol, + bool enable); typedef void (*tcpc_alert_handler_cb_t)(const struct device *dev, void *data, - enum tcpc_alert alert); + enum tcpc_alert alert); __subsystem struct tcpc_driver_api { int (*init)(const struct device *dev); int (*get_cc)(const struct device *dev, enum tc_cc_voltage_state *cc1, - enum tc_cc_voltage_state *cc2); + enum tc_cc_voltage_state *cc2); int (*select_rp_value)(const struct device *dev, enum tc_rp_value rp); int (*get_rp_value)(const struct device *dev, enum tc_rp_value *rp); int (*set_cc)(const struct device *dev, enum tc_cc_pull pull); @@ -137,7 +139,7 @@ __subsystem struct tcpc_driver_api { int (*vconn_discharge)(const struct device *dev, bool enable); int (*set_vconn)(const struct device *dev, bool enable); int (*set_roles)(const struct device *dev, enum tc_power_role power_role, - enum tc_data_role data_role); + enum tc_data_role data_role); int (*get_rx_pending_msg)(const struct device *dev, struct pd_msg *msg); int (*set_rx_enable)(const struct device *dev, bool enable); int (*set_cc_polarity)(const struct device *dev, enum tc_cc_polarity polarity); @@ -145,11 +147,11 @@ __subsystem struct tcpc_driver_api { int (*dump_std_reg)(const struct device *dev); void (*alert_handler_cb)(const struct device *dev, void *data, enum tcpc_alert alert); int (*get_status_register)(const struct device *dev, enum tcpc_status_reg reg, - int32_t *status); + uint32_t *status); int (*clear_status_register)(const struct device *dev, enum tcpc_status_reg reg, - uint32_t mask); + uint32_t mask); int (*mask_status_register)(const struct device *dev, enum tcpc_status_reg reg, - uint32_t mask); + uint32_t mask); int (*set_debug_accessory)(const struct device *dev, bool enable); int (*set_debug_detach)(const struct device *dev); int (*set_drp_toggle)(const struct device *dev, bool enable); @@ -162,7 +164,7 @@ __subsystem struct tcpc_driver_api { int (*sop_prime_enable)(const struct device *dev, bool enable); int (*set_bist_test_mode)(const struct device *dev, bool enable); int (*set_alert_handler_cb)(const struct device *dev, tcpc_alert_handler_cb_t handler, - void *data); + void *data); }; /** @@ -170,15 +172,13 @@ __subsystem struct tcpc_driver_api { */ static inline int tcpc_is_cc_rp(enum tc_cc_voltage_state cc) { - return (cc == TC_CC_VOLT_RP_DEF) || (cc == TC_CC_VOLT_RP_1A5) || - (cc == TC_CC_VOLT_RP_3A0); + return (cc == TC_CC_VOLT_RP_DEF) || (cc == TC_CC_VOLT_RP_1A5) || (cc == TC_CC_VOLT_RP_3A0); } /** * @brief Returns true if both CC lines are completely open */ -static inline int tcpc_is_cc_open(enum tc_cc_voltage_state cc1, - enum tc_cc_voltage_state cc2) +static inline int tcpc_is_cc_open(enum tc_cc_voltage_state cc1, enum tc_cc_voltage_state cc2) { return (cc1 < TC_CC_VOLT_RD) && (cc2 < TC_CC_VOLT_RD); } @@ -186,8 +186,7 @@ static inline int tcpc_is_cc_open(enum tc_cc_voltage_state cc1, /** * @brief Returns true if we detect the port partner is a snk debug accessory */ -static inline int tcpc_is_cc_snk_dbg_acc(enum tc_cc_voltage_state cc1, - enum tc_cc_voltage_state cc2) +static inline int tcpc_is_cc_snk_dbg_acc(enum tc_cc_voltage_state cc1, enum tc_cc_voltage_state cc2) { return cc1 == TC_CC_VOLT_RD && cc2 == TC_CC_VOLT_RD; } @@ -195,8 +194,7 @@ static inline int tcpc_is_cc_snk_dbg_acc(enum tc_cc_voltage_state cc1, /** * @brief Returns true if we detect the port partner is a src debug accessory */ -static inline int tcpc_is_cc_src_dbg_acc(enum tc_cc_voltage_state cc1, - enum tc_cc_voltage_state cc2) +static inline int tcpc_is_cc_src_dbg_acc(enum tc_cc_voltage_state cc1, enum tc_cc_voltage_state cc2) { return tcpc_is_cc_rp(cc1) && tcpc_is_cc_rp(cc2); } @@ -204,8 +202,7 @@ static inline int tcpc_is_cc_src_dbg_acc(enum tc_cc_voltage_state cc1, /** * @brief Returns true if the port partner is an audio accessory */ -static inline int tcpc_is_cc_audio_acc(enum tc_cc_voltage_state cc1, - enum tc_cc_voltage_state cc2) +static inline int tcpc_is_cc_audio_acc(enum tc_cc_voltage_state cc1, enum tc_cc_voltage_state cc2) { return cc1 == TC_CC_VOLT_RA && cc2 == TC_CC_VOLT_RA; } @@ -222,8 +219,7 @@ static inline int tcpc_is_cc_at_least_one_rd(enum tc_cc_voltage_state cc1, /** * @brief Returns true if the port partner is presenting Rd on only one CC line */ -static inline int tcpc_is_cc_only_one_rd(enum tc_cc_voltage_state cc1, - enum tc_cc_voltage_state cc2) +static inline int tcpc_is_cc_only_one_rd(enum tc_cc_voltage_state cc1, enum tc_cc_voltage_state cc2) { return tcpc_is_cc_at_least_one_rd(cc1, cc2) && cc1 != cc2; } @@ -239,11 +235,9 @@ static inline int tcpc_is_cc_only_one_rd(enum tc_cc_voltage_state cc1, */ static inline int tcpc_init(const struct device *dev) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; - __ASSERT(api->init != NULL, - "Callback pointer should not be NULL"); + __ASSERT(api->init != NULL, "Callback pointer should not be NULL"); return api->init(dev); } @@ -259,12 +253,10 @@ static inline int tcpc_init(const struct device *dev) * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_get_cc(const struct device *dev, - enum tc_cc_voltage_state *cc1, +static inline int tcpc_get_cc(const struct device *dev, enum tc_cc_voltage_state *cc1, enum tc_cc_voltage_state *cc2) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->get_cc == NULL) { return -ENOSYS; @@ -285,8 +277,7 @@ static inline int tcpc_get_cc(const struct device *dev, */ static inline int tcpc_select_rp_value(const struct device *dev, enum tc_rp_value rp) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->select_rp_value == NULL) { return -ENOSYS; @@ -307,8 +298,7 @@ static inline int tcpc_select_rp_value(const struct device *dev, enum tc_rp_valu */ static inline int tcpc_get_rp_value(const struct device *dev, enum tc_rp_value *rp) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->get_rp_value == NULL) { return -ENOSYS; @@ -328,11 +318,9 @@ static inline int tcpc_get_rp_value(const struct device *dev, enum tc_rp_value * */ static inline int tcpc_set_cc(const struct device *dev, enum tc_cc_pull pull) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; - __ASSERT(api->set_cc != NULL, - "Callback pointer should not be NULL"); + __ASSERT(api->set_cc != NULL, "Callback pointer should not be NULL"); return api->set_cc(dev, pull); } @@ -347,14 +335,11 @@ static inline int tcpc_set_cc(const struct device *dev, enum tc_cc_pull pull) * @param dev Runtime device structure * @param vconn_cb pointer to the callback function that controls vconn */ -static inline void tcpc_set_vconn_cb(const struct device *dev, - tcpc_vconn_control_cb_t vconn_cb) +static inline void tcpc_set_vconn_cb(const struct device *dev, tcpc_vconn_control_cb_t vconn_cb) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; - __ASSERT(api->set_vconn_cb != NULL, - "Callback pointer should not be NULL"); + __ASSERT(api->set_vconn_cb != NULL, "Callback pointer should not be NULL"); api->set_vconn_cb(dev, vconn_cb); } @@ -370,13 +355,11 @@ static inline void tcpc_set_vconn_cb(const struct device *dev, * @param cb pointer to the callback function that discharges vconn */ static inline void tcpc_set_vconn_discharge_cb(const struct device *dev, - tcpc_vconn_discharge_cb_t cb) + tcpc_vconn_discharge_cb_t cb) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; - __ASSERT(api->set_vconn_discharge_cb != NULL, - "Callback pointer should not be NULL"); + __ASSERT(api->set_vconn_discharge_cb != NULL, "Callback pointer should not be NULL"); api->set_vconn_discharge_cb(dev, cb); } @@ -396,8 +379,7 @@ static inline void tcpc_set_vconn_discharge_cb(const struct device *dev, */ static inline int tcpc_vconn_discharge(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->vconn_discharge == NULL) { return -ENOSYS; @@ -421,8 +403,7 @@ static inline int tcpc_vconn_discharge(const struct device *dev, bool enable) */ static inline int tcpc_set_vconn(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_vconn == NULL) { return -ENOSYS; @@ -444,12 +425,10 @@ static inline int tcpc_set_vconn(const struct device *dev, bool enable) * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_set_roles(const struct device *dev, - enum tc_power_role power_role, +static inline int tcpc_set_roles(const struct device *dev, enum tc_power_role power_role, enum tc_data_role data_role) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_roles == NULL) { return -ENOSYS; @@ -493,8 +472,7 @@ static inline int tcpc_get_rx_pending_msg(const struct device *dev, struct pd_ms */ static inline int tcpc_set_rx_enable(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_rx_enable == NULL) { return -ENOSYS; @@ -512,14 +490,11 @@ static inline int tcpc_set_rx_enable(const struct device *dev, bool enable) * @retval 0 on success * @retval -EIO on failure */ -static inline int tcpc_set_cc_polarity(const struct device *dev, - enum tc_cc_polarity polarity) +static inline int tcpc_set_cc_polarity(const struct device *dev, enum tc_cc_polarity polarity) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; - __ASSERT(api->set_cc_polarity != NULL, - "Callback pointer should not be NULL"); + __ASSERT(api->set_cc_polarity != NULL, "Callback pointer should not be NULL"); return api->set_cc_polarity(dev, polarity); } @@ -534,11 +509,9 @@ static inline int tcpc_set_cc_polarity(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_transmit_data(const struct device *dev, - struct pd_msg *msg) +static inline int tcpc_transmit_data(const struct device *dev, struct pd_msg *msg) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->transmit_data == NULL) { return -ENOSYS; @@ -558,8 +531,7 @@ static inline int tcpc_transmit_data(const struct device *dev, */ static inline int tcpc_dump_std_reg(const struct device *dev) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->dump_std_reg == NULL) { return -ENOSYS; @@ -582,14 +554,11 @@ static inline int tcpc_dump_std_reg(const struct device *dev) * @retval -EINVAL on failure */ static inline int tcpc_set_alert_handler_cb(const struct device *dev, - tcpc_alert_handler_cb_t handler, - void *data) + tcpc_alert_handler_cb_t handler, void *data) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; - __ASSERT(api->set_alert_handler_cb != NULL, - "Callback pointer should not be NULL"); + __ASSERT(api->set_alert_handler_cb != NULL, "Callback pointer should not be NULL"); return api->set_alert_handler_cb(dev, handler, data); } @@ -605,12 +574,10 @@ static inline int tcpc_set_alert_handler_cb(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_get_status_register(const struct device *dev, - enum tcpc_status_reg reg, +static inline int tcpc_get_status_register(const struct device *dev, enum tcpc_status_reg reg, int32_t *status) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->get_status_register == NULL) { return -ENOSYS; @@ -631,12 +598,10 @@ static inline int tcpc_get_status_register(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_clear_status_register(const struct device *dev, - enum tcpc_status_reg reg, +static inline int tcpc_clear_status_register(const struct device *dev, enum tcpc_status_reg reg, uint32_t mask) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->clear_status_register == NULL) { return -ENOSYS; @@ -657,12 +622,10 @@ static inline int tcpc_clear_status_register(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_mask_status_register(const struct device *dev, - enum tcpc_status_reg reg, +static inline int tcpc_mask_status_register(const struct device *dev, enum tcpc_status_reg reg, uint32_t mask) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->mask_status_register == NULL) { return -ENOSYS; @@ -681,11 +644,9 @@ static inline int tcpc_mask_status_register(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_set_debug_accessory(const struct device *dev, - bool enable) +static inline int tcpc_set_debug_accessory(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_debug_accessory == NULL) { return -ENOSYS; @@ -705,8 +666,7 @@ static inline int tcpc_set_debug_accessory(const struct device *dev, */ static inline int tcpc_set_debug_detach(const struct device *dev) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_debug_detach == NULL) { return -ENOSYS; @@ -727,8 +687,7 @@ static inline int tcpc_set_debug_detach(const struct device *dev) */ static inline int tcpc_set_drp_toggle(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_drp_toggle == NULL) { return -ENOSYS; @@ -748,8 +707,7 @@ static inline int tcpc_set_drp_toggle(const struct device *dev, bool enable) */ static inline int tcpc_get_snk_ctrl(const struct device *dev) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->get_snk_ctrl == NULL) { return -ENOSYS; @@ -788,8 +746,7 @@ static inline int tcpc_set_snk_ctrl(const struct device *dev, bool enable) */ static inline int tcpc_get_src_ctrl(const struct device *dev) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->get_src_ctrl == NULL) { return -ENOSYS; @@ -828,11 +785,9 @@ static inline int tcpc_set_src_ctrl(const struct device *dev, bool enable) * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_set_bist_test_mode(const struct device *dev, - bool enable) +static inline int tcpc_set_bist_test_mode(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_bist_test_mode == NULL) { return -ENOSYS; @@ -851,11 +806,9 @@ static inline int tcpc_set_bist_test_mode(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_get_chip_info(const struct device *dev, - struct tcpc_chip_info *chip_info) +static inline int tcpc_get_chip_info(const struct device *dev, struct tcpc_chip_info *chip_info) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->get_chip_info == NULL) { return -ENOSYS; @@ -874,11 +827,9 @@ static inline int tcpc_get_chip_info(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_set_low_power_mode(const struct device *dev, - bool enable) +static inline int tcpc_set_low_power_mode(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->set_low_power_mode == NULL) { return -ENOSYS; @@ -897,11 +848,9 @@ static inline int tcpc_set_low_power_mode(const struct device *dev, * @retval -EIO on failure * @retval -ENOSYS if not implemented */ -static inline int tcpc_sop_prime_enable(const struct device *dev, - bool enable) +static inline int tcpc_sop_prime_enable(const struct device *dev, bool enable) { - const struct tcpc_driver_api *api = - (const struct tcpc_driver_api *)dev->api; + const struct tcpc_driver_api *api = (const struct tcpc_driver_api *)dev->api; if (api->sop_prime_enable == NULL) { return -ENOSYS;