1 /*
2  * Copyright (c) 2006-2022, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2022-11-26     GuEe-GUI     first version
9  */
10 
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 
14 #include <drivers/platform.h>
15 
fixed_clk_ofw_init(struct rt_platform_device * pdev,struct rt_clk_fixed_rate * clk_fixed)16 static rt_err_t fixed_clk_ofw_init(struct rt_platform_device *pdev, struct rt_clk_fixed_rate *clk_fixed)
17 {
18     rt_err_t err = RT_EOK;
19     rt_uint32_t rate, accuracy;
20     struct rt_ofw_node *np = pdev->parent.ofw_node;
21     const char *clk_name = np->name;
22 
23     if (!rt_ofw_prop_read_u32(np, "clock-frequency", &rate))
24     {
25         rt_ofw_prop_read_u32(np, "clock-accuracy", &accuracy);
26         rt_ofw_prop_read_string(np, "clock-output-names", &clk_name);
27 
28         clk_fixed->clk.name = clk_name;
29         clk_fixed->clk.rate = rate;
30         clk_fixed->clk.min_rate = rate;
31         clk_fixed->clk.max_rate = rate;
32         clk_fixed->fixed_rate = rate;
33         clk_fixed->fixed_accuracy = accuracy;
34 
35         rt_ofw_data(np) = &clk_fixed->clk;
36     }
37     else
38     {
39         err = -RT_EIO;
40     }
41 
42     return err;
43 }
44 
fixed_clk_probe(struct rt_platform_device * pdev)45 static rt_err_t fixed_clk_probe(struct rt_platform_device *pdev)
46 {
47     rt_err_t err = RT_EOK;
48     struct rt_clk_fixed_rate *clk_fixed = rt_calloc(1, sizeof(*clk_fixed));
49 
50     if (clk_fixed)
51     {
52         err = fixed_clk_ofw_init(pdev, clk_fixed);
53     }
54     else
55     {
56         err = -RT_ENOMEM;
57     }
58 
59     if (!err)
60     {
61         err = rt_clk_register(&clk_fixed->clk, RT_NULL);
62     }
63 
64     if (err && clk_fixed)
65     {
66         rt_free(clk_fixed);
67     }
68 
69     return err;
70 }
71 
72 static const struct rt_ofw_node_id fixed_clk_ofw_ids[] =
73 {
74     { .compatible = "fixed-clock" },
75     { /* sentinel */ }
76 };
77 
78 static struct rt_platform_driver fixed_clk_driver =
79 {
80     .name = "clk-fixed-rate",
81     .ids = fixed_clk_ofw_ids,
82 
83     .probe = fixed_clk_probe,
84 };
85 
fixed_clk_drv_register(void)86 static int fixed_clk_drv_register(void)
87 {
88     rt_platform_driver_register(&fixed_clk_driver);
89 
90     return 0;
91 }
92 INIT_SUBSYS_EXPORT(fixed_clk_drv_register);
93