/* * Copyright 2023 Cirrus Logic, Inc. * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Charger APIs */ #ifndef ZEPHYR_INCLUDE_DRIVERS_CHARGER_H_ #define ZEPHYR_INCLUDE_DRIVERS_CHARGER_H_ /** * @brief Charger Interface * @defgroup charger_interface Charger Interface * @ingroup io_interfaces * @{ */ #include #include #include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** * @brief Runtime Dynamic Battery Parameters */ enum charger_property { /** Indicates if external supply is present for the charger. */ /** Value should be of type enum charger_online */ CHARGER_PROP_ONLINE = 0, /** Reports whether or not a battery is present. */ /** Value should be of type bool*/ CHARGER_PROP_PRESENT, /** Represents the charging status of the charger. */ /** Value should be of type enum charger_status */ CHARGER_PROP_STATUS, /** Represents the charging algo type of the charger. */ /** Value should be of type enum charger_charge_type */ CHARGER_PROP_CHARGE_TYPE, /** Represents the health of the charger. */ /** Value should be of type enum charger_health */ CHARGER_PROP_HEALTH, /** Configuration of current sink used for charging in µA */ CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA, /** Configuration of current sink used for conditioning in µA */ CHARGER_PROP_PRECHARGE_CURRENT_UA, /** Configuration of charge termination target in µA */ CHARGER_PROP_CHARGE_TERM_CURRENT_UA, /** Configuration of charge voltage regulation target in µV */ CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV, /** * Configuration of the input current regulation target in µA * * This value is a rising current threshold that is regulated by reducing the charge * current output */ CHARGER_PROP_INPUT_REGULATION_CURRENT_UA, /** * Configuration of the input voltage regulation target in µV * * This value is a falling voltage threshold that is regulated by reducing the charge * current output */ CHARGER_PROP_INPUT_REGULATION_VOLTAGE_UV, /** * Configuration to issue a notification to the system based on the input current * level and timing * * Value should be of type struct charger_current_notifier */ CHARGER_PROP_INPUT_CURRENT_NOTIFICATION, /** * Configuration to issue a notification to the system based on the battery discharge * current level and timing * * Value should be of type struct charger_current_notifier */ CHARGER_PROP_DISCHARGE_CURRENT_NOTIFICATION, /** * Configuration of the falling system voltage threshold where a notification * is issued to the system, measured in µV */ CHARGER_PROP_SYSTEM_VOLTAGE_NOTIFICATION_UV, /** * Configuration to issue a notification to the system based on the charger status change * * Value should be of type charger_status_notifier_t */ CHARGER_PROP_STATUS_NOTIFICATION, /** * Configuration to issue a notification to the system based on the charger online change * * Value should be of type charger_online_notifier_t */ CHARGER_PROP_ONLINE_NOTIFICATION, /** Reserved to demark end of common charger properties */ CHARGER_PROP_COMMON_COUNT, /** * Reserved to demark downstream custom properties - use this value as the actual value may * change over future versions of this API */ CHARGER_PROP_CUSTOM_BEGIN = CHARGER_PROP_COMMON_COUNT + 1, /** Reserved to demark end of valid enum properties */ CHARGER_PROP_MAX = UINT16_MAX, }; /** * @typedef charger_prop_t * @brief A charger property's identifier * * See charger_property for a list of identifiers */ typedef uint16_t charger_prop_t; /** * @brief External supply states */ enum charger_online { /** External supply not present */ CHARGER_ONLINE_OFFLINE = 0, /** External supply is present and of fixed output */ CHARGER_ONLINE_FIXED, /** External supply is present and of programmable output*/ CHARGER_ONLINE_PROGRAMMABLE, }; /** * @brief Charging states */ enum charger_status { /** Charging device state is unknown */ CHARGER_STATUS_UNKNOWN = 0, /** Charging device is charging a battery */ CHARGER_STATUS_CHARGING, /** Charging device is not able to charge a battery */ CHARGER_STATUS_DISCHARGING, /** Charging device is not charging a battery */ CHARGER_STATUS_NOT_CHARGING, /** The battery is full and the charging device will not attempt charging */ CHARGER_STATUS_FULL, }; /** * @brief Charge algorithm types */ enum charger_charge_type { /** Charge type is unknown */ CHARGER_CHARGE_TYPE_UNKNOWN = 0, /** Charging is not occurring */ CHARGER_CHARGE_TYPE_NONE, /** * Charging is occurring at the slowest desired charge rate, * typically for battery detection or preconditioning */ CHARGER_CHARGE_TYPE_TRICKLE, /** Charging is occurring at the fastest desired charge rate */ CHARGER_CHARGE_TYPE_FAST, /** Charging is occurring at a moderate charge rate */ CHARGER_CHARGE_TYPE_STANDARD, /* * Charging is being dynamically adjusted by the charger device */ CHARGER_CHARGE_TYPE_ADAPTIVE, /* * Charging is occurring at a reduced charge rate to preserve * battery health */ CHARGER_CHARGE_TYPE_LONGLIFE, /* * The charger device is being bypassed and the power conversion * is being handled externally, typically by a "smart" wall adaptor */ CHARGER_CHARGE_TYPE_BYPASS, }; /** * @brief Charger health conditions * * These conditions determine the ability to, or the rate of, charge */ enum charger_health { /** Charger health condition is unknown */ CHARGER_HEALTH_UNKNOWN = 0, /** Charger health condition is good */ CHARGER_HEALTH_GOOD, /** The charger device is overheated */ CHARGER_HEALTH_OVERHEAT, /** The battery voltage has exceeded its overvoltage threshold */ CHARGER_HEALTH_OVERVOLTAGE, /** * The battery or charger device is experiencing an unspecified * failure. */ CHARGER_HEALTH_UNSPEC_FAILURE, /** The battery temperature is below the "cold" threshold */ CHARGER_HEALTH_COLD, /** The charger device's watchdog timer has expired */ CHARGER_HEALTH_WATCHDOG_TIMER_EXPIRE, /** The charger device's safety timer has expired */ CHARGER_HEALTH_SAFETY_TIMER_EXPIRE, /** The charger device requires calibration */ CHARGER_HEALTH_CALIBRATION_REQUIRED, /** The battery temperature is in the "warm" range */ CHARGER_HEALTH_WARM, /** The battery temperature is in the "cool" range */ CHARGER_HEALTH_COOL, /** The battery temperature is below the "hot" threshold */ CHARGER_HEALTH_HOT, /** The charger device does not detect a battery */ CHARGER_HEALTH_NO_BATTERY, }; /** * @brief Charger severity levels for system notifications */ enum charger_notification_severity { /** Most severe level, typically triggered instantaneously */ CHARGER_SEVERITY_PEAK = 0, /** More severe than the warning level, less severe than peak */ CHARGER_SEVERITY_CRITICAL, /** Base severity level */ CHARGER_SEVERITY_WARNING, }; /** * @brief The input current thresholds for the charger to notify the system */ struct charger_current_notifier { /** The severity of the notification where CHARGER_SEVERITY_PEAK is the most severe */ uint8_t severity; /** The current threshold to be exceeded */ uint32_t current_ua; /** The duration of excess current before notifying the system */ uint32_t duration_us; }; /** * @brief The charger status change callback to notify the system * * @param status Current charging state */ typedef void (*charger_status_notifier_t)(enum charger_status status); /** * @brief The charger online change callback to notify the system * * @param online Current external supply state */ typedef void (*charger_online_notifier_t)(enum charger_online online); /** * @brief container for a charger_property value * */ union charger_propval { /* Fields have the format: */ /* CHARGER_PROPERTY_FIELD */ /* type property_field; */ /** CHARGER_PROP_ONLINE */ enum charger_online online; /** CHARGER_PROP_PRESENT */ bool present; /** CHARGER_PROP_STATUS */ enum charger_status status; /** CHARGER_PROP_CHARGE_TYPE */ enum charger_charge_type charge_type; /** CHARGER_PROP_HEALTH */ enum charger_health health; /** CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA */ uint32_t const_charge_current_ua; /** CHARGER_PROP_PRECHARGE_CURRENT_UA */ uint32_t precharge_current_ua; /** CHARGER_PROP_CHARGE_TERM_CURRENT_UA */ uint32_t charge_term_current_ua; /** CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV */ uint32_t const_charge_voltage_uv; /** CHARGER_PROP_INPUT_REGULATION_CURRENT_UA */ uint32_t input_current_regulation_current_ua; /** CHARGER_PROP_INPUT_REGULATION_VOLTAGE_UV */ uint32_t input_voltage_regulation_voltage_uv; /** CHARGER_PROP_INPUT_CURRENT_NOTIFICATION */ struct charger_current_notifier input_current_notification; /** CHARGER_PROP_DISCHARGE_CURRENT_NOTIFICATION */ struct charger_current_notifier discharge_current_notification; /** CHARGER_PROP_SYSTEM_VOLTAGE_NOTIFICATION_UV */ uint32_t system_voltage_notification; /** CHARGER_PROP_STATUS_NOTIFICATION */ charger_status_notifier_t status_notification; /** CHARGER_PROP_ONLINE_NOTIFICATION */ charger_online_notifier_t online_notification; }; /** * @typedef charger_get_property_t * @brief Callback API for getting a charger property. * * See charger_get_property() for argument description */ typedef int (*charger_get_property_t)(const struct device *dev, const charger_prop_t prop, union charger_propval *val); /** * @typedef charger_set_property_t * @brief Callback API for setting a charger property. * * See charger_set_property() for argument description */ typedef int (*charger_set_property_t)(const struct device *dev, const charger_prop_t prop, const union charger_propval *val); /** * @typedef charger_charge_enable_t * @brief Callback API enabling or disabling a charge cycle. * * See charger_charge_enable() for argument description */ typedef int (*charger_charge_enable_t)(const struct device *dev, const bool enable); /** * @brief Charging device API * * Caching is entirely on the onus of the client */ __subsystem struct charger_driver_api { charger_get_property_t get_property; charger_set_property_t set_property; charger_charge_enable_t charge_enable; }; /** * @brief Fetch a battery charger property * * @param dev Pointer to the battery charger device * @param prop Charger property to get * @param val Pointer to charger_propval union * * @retval 0 if successful * @retval < 0 if getting property failed */ __syscall int charger_get_prop(const struct device *dev, const charger_prop_t prop, union charger_propval *val); static inline int z_impl_charger_get_prop(const struct device *dev, const charger_prop_t prop, union charger_propval *val) { const struct charger_driver_api *api = (const struct charger_driver_api *)dev->api; return api->get_property(dev, prop, val); } /** * @brief Set a battery charger property * * @param dev Pointer to the battery charger device * @param prop Charger property to set * @param val Pointer to charger_propval union * * @retval 0 if successful * @retval < 0 if setting property failed */ __syscall int charger_set_prop(const struct device *dev, const charger_prop_t prop, const union charger_propval *val); static inline int z_impl_charger_set_prop(const struct device *dev, const charger_prop_t prop, const union charger_propval *val) { const struct charger_driver_api *api = (const struct charger_driver_api *)dev->api; return api->set_property(dev, prop, val); } /** * @brief Enable or disable a charge cycle * * @param dev Pointer to the battery charger device * @param enable true enables a charge cycle, false disables a charge cycle * * @retval 0 if successful * @retval -EIO if communication with the charger failed * @retval -EINVAL if the conditions for initiating charging are invalid */ __syscall int charger_charge_enable(const struct device *dev, const bool enable); static inline int z_impl_charger_charge_enable(const struct device *dev, const bool enable) { const struct charger_driver_api *api = (const struct charger_driver_api *)dev->api; return api->charge_enable(dev, enable); } /** * @} */ #ifdef __cplusplus } #endif /* __cplusplus */ #include #endif /* ZEPHYR_INCLUDE_DRIVERS_CHARGER_H_ */