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