/* * Copyright (c) 2022 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_DRIVERS_SMBUS_SMBUS_UTILS_H_ #define ZEPHYR_DRIVERS_SMBUS_SMBUS_UTILS_H_ #include #include #include #include /** * @brief Generic function to insert a callback to a callback list * * @param callbacks A pointer to the original list of callbacks (can be NULL) * @param callback A pointer of the callback to insert to the list * * @return 0 on success, negative errno otherwise. */ static inline int smbus_callback_set(sys_slist_t *callbacks, struct smbus_callback *callback) { __ASSERT(callback, "No callback!"); __ASSERT(callback->handler, "No callback handler!"); if (!sys_slist_is_empty(callbacks)) { sys_slist_find_and_remove(callbacks, &callback->node); } sys_slist_prepend(callbacks, &callback->node); return 0; } /** * @brief Generic function to remove a callback from a callback list * * @param callbacks A pointer to the original list of callbacks (can be NULL) * @param callback A pointer of the callback to remove from the list * * @return 0 on success, negative errno otherwise. */ static inline int smbus_callback_remove(sys_slist_t *callbacks, struct smbus_callback *callback) { __ASSERT(callback, "No callback!"); __ASSERT(callback->handler, "No callback handler!"); if (sys_slist_is_empty(callbacks) || !sys_slist_find_and_remove(callbacks, &callback->node)) { return -ENOENT; } return 0; } /** * @brief Generic function to go through and fire callback from a callback list * * @param list A pointer on the SMBus callback list * @param dev A pointer on the SMBus device instance * @param addr A SMBus peripheral device address. */ static inline void smbus_fire_callbacks(sys_slist_t *list, const struct device *dev, uint8_t addr) { struct smbus_callback *cb, *tmp; SYS_SLIST_FOR_EACH_CONTAINER_SAFE(list, cb, tmp, node) { if (cb->addr == addr) { __ASSERT(cb->handler, "No callback handler!"); cb->handler(dev, cb, addr); } } } /** * @brief Helper to initialize a struct smbus_callback properly * * @param callback A valid Application's callback structure pointer. * @param handler A valid handler function pointer. * @param addr A SMBus peripheral device address. */ static inline void smbus_init_callback(struct smbus_callback *callback, smbus_callback_handler_t handler, uint8_t addr) { __ASSERT(callback, "Callback pointer should not be NULL"); __ASSERT(handler, "Callback handler pointer should not be NULL"); callback->handler = handler; callback->addr = addr; } /** * @brief Helper for handling an SMB alert * * This loops through all devices which triggered the SMB alert and * fires the callbacks. * * @param dev SMBus device * @param callbacks list of SMB alert callbacks */ void smbus_loop_alert_devices(const struct device *dev, sys_slist_t *callbacks); #endif /* ZEPHYR_DRIVERS_SMBUS_SMBUS_UTILS_H_ */