You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
3.0 KiB
110 lines
3.0 KiB
/* |
|
* 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 <stdint.h> |
|
#include <zephyr/device.h> |
|
#include <zephyr/drivers/smbus.h> |
|
#include <zephyr/sys/slist.h> |
|
|
|
/** |
|
* @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_ */
|
|
|