| /* |
| * Copyright 2023 Google LLC |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| /** |
| * @file |
| * @brief USB Type-C Power Path Controller device API |
| * |
| */ |
| |
| #ifndef ZEPHYR_INCLUDE_DRIVERS_USBC_USBC_PPC_H_ |
| #define ZEPHYR_INCLUDE_DRIVERS_USBC_USBC_PPC_H_ |
| |
| #include <zephyr/types.h> |
| #include <zephyr/device.h> |
| #include <errno.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** Type of event being notified by Power Path Controller */ |
| enum usbc_ppc_event { |
| /** Exit from dead-battery mode failed */ |
| USBC_PPC_EVENT_DEAD_BATTERY_ERROR = 0, |
| |
| /** Overvoltage detected while being in a source role */ |
| USBC_PPC_EVENT_SRC_OVERVOLTAGE, |
| /** Reverse current detected while being in a source role */ |
| USBC_PPC_EVENT_SRC_REVERSE_CURRENT, |
| /** Overcurrent detected while being in a source role */ |
| USBC_PPC_EVENT_SRC_OVERCURRENT, |
| /** VBUS short detected while being in a source role */ |
| USBC_PPC_EVENT_SRC_SHORT, |
| |
| /** Chip over temperature detected */ |
| USBC_PPC_EVENT_OVER_TEMPERATURE, |
| /** Sink and source paths enabled simultaneously */ |
| USBC_PPC_EVENT_BOTH_SNKSRC_ENABLED, |
| |
| /** Reverse current detected while being in a sink role */ |
| USBC_PPC_EVENT_SNK_REVERSE_CURRENT, |
| /** VBUS short detected while being in a sink role */ |
| USBC_PPC_EVENT_SNK_SHORT, |
| /** Overvoltage detected while being in a sink role */ |
| USBC_PPC_EVENT_SNK_OVERVOLTAGE, |
| }; |
| |
| typedef void (*usbc_ppc_event_cb_t)(const struct device *dev, void *data, enum usbc_ppc_event ev); |
| |
| /** Structure with pointers to the functions implemented by driver */ |
| __subsystem struct usbc_ppc_drv { |
| int (*is_dead_battery_mode)(const struct device *dev); |
| int (*exit_dead_battery_mode)(const struct device *dev); |
| int (*is_vbus_source)(const struct device *dev); |
| int (*is_vbus_sink)(const struct device *dev); |
| int (*set_snk_ctrl)(const struct device *dev, bool enable); |
| int (*set_src_ctrl)(const struct device *dev, bool enable); |
| int (*set_vbus_discharge)(const struct device *dev, bool enable); |
| int (*is_vbus_present)(const struct device *dev); |
| int (*set_event_handler)(const struct device *dev, usbc_ppc_event_cb_t handler, void *data); |
| int (*dump_regs)(const struct device *dev); |
| }; |
| |
| /* |
| * API functions |
| */ |
| |
| /** |
| * @brief Check if PPC is in the dead battery mode |
| * |
| * @param dev PPC device structure |
| * @retval 1 if PPC is in the dead battery mode |
| * @retval 0 if PPC is not in the dead battery mode |
| * @retval -EIO if I2C communication failed |
| * @retval -ENOSYS if this function is not supported by the driver |
| */ |
| static inline int ppc_is_dead_battery_mode(const struct device *dev) |
| { |
| const struct usbc_ppc_drv *api = (const struct usbc_ppc_drv *)dev->api; |
| |
| if (api->is_dead_battery_mode == NULL) { |
| return -ENOSYS; |
| } |
| |
| return api->is_dead_battery_mode(dev); |
| } |
| |
| /** |
| * @brief Request the PPC to exit from the dead battery mode |
| * Return from this call doesn't mean that the PPC is not in the dead battery anymore. |
| * In the case of error, the driver should execute the callback with |
| * USBC_PPC_EVENT_DEAD_BATTERY_ERROR enum. To check if the PPC disabled the dead battery mode, |
| * the call to ppc_is_dead_battery_mode should be done. |
| * |
| * @param dev PPC device structure |
| * @retval 0 if request was successfully sent |
| * @retval -EIO if I2C communication failed |
| * @retval -ENOSYS if this function is not supported by the driver |
| */ |
| static inline int ppc_exit_dead_battery_mode(const struct device *dev) |
| { |
| const struct usbc_ppc_drv *api = (const struct usbc_ppc_drv *)dev->api; |
| |
| if (api->exit_dead_battery_mode == NULL) { |
| return -ENOSYS; |
| } |
| |
| return api->exit_dead_battery_mode(dev); |
| } |
| |
| /** |
| * @brief Check if the PPC is sourcing the VBUS |
| * |
| * @param dev PPC device structure |
| * @retval 1 if the PPC is sourcing the VBUS |
| * @retval 0 if the PPC is not sourcing the VBUS |
| * @retval -EIO if I2C communication failed |
| * @retval -ENOSYS if this function is not supported by the driver |
| */ |
| static inline int ppc_is_vbus_source(const struct device *dev) |
| { |
| const struct usbc_ppc_drv *api = (const struct usbc_ppc_drv *)dev->api; |
| |
| if (api->is_vbus_source == NULL) { |
| return -ENOSYS; |
| } |
| |
| return api->is_vbus_source(dev); |
| } |
| |
| /** |
| * @brief Check if the PPC is sinking the VBUS |
| * |
| * @param dev PPC device structure |
| * @retval 1 if the PPC is sinking the VBUS |
| * @retval 0 if the PPC is not sinking the VBUS |
| * @retval -EIO if I2C communication failed |
| * @retval -ENOSYS if this function is not supported by the driver |
| */ |
| static inline int ppc_is_vbus_sink(const struct device *dev) |
| { |
| const struct usbc_ppc_drv *api = (const struct usbc_ppc_drv *)dev->api; |
| |
| if (api->is_vbus_sink == NULL) { |
| return -ENOSYS; |
| } |
| |
| return api->is_vbus_sink(dev); |
| } |
| |
| /** |
| * @brief Set the state of VBUS sinking |
| * |
| * @param dev PPC device structure |
| * @param enable True if sinking VBUS should be enabled, false if should be disabled |
| * @retval 0 if success |
| * @retval -EIO if I2C communication failed |
| * @retval -ENOSYS if this function is not supported by the driver |
| */ |
| static inline int ppc_set_snk_ctrl(const struct device *dev, bool enable) |
| { |
| const struct usbc_ppc_drv *api = (const struct usbc_ppc_drv *)dev->api; |
| |
| if (api->set_snk_ctrl == NULL) { |
| return -ENOSYS; |
| } |
| |
| return api->set_snk_ctrl(dev, enable); |
| } |
| |
| /** |
| * @brief Set the state of VBUS sourcing |
| * |
| * @param dev PPC device structure |
| * @param enable True if sourcing VBUS should be enabled, false if should be disabled |
| * @retval 0 if success |
| * @retval -EIO if I2C communication failed |
| * @retval -ENOSYS if this function is not supported by the driver |
| */ |
| static inline int ppc_set_src_ctrl(const struct device *dev, bool enable) |
| { |
| const struct usbc_ppc_drv *api = (const struct usbc_ppc_drv *)dev->api; |
| |
| if (api->set_src_ctrl == NULL) { |
| return -ENOSYS; |
| } |
| |
| return api->set_src_ctrl(dev, enable); |
| } |
| |
| /** |
| * @brief Set the state of VBUS discharging |
| * |
| * @param dev PPC device structure |
| * @param enable True if VBUS discharging should be enabled, false if should be disabled |
| * @retval 0 if success |
| * @retval -EIO if I2C communication failed |
| * @retval -ENOSYS if this function is not supported by the driver |
| */ |
| static inline int ppc_set_vbus_discharge(const struct device *dev, bool enable) |
| { |
| const struct usbc_ppc_drv *api = (const struct usbc_ppc_drv *)dev->api; |
| |
| if (api->set_vbus_discharge == NULL) { |
| return -ENOSYS; |
| } |
| |
| return api->set_vbus_discharge(dev, enable); |
| } |
| |
| /** |
| * @brief Check if VBUS is present |
| * |
| * @param dev PPC device structure |
| * @retval 1 if VBUS voltage is present |
| * @retval 0 if no VBUS voltage is detected |
| * @retval -EIO if I2C communication failed |
| * @retval -ENOSYS if this function is not supported by the driver |
| */ |
| static inline int ppc_is_vbus_present(const struct device *dev) |
| { |
| const struct usbc_ppc_drv *api = (const struct usbc_ppc_drv *)dev->api; |
| |
| if (api->is_vbus_present == NULL) { |
| return -ENOSYS; |
| } |
| |
| return api->is_vbus_present(dev); |
| } |
| |
| /** |
| * @brief Set the callback used to notify about PPC events |
| * |
| * @param dev PPC device structure |
| * @param handler Handler that will be called with events notifications |
| * @param data Pointer used as an argument to the callback |
| * @retval 0 if success |
| * @retval -ENOSYS if this function is not supported by the driver |
| */ |
| static inline int ppc_set_event_handler(const struct device *dev, |
| usbc_ppc_event_cb_t handler, void *data) |
| { |
| const struct usbc_ppc_drv *api = (const struct usbc_ppc_drv *)dev->api; |
| |
| if (api->set_event_handler == NULL) { |
| return -ENOSYS; |
| } |
| |
| return api->set_event_handler(dev, handler, data); |
| } |
| |
| /** |
| * @brief Print the values or PPC registers |
| * |
| * @param dev PPC device structure |
| * @retval 0 if success |
| * @retval -EIO if I2C communication failed |
| * @retval -ENOSYS if this function is not supported by the driver |
| */ |
| static inline int ppc_dump_regs(const struct device *dev) |
| { |
| const struct usbc_ppc_drv *api = (const struct usbc_ppc_drv *)dev->api; |
| |
| if (api->dump_regs == NULL) { |
| return -ENOSYS; |
| } |
| |
| return api->dump_regs(dev); |
| } |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* ZEPHYR_INCLUDE_DRIVERS_USBC_USBC_PPC_H_ */ |