added API and syscalls for reset controller added reset controller devicetree macro public API header file Signed-off-by: Andrei-Edward Popa <andrei.popa105@yahoo.com>
326 lines
7.8 KiB
C
326 lines
7.8 KiB
C
/*
|
|
* Copyright (c) 2022 Andrei-Edward Popa <andrei.popa105@yahoo.com>
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* @brief Public Reset Controller driver APIs
|
|
*/
|
|
|
|
#ifndef ZEPHYR_INCLUDE_DRIVERS_RESET_H_
|
|
#define ZEPHYR_INCLUDE_DRIVERS_RESET_H_
|
|
|
|
/**
|
|
* @brief Reset Controller Interface
|
|
* @defgroup reset_controller_interface Reset Controller Interface
|
|
* @ingroup io_interfaces
|
|
* @{
|
|
*/
|
|
|
|
#include <zephyr/types.h>
|
|
#include <device.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/** Reset controller device configuration. */
|
|
struct reset_dt_spec {
|
|
/** Reset controller device. */
|
|
const struct device *dev;
|
|
/** Reset line. */
|
|
uint32_t id;
|
|
};
|
|
|
|
/**
|
|
* @brief Static initializer for a @p reset_dt_spec
|
|
*
|
|
* This returns a static initializer for a @p reset_dt_spec structure given a
|
|
* devicetree node identifier, a property specifying a Reset Controller and an index.
|
|
*
|
|
* Example devicetree fragment:
|
|
*
|
|
* n: node {
|
|
* resets = <&reset 10>;
|
|
* }
|
|
*
|
|
* Example usage:
|
|
*
|
|
* const struct reset_dt_spec spec = RESET_DT_SPEC_GET_BY_IDX(DT_NODELABEL(n), 0);
|
|
* // Initializes 'spec' to:
|
|
* // {
|
|
* // .dev = DEVICE_DT_GET(DT_NODELABEL(reset)),
|
|
* // .id = 10
|
|
* // }
|
|
*
|
|
* The 'reset' field must still be checked for readiness, e.g. using
|
|
* device_is_ready(). It is an error to use this macro unless the node
|
|
* exists, has the given property, and that property specifies a reset
|
|
* controller reset line id as shown above.
|
|
*
|
|
* @param node_id devicetree node identifier
|
|
* @param idx logical index into "resets"
|
|
* @return static initializer for a struct reset_dt_spec for the property
|
|
*/
|
|
#define RESET_DT_SPEC_GET_BY_IDX(node_id, idx) \
|
|
{ \
|
|
.dev = DEVICE_DT_GET(DT_RESET_CTLR_BY_IDX(node_id, idx)), \
|
|
.id = DT_RESET_ID_BY_IDX(node_id, idx) \
|
|
}
|
|
|
|
/**
|
|
* @brief Equivalent to RESET_DT_SPEC_GET_BY_IDX(node_id, 0).
|
|
*
|
|
* @param node_id devicetree node identifier
|
|
* @return static initializer for a struct reset_dt_spec for the property
|
|
* @see RESET_DT_SPEC_GET_BY_IDX()
|
|
*/
|
|
#define RESET_DT_SPEC_GET(node_id) \
|
|
RESET_DT_SPEC_GET_BY_IDX(node_id, 0)
|
|
|
|
/**
|
|
* @brief Static initializer for a @p reset_dt_spec from a DT_DRV_COMPAT
|
|
* instance's Reset Controller property at an index.
|
|
*
|
|
* @param inst DT_DRV_COMPAT instance number
|
|
* @param idx logical index into "resets"
|
|
* @return static initializer for a struct reset_dt_spec for the property
|
|
* @see RESET_DT_SPEC_GET_BY_IDX()
|
|
*/
|
|
#define RESET_DT_SPEC_INST_GET_BY_IDX(inst, idx) \
|
|
RESET_DT_SPEC_GET_BY_IDX(DT_DRV_INST(inst), idx)
|
|
|
|
/**
|
|
* @brief Equivalent to RESET_DT_SPEC_INST_GET_BY_IDX(inst, 0).
|
|
*
|
|
* @param inst DT_DRV_COMPAT instance number
|
|
* @return static initializer for a struct reset_dt_spec for the property
|
|
* @see RESET_DT_SPEC_INST_GET_BY_IDX()
|
|
*/
|
|
#define RESET_DT_SPEC_INST_GET(inst) \
|
|
RESET_DT_SPEC_INST_GET_BY_IDX(inst, 0)
|
|
|
|
/** @cond INTERNAL_HIDDEN */
|
|
|
|
/**
|
|
* API template to get the reset status of the device.
|
|
*
|
|
* @see reset_status
|
|
*/
|
|
typedef int (*reset_api_status)(const struct device *dev, uint32_t id, uint8_t *status);
|
|
|
|
/**
|
|
* API template to put the device in reset state.
|
|
*
|
|
* @see reset_assert
|
|
*/
|
|
typedef int (*reset_api_assert)(const struct device *dev, uint32_t id);
|
|
|
|
/**
|
|
* API template to take out the device from reset state.
|
|
*
|
|
* @see reset_deassert
|
|
*/
|
|
typedef int (*reset_api_deassert)(const struct device *dev, uint32_t id);
|
|
|
|
/**
|
|
* API template to reset the device.
|
|
*
|
|
* @see reset_toggle
|
|
*/
|
|
typedef int (*reset_api_toggle)(const struct device *dev, uint32_t id);
|
|
|
|
/**
|
|
* @brief Reset Controller driver API
|
|
*/
|
|
__subsystem struct reset_driver_api {
|
|
reset_api_status status;
|
|
reset_api_assert assert;
|
|
reset_api_deassert deassert;
|
|
reset_api_toggle toggle;
|
|
};
|
|
|
|
/** @endcond */
|
|
|
|
/**
|
|
* @brief Get the reset status
|
|
*
|
|
* This function returns the reset status of the device.
|
|
*
|
|
* @param dev Reset controller device.
|
|
* @param id Reset line.
|
|
* @param status Where to write the reset status.
|
|
*
|
|
* @retval 0 On success.
|
|
* @retval -ENOSYS If the functionality is not implemented by the driver.
|
|
* @retval -errno Other negative errno in case of failure.
|
|
*/
|
|
__syscall int reset_status(const struct device *dev, uint32_t id, uint8_t *status);
|
|
|
|
static inline int z_impl_reset_status(const struct device *dev, uint32_t id, uint8_t *status)
|
|
{
|
|
const struct reset_driver_api *api = dev->api;
|
|
|
|
if (!api->status) {
|
|
return -ENOSYS;
|
|
}
|
|
|
|
return api->status(dev, id, status);
|
|
}
|
|
|
|
/**
|
|
* @brief Get the reset status from a @p reset_dt_spec.
|
|
*
|
|
* This is equivalent to:
|
|
*
|
|
* reset_status(spec->dev, spec->id, status);
|
|
*
|
|
* @param spec Reset controller specification from devicetree
|
|
* @param status Where to write the reset status.
|
|
*
|
|
* @return a value from reset_status()
|
|
*/
|
|
static inline int reset_status_dt(const struct reset_dt_spec *spec, uint8_t *status)
|
|
{
|
|
return reset_status(spec->dev, spec->id, status);
|
|
}
|
|
|
|
/**
|
|
* @brief Put the device in reset state
|
|
*
|
|
* This function sets/clears the reset bits of the device,
|
|
* depending on the logic level (active-high/active-low).
|
|
*
|
|
* @param dev Reset controller device.
|
|
* @param id Reset line.
|
|
*
|
|
* @retval 0 On success.
|
|
* @retval -ENOSYS If the functionality is not implemented by the driver.
|
|
* @retval -errno Other negative errno in case of failure.
|
|
*/
|
|
__syscall int reset_assert(const struct device *dev, uint32_t id);
|
|
|
|
static inline int z_impl_reset_assert(const struct device *dev, uint32_t id)
|
|
{
|
|
const struct reset_driver_api *api = dev->api;
|
|
|
|
if (!api->assert) {
|
|
return -ENOSYS;
|
|
}
|
|
|
|
return api->assert(dev, id);
|
|
}
|
|
|
|
/**
|
|
* @brief Assert the reset state from a @p reset_dt_spec.
|
|
*
|
|
* This is equivalent to:
|
|
*
|
|
* reset_assert(spec->dev, spec->id);
|
|
*
|
|
* @param spec Reset controller specification from devicetree
|
|
*
|
|
* @return a value from reset_assert()
|
|
*/
|
|
static inline int reset_assert_dt(const struct reset_dt_spec *spec)
|
|
{
|
|
return reset_assert(spec->dev, spec->id);
|
|
}
|
|
|
|
/**
|
|
* @brief Take out the device from reset state.
|
|
*
|
|
* This function sets/clears the reset bits of the device,
|
|
* depending on the logic level (active-low/active-high).
|
|
*
|
|
* @param dev Reset controller device.
|
|
* @param id Reset line.
|
|
*
|
|
* @retval 0 On success.
|
|
* @retval -ENOSYS If the functionality is not implemented by the driver.
|
|
* @retval -errno Other negative errno in case of failure.
|
|
*/
|
|
__syscall int reset_deassert(const struct device *dev, uint32_t id);
|
|
|
|
static inline int z_impl_reset_deassert(const struct device *dev, uint32_t id)
|
|
{
|
|
const struct reset_driver_api *api = dev->api;
|
|
|
|
if (!api->deassert) {
|
|
return -ENOSYS;
|
|
}
|
|
|
|
return api->deassert(dev, id);
|
|
}
|
|
|
|
/**
|
|
* @brief Deassert the reset state from a @p reset_dt_spec.
|
|
*
|
|
* This is equivalent to:
|
|
*
|
|
* reset_deassert(spec->dev, spec->id)
|
|
*
|
|
* @param spec Reset controller specification from devicetree
|
|
*
|
|
* @return a value from reset_deassert()
|
|
*/
|
|
static inline int reset_deassert_dt(const struct reset_dt_spec *spec)
|
|
{
|
|
return reset_deassert(spec->dev, spec->id);
|
|
}
|
|
|
|
/**
|
|
* @brief Reset the device.
|
|
*
|
|
* This function performs reset for a device (assert + deassert).
|
|
*
|
|
* @param dev Reset controller device.
|
|
* @param id Reset line.
|
|
*
|
|
* @retval 0 On success.
|
|
* @retval -ENOSYS If the functionality is not implemented by the driver.
|
|
* @retval -errno Other negative errno in case of failure.
|
|
*/
|
|
__syscall int reset_toggle(const struct device *dev, uint32_t id);
|
|
|
|
static inline int z_impl_reset_toggle(const struct device *dev, uint32_t id)
|
|
{
|
|
const struct reset_driver_api *api = dev->api;
|
|
|
|
if (!api->toggle) {
|
|
return -ENOSYS;
|
|
}
|
|
|
|
return api->toggle(dev, id);
|
|
}
|
|
|
|
/**
|
|
* @brief Reset the device from a @p reset_dt_spec.
|
|
*
|
|
* This is equivalent to:
|
|
*
|
|
* reset_toggle(spec->dev, spec->id)
|
|
*
|
|
* @param spec Reset controller specification from devicetree
|
|
*
|
|
* @return a value from reset_toggle()
|
|
*/
|
|
static inline int reset_toggle_dt(const struct reset_dt_spec *spec)
|
|
{
|
|
return reset_toggle(spec->dev, spec->id);
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#include <syscalls/reset.h>
|
|
|
|
#endif /* ZEPHYR_INCLUDE_DRIVERS_RESET_H_ */
|