|
@@ -1,17 +1,27 @@
|
|
|
/*
|
|
|
- * Copyright (c) 2006-2022, RT-Thread Development Team
|
|
|
+ * Copyright (c) 2006-2025 RT-Thread Development Team
|
|
|
*
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
*
|
|
|
* Change Logs:
|
|
|
* Date Author Notes
|
|
|
* 2022-11-26 GuEe-GUI first version
|
|
|
+ * 2025-01-24 wumingzi add doxygen comment
|
|
|
*/
|
|
|
|
|
|
#include <rtthread.h>
|
|
|
#include <rtservice.h>
|
|
|
#include <rtdevice.h>
|
|
|
|
|
|
+/**
|
|
|
+ * @addtogroup Drivers RTTHREAD Driver
|
|
|
+ * @defgroup clk clk
|
|
|
+ * @brief clk driver api
|
|
|
+ * @ingroup Drivers
|
|
|
+ * @addtogroup clk
|
|
|
+ * @{
|
|
|
+ */
|
|
|
+
|
|
|
#define DBG_TAG "rtdm.clk"
|
|
|
#define DBG_LVL DBG_INFO
|
|
|
#include <rtdbg.h>
|
|
@@ -20,6 +30,12 @@ static struct rt_spinlock _clk_lock = { 0 };
|
|
|
static rt_list_t _clk_nodes = RT_LIST_OBJECT_INIT(_clk_nodes);
|
|
|
static rt_list_t _clk_notifier_nodes = RT_LIST_OBJECT_INIT(_clk_notifier_nodes);
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Release clock node
|
|
|
+ *
|
|
|
+ * @param r point to reference count of clock node
|
|
|
+ * @warning The function only can print log and MORE DETAILS SHOULD BE IMPLEMENTED.
|
|
|
+ */
|
|
|
static void clk_release(struct rt_ref *r)
|
|
|
{
|
|
|
struct rt_clk_node *clk_np = rt_container_of(r, struct rt_clk_node, ref);
|
|
@@ -30,6 +46,13 @@ static void clk_release(struct rt_ref *r)
|
|
|
RT_ASSERT(0);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Increase reference count for clock node
|
|
|
+ *
|
|
|
+ * @param clk_np point to clock node
|
|
|
+ *
|
|
|
+ * @return struct rt_clk_node * point to clock node whose reference count has increased
|
|
|
+ */
|
|
|
rt_inline struct rt_clk_node *clk_get(struct rt_clk_node *clk_np)
|
|
|
{
|
|
|
rt_ref_get(&clk_np->ref);
|
|
@@ -37,11 +60,27 @@ rt_inline struct rt_clk_node *clk_get(struct rt_clk_node *clk_np)
|
|
|
return clk_np;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Decrease reference count for clock node
|
|
|
+ *
|
|
|
+ * @param clk_np point to clock node
|
|
|
+ *
|
|
|
+ */
|
|
|
rt_inline void clk_put(struct rt_clk_node *clk_np)
|
|
|
{
|
|
|
rt_ref_put(&clk_np->ref, &clk_release);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Allocate memory space for struct clock and return it
|
|
|
+ *
|
|
|
+ * @param clk_np point to clock node
|
|
|
+ * @param dev_id device identifier for the clock
|
|
|
+ * @param con_id connection identifier for the clock
|
|
|
+ * @param fw_node point to the firmware node associated with the clock
|
|
|
+ *
|
|
|
+ * @return struct rt_clk* point to clock
|
|
|
+ */
|
|
|
static struct rt_clk *clk_alloc(struct rt_clk_node *clk_np, const char *dev_id,
|
|
|
const char *con_id, void *fw_node)
|
|
|
{
|
|
@@ -63,6 +102,12 @@ static struct rt_clk *clk_alloc(struct rt_clk_node *clk_np, const char *dev_id,
|
|
|
return clk;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Free memory space of clock object
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ *
|
|
|
+ */
|
|
|
static void clk_free(struct rt_clk *clk)
|
|
|
{
|
|
|
struct rt_clk_node *clk_np = clk->clk_np;
|
|
@@ -75,6 +120,17 @@ static void clk_free(struct rt_clk *clk)
|
|
|
rt_free(clk);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Allocate memory space and creat clock object
|
|
|
+ *
|
|
|
+ * @param clk_np point to clock node
|
|
|
+ * @param dev_id device identifier for the clock
|
|
|
+ * @param con_id connection identifier for the clock
|
|
|
+ * @param fw_data point to the firmware data associated with the clock
|
|
|
+ * @param fw_node point to the firmware node associated with the clock
|
|
|
+ *
|
|
|
+ * @return struct rt_clk* point to clock
|
|
|
+ */
|
|
|
static struct rt_clk *clk_create(struct rt_clk_node *clk_np, const char *dev_id,
|
|
|
const char *con_id, void *fw_data, void *fw_node)
|
|
|
{
|
|
@@ -96,6 +152,16 @@ static struct rt_clk *clk_create(struct rt_clk_node *clk_np, const char *dev_id,
|
|
|
return clk;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Notify corresponding clock from all
|
|
|
+ *
|
|
|
+ * @param clk_np point to clock node
|
|
|
+ * @param msg message identifier for the event
|
|
|
+ * @param old_rate old rate of the clock before the event
|
|
|
+ * @param new_rate new rate of the clock after the event
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on notify clock sucessfully, and other value is failed.
|
|
|
+ */
|
|
|
static rt_err_t clk_notify(struct rt_clk_node *clk_np, rt_ubase_t msg, rt_ubase_t old_rate, rt_ubase_t new_rate)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -118,6 +184,13 @@ static rt_err_t clk_notify(struct rt_clk_node *clk_np, rt_ubase_t msg, rt_ubase_
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Set parent clock
|
|
|
+ *
|
|
|
+ * @param clk_np point to clock node
|
|
|
+ * @param parent_np point to parent rt_clk
|
|
|
+ *
|
|
|
+ */
|
|
|
static void clk_set_parent(struct rt_clk_node *clk_np, struct rt_clk_node *parent_np)
|
|
|
{
|
|
|
rt_hw_spin_lock(&_clk_lock.lock);
|
|
@@ -133,6 +206,15 @@ static const struct rt_clk_ops unused_clk_ops =
|
|
|
{
|
|
|
};
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Register clock node into clock list
|
|
|
+ *
|
|
|
+ * @param clk_np point to child node that will be registered node.
|
|
|
+ * @param parent_np point to parent rt_clk. If it is RT_NULL, clock node will be linked to init node.
|
|
|
+ *
|
|
|
+ * @retval RT_EOK
|
|
|
+ * @retval -RT_ENOMEM
|
|
|
+ */
|
|
|
rt_err_t rt_clk_register(struct rt_clk_node *clk_np, struct rt_clk_node *parent_np)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -190,6 +272,15 @@ rt_err_t rt_clk_register(struct rt_clk_node *clk_np, struct rt_clk_node *parent_
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Unregister clock node from clock list
|
|
|
+ *
|
|
|
+ * @param clk_np point to child node that will be Unregistered node.
|
|
|
+ *
|
|
|
+ * @retval RT_EOK
|
|
|
+ * @retval -RT_EBUSY
|
|
|
+ * @retval -RT_EINVAL
|
|
|
+ */
|
|
|
rt_err_t rt_clk_unregister(struct rt_clk_node *clk_np)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -221,6 +312,15 @@ rt_err_t rt_clk_unregister(struct rt_clk_node *clk_np)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Register clock notifier into notifier list
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ * @param notifier point to notifier for register
|
|
|
+ *
|
|
|
+ * @retval RT_EOK
|
|
|
+ * @retval -RT_EINVAL
|
|
|
+ */
|
|
|
rt_err_t rt_clk_notifier_register(struct rt_clk *clk, struct rt_clk_notifier *notifier)
|
|
|
{
|
|
|
if (!clk || !clk->clk_np || !notifier)
|
|
@@ -239,6 +339,15 @@ rt_err_t rt_clk_notifier_register(struct rt_clk *clk, struct rt_clk_notifier *no
|
|
|
return RT_EOK;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Unregister clock notifier into notifier list
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ * @param notifier point to notifier for unregister
|
|
|
+ *
|
|
|
+ * @retval RT_EOK
|
|
|
+ * @retval -RT_EINVAL
|
|
|
+ */
|
|
|
rt_err_t rt_clk_notifier_unregister(struct rt_clk *clk, struct rt_clk_notifier *notifier)
|
|
|
{
|
|
|
struct rt_clk_notifier *notifier_find;
|
|
@@ -266,6 +375,14 @@ rt_err_t rt_clk_notifier_unregister(struct rt_clk *clk, struct rt_clk_notifier *
|
|
|
return RT_EOK;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Recursively prepare clock
|
|
|
+ *
|
|
|
+ * @param clk Ponit to clock that will be prepared
|
|
|
+ * @param clk_np Ponit to clock node that will be prepared
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on prepare clock sucessfully, and other value is failed.
|
|
|
+ */
|
|
|
static rt_err_t clk_prepare(struct rt_clk *clk, struct rt_clk_node *clk_np)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -288,6 +405,13 @@ static rt_err_t clk_prepare(struct rt_clk *clk, struct rt_clk_node *clk_np)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Prepare clock
|
|
|
+ *
|
|
|
+ * @param clk
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on prepare clock sucessfully, and other value is failed.
|
|
|
+ */
|
|
|
rt_err_t rt_clk_prepare(struct rt_clk *clk)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -306,6 +430,13 @@ rt_err_t rt_clk_prepare(struct rt_clk *clk)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Recursively unprepare clock
|
|
|
+ *
|
|
|
+ * @param clk Ponit to clock that will be unprepared
|
|
|
+ * @param clk_np Ponit to clock node that will be unprepared
|
|
|
+ *
|
|
|
+ */
|
|
|
static void clk_unprepare(struct rt_clk *clk, struct rt_clk_node *clk_np)
|
|
|
{
|
|
|
if (clk_np->parent)
|
|
@@ -341,6 +472,13 @@ rt_err_t rt_clk_unprepare(struct rt_clk *clk)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Enable clock
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on enable clock FOREVER.
|
|
|
+ */
|
|
|
static rt_err_t clk_enable(struct rt_clk *clk, struct rt_clk_node *clk_np)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -363,6 +501,13 @@ static rt_err_t clk_enable(struct rt_clk *clk, struct rt_clk_node *clk_np)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Enable clock
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on enable clock sucessfully, and other value is failed.
|
|
|
+ */
|
|
|
rt_err_t rt_clk_enable(struct rt_clk *clk)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -379,6 +524,13 @@ rt_err_t rt_clk_enable(struct rt_clk *clk)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Recursively disable clock
|
|
|
+ *
|
|
|
+ * @param clk Ponit to clock that will be disabled
|
|
|
+ * @param clk_np Ponit to clock node that will be disabled
|
|
|
+ *
|
|
|
+ */
|
|
|
static void clk_disable(struct rt_clk *clk, struct rt_clk_node *clk_np)
|
|
|
{
|
|
|
if (clk_np->parent)
|
|
@@ -396,6 +548,12 @@ static void clk_disable(struct rt_clk *clk, struct rt_clk_node *clk_np)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Disable clock
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ *
|
|
|
+ */
|
|
|
void rt_clk_disable(struct rt_clk *clk)
|
|
|
{
|
|
|
if (clk && clk->clk_np)
|
|
@@ -408,6 +566,13 @@ void rt_clk_disable(struct rt_clk *clk)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Prepare and enable clock
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on prepare and enable clock sucessfully, and other value is failed.
|
|
|
+ */
|
|
|
rt_err_t rt_clk_prepare_enable(struct rt_clk *clk)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -432,6 +597,12 @@ rt_err_t rt_clk_prepare_enable(struct rt_clk *clk)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Disable and unprepare clock
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ *
|
|
|
+ */
|
|
|
void rt_clk_disable_unprepare(struct rt_clk *clk)
|
|
|
{
|
|
|
RT_DEBUG_NOT_IN_INTERRUPT;
|
|
@@ -443,6 +614,13 @@ void rt_clk_disable_unprepare(struct rt_clk *clk)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Prepare clock array for mutipule out clock
|
|
|
+ *
|
|
|
+ * @param clk_arr point to clock array
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on prepare clock array sucessfully, and other value is failed.
|
|
|
+ */
|
|
|
rt_err_t rt_clk_array_prepare(struct rt_clk_array *clk_arr)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -490,6 +668,13 @@ rt_err_t rt_clk_array_unprepare(struct rt_clk_array *clk_arr)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Enable clock array for mutipule out clock
|
|
|
+ *
|
|
|
+ * @param clk_arr point to clock array
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on Enable clock array sucessfully, and other value is failed.
|
|
|
+ */
|
|
|
rt_err_t rt_clk_array_enable(struct rt_clk_array *clk_arr)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -516,6 +701,12 @@ rt_err_t rt_clk_array_enable(struct rt_clk_array *clk_arr)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Enable clock array for mutipule out clock
|
|
|
+ *
|
|
|
+ * @param clk_arr point to clock array
|
|
|
+ *
|
|
|
+ */
|
|
|
void rt_clk_array_disable(struct rt_clk_array *clk_arr)
|
|
|
{
|
|
|
if (clk_arr)
|
|
@@ -527,6 +718,14 @@ void rt_clk_array_disable(struct rt_clk_array *clk_arr)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Prepare and enable clock array
|
|
|
+ *
|
|
|
+ * @param clk_arr point to clock array
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on prepare and enable clock array sucessfully, and other
|
|
|
+ value is failed.
|
|
|
+ */
|
|
|
rt_err_t rt_clk_array_prepare_enable(struct rt_clk_array *clk_arr)
|
|
|
{
|
|
|
rt_err_t err;
|
|
@@ -544,12 +743,27 @@ rt_err_t rt_clk_array_prepare_enable(struct rt_clk_array *clk_arr)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Disable and unprepare clock array
|
|
|
+ *
|
|
|
+ * @param clk_arr point to clock array
|
|
|
+ *
|
|
|
+ */
|
|
|
void rt_clk_array_disable_unprepare(struct rt_clk_array *clk_arr)
|
|
|
{
|
|
|
rt_clk_array_disable(clk_arr);
|
|
|
rt_clk_array_unprepare(clk_arr);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Set clock rate range
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ * @param min minimum clock rate
|
|
|
+ * @param max minimum clock rate
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on set clock rate range sucessfully, and other value is failed.
|
|
|
+ */
|
|
|
rt_err_t rt_clk_set_rate_range(struct rt_clk *clk, rt_ubase_t min, rt_ubase_t max)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -590,6 +804,14 @@ rt_err_t rt_clk_set_rate_range(struct rt_clk *clk, rt_ubase_t min, rt_ubase_t ma
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Set minimum clock rate
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ * @param rate miminum clock rate
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on set minimum clock rate sucessfully, and other value is failed.
|
|
|
+ */
|
|
|
rt_err_t rt_clk_set_min_rate(struct rt_clk *clk, rt_ubase_t rate)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -604,6 +826,14 @@ rt_err_t rt_clk_set_min_rate(struct rt_clk *clk, rt_ubase_t rate)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Set maximum clock rate
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ * @param rate maximum clock rate
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on set maximum clock rate sucessfully, and other value is failed.
|
|
|
+ */
|
|
|
rt_err_t rt_clk_set_max_rate(struct rt_clk *clk, rt_ubase_t rate)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -618,6 +848,14 @@ rt_err_t rt_clk_set_max_rate(struct rt_clk *clk, rt_ubase_t rate)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Set clock rate
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ * @param rate target rate
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on set clock rate sucessfully, and other value is failed.
|
|
|
+ */
|
|
|
rt_err_t rt_clk_set_rate(struct rt_clk *clk, rt_ubase_t rate)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -666,6 +904,13 @@ rt_err_t rt_clk_set_rate(struct rt_clk *clk, rt_ubase_t rate)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Get clock rate
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ *
|
|
|
+ * @return rt_ubase_t clock rate or error code
|
|
|
+ */
|
|
|
rt_ubase_t rt_clk_get_rate(struct rt_clk *clk)
|
|
|
{
|
|
|
rt_ubase_t rate = 0;
|
|
@@ -685,6 +930,14 @@ rt_ubase_t rt_clk_get_rate(struct rt_clk *clk)
|
|
|
return rate;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Set clock phase
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ * @param degrees target phase and the unit of phase is degree
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on set clock phase sucessfully, and other value is failed.
|
|
|
+ */
|
|
|
rt_err_t rt_clk_set_phase(struct rt_clk *clk, int degrees)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -701,6 +954,13 @@ rt_err_t rt_clk_set_phase(struct rt_clk *clk, int degrees)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Get clock phase
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ *
|
|
|
+ * @return rt_base_t clock phase or error code
|
|
|
+ */
|
|
|
rt_base_t rt_clk_get_phase(struct rt_clk *clk)
|
|
|
{
|
|
|
rt_base_t res = RT_EOK;
|
|
@@ -717,6 +977,16 @@ rt_base_t rt_clk_get_phase(struct rt_clk *clk)
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Check if clock rate is in the minimum to maximun and get it
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ * @param rate rate will be checked
|
|
|
+ *
|
|
|
+ * @return rt_base_t get the correct rate
|
|
|
+ * @note if parameter rate less than the minimum or more than maximum, the
|
|
|
+ retrun rate will be set to minimum ormaximum value
|
|
|
+ */
|
|
|
rt_base_t rt_clk_round_rate(struct rt_clk *clk, rt_ubase_t rate)
|
|
|
{
|
|
|
rt_base_t res = -RT_EINVAL;
|
|
@@ -761,6 +1031,14 @@ rt_base_t rt_clk_round_rate(struct rt_clk *clk, rt_ubase_t rate)
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Set clock parent object
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ * @param clk_parent point to parent clock
|
|
|
+ *
|
|
|
+ * @return rt_err_t RT_EOK on set clock parent sucessfully, and other value is failed.
|
|
|
+ */
|
|
|
rt_err_t rt_clk_set_parent(struct rt_clk *clk, struct rt_clk *clk_parent)
|
|
|
{
|
|
|
rt_err_t err = RT_EOK;
|
|
@@ -777,6 +1055,14 @@ rt_err_t rt_clk_set_parent(struct rt_clk *clk, struct rt_clk *clk_parent)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Get parent clock pointer
|
|
|
+ *
|
|
|
+ * @param clk child clock
|
|
|
+ *
|
|
|
+ * @return struct rt_clk* parent clock object pointer will be return, unless child
|
|
|
+ clock node havn't parent node instead return RT_NULL
|
|
|
+ */
|
|
|
struct rt_clk *rt_clk_get_parent(struct rt_clk *clk)
|
|
|
{
|
|
|
struct rt_clk *parent = RT_NULL;
|
|
@@ -795,6 +1081,14 @@ struct rt_clk *rt_clk_get_parent(struct rt_clk *clk)
|
|
|
return parent;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Get clock array pointer from ofw device node
|
|
|
+ *
|
|
|
+ * @param dev point to dev
|
|
|
+ *
|
|
|
+ * @return struct rt_clk_array* if use ofw and under normal circumstance, it will return
|
|
|
+ clock array pointer and other value is RT_NULL
|
|
|
+ */
|
|
|
struct rt_clk_array *rt_clk_get_array(struct rt_device *dev)
|
|
|
{
|
|
|
struct rt_clk_array *clk_arr = RT_NULL;
|
|
@@ -806,6 +1100,15 @@ struct rt_clk_array *rt_clk_get_array(struct rt_device *dev)
|
|
|
return clk_arr;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Get clock pointer from ofw device node by index
|
|
|
+ *
|
|
|
+ * @param dev point to dev
|
|
|
+ * @param index index of clock object
|
|
|
+ *
|
|
|
+ * @return struct rt_clk* if use ofw and under normal circumstance, it will return clock
|
|
|
+ pointer and other value is RT_NULL
|
|
|
+ */
|
|
|
struct rt_clk *rt_clk_get_by_index(struct rt_device *dev, int index)
|
|
|
{
|
|
|
struct rt_clk *clk = RT_NULL;
|
|
@@ -817,6 +1120,15 @@ struct rt_clk *rt_clk_get_by_index(struct rt_device *dev, int index)
|
|
|
return clk;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Get clock pointer from ofw device node by name
|
|
|
+ *
|
|
|
+ * @param dev point to dev
|
|
|
+ * @param name name of clock object
|
|
|
+ *
|
|
|
+ * @return struct rt_clk* if use ofw and under normal circumstance, it will return clock
|
|
|
+ pointer and other value is RT_NULL
|
|
|
+ */
|
|
|
struct rt_clk *rt_clk_get_by_name(struct rt_device *dev, const char *name)
|
|
|
{
|
|
|
struct rt_clk *clk = RT_NULL;
|
|
@@ -828,6 +1140,12 @@ struct rt_clk *rt_clk_get_by_name(struct rt_device *dev, const char *name)
|
|
|
return clk;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Put reference count of all colock in the clock array
|
|
|
+ *
|
|
|
+ * @param clk_arr point to clock array
|
|
|
+ *
|
|
|
+ */
|
|
|
void rt_clk_array_put(struct rt_clk_array *clk_arr)
|
|
|
{
|
|
|
if (clk_arr)
|
|
@@ -848,6 +1166,12 @@ void rt_clk_array_put(struct rt_clk_array *clk_arr)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Put reference count of clock
|
|
|
+ *
|
|
|
+ * @param clk point to clock
|
|
|
+ *
|
|
|
+ */
|
|
|
void rt_clk_put(struct rt_clk *clk)
|
|
|
{
|
|
|
if (clk)
|
|
@@ -858,6 +1182,16 @@ void rt_clk_put(struct rt_clk *clk)
|
|
|
}
|
|
|
|
|
|
#ifdef RT_USING_OFW
|
|
|
+/**
|
|
|
+ * @brief Get a clock object from a device tree node without acquiring a lock
|
|
|
+ *
|
|
|
+ * @param np point to ofw node
|
|
|
+ * @param index index of clock in ofw
|
|
|
+ * @param name connection identifier for the clock
|
|
|
+ * @param locked lock flag for indicating whether the caller holds the lock
|
|
|
+ *
|
|
|
+ * @return struct rt_clk* point to the newly created clock object, or an error pointer
|
|
|
+ */
|
|
|
static struct rt_clk *ofw_get_clk_no_lock(struct rt_ofw_node *np, int index, const char *name, rt_bool_t locked)
|
|
|
{
|
|
|
struct rt_clk *clk = RT_NULL;
|
|
@@ -914,6 +1248,15 @@ static struct rt_clk *ofw_get_clk_no_lock(struct rt_ofw_node *np, int index, con
|
|
|
return clk;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Get clock from ofw with acquiring a spin lock
|
|
|
+ *
|
|
|
+ * @param np point to ofw node
|
|
|
+ * @param index index of clock in ofw
|
|
|
+ * @param name connection identifier for the clock
|
|
|
+ *
|
|
|
+ * @return struct rt_clk* point to the newly created clock object, or an error pointer
|
|
|
+ */
|
|
|
static struct rt_clk *ofw_get_clk(struct rt_ofw_node *np, int index, const char *name)
|
|
|
{
|
|
|
struct rt_clk *clk;
|
|
@@ -927,6 +1270,13 @@ static struct rt_clk *ofw_get_clk(struct rt_ofw_node *np, int index, const char
|
|
|
return clk;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Get clock array from ofw
|
|
|
+ *
|
|
|
+ * @param np point to ofw node
|
|
|
+ *
|
|
|
+ * @return struct rt_clk_array* point to the newly created clock array, or an error pointer
|
|
|
+ */
|
|
|
struct rt_clk_array *rt_ofw_get_clk_array(struct rt_ofw_node *np)
|
|
|
{
|
|
|
int count;
|
|
@@ -984,6 +1334,14 @@ struct rt_clk_array *rt_ofw_get_clk_array(struct rt_ofw_node *np)
|
|
|
return clk_arr;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Get clock from ofw with acquiring a spin lock by index and node pointer
|
|
|
+ *
|
|
|
+ * @param np point to ofw node
|
|
|
+ * @param index index of clock in ofw
|
|
|
+ *
|
|
|
+ * @return struct rt_clk* point to the newly created clock object, or an error pointer
|
|
|
+ */
|
|
|
struct rt_clk *rt_ofw_get_clk(struct rt_ofw_node *np, int index)
|
|
|
{
|
|
|
struct rt_clk *clk = RT_NULL;
|
|
@@ -996,6 +1354,14 @@ struct rt_clk *rt_ofw_get_clk(struct rt_ofw_node *np, int index)
|
|
|
return clk;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Get clock from ofw with acquiring a spin lock by name
|
|
|
+ *
|
|
|
+ * @param np point to ofw node
|
|
|
+ * @param name name of clock will be returned
|
|
|
+ *
|
|
|
+ * @return struct rt_clk* point to the newly created clock object, or an error pointer
|
|
|
+ */
|
|
|
struct rt_clk *rt_ofw_get_clk_by_name(struct rt_ofw_node *np, const char *name)
|
|
|
{
|
|
|
struct rt_clk *clk = RT_NULL;
|
|
@@ -1013,6 +1379,13 @@ struct rt_clk *rt_ofw_get_clk_by_name(struct rt_ofw_node *np, const char *name)
|
|
|
return clk;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * @brief Count number of clocks in ofw
|
|
|
+ *
|
|
|
+ * @param clk_ofw_np point to ofw node
|
|
|
+ *
|
|
|
+ * @return rt_ssize_t number of clocks
|
|
|
+ */
|
|
|
rt_ssize_t rt_ofw_count_of_clk(struct rt_ofw_node *clk_ofw_np)
|
|
|
{
|
|
|
if (clk_ofw_np)
|
|
@@ -1080,4 +1453,7 @@ rt_ssize_t rt_ofw_count_of_clk(struct rt_ofw_node *clk_ofw_np)
|
|
|
|
|
|
return -RT_EINVAL;
|
|
|
}
|
|
|
+
|
|
|
#endif /* RT_USING_OFW */
|
|
|
+
|
|
|
+/**@}*/
|