1 /*
2  * Copyright (c) 2016, NVIDIA CORPORATION.
3  *
4  * SPDX-License-Identifier: GPL-2.0
5  */
6 
7 #include <common.h>
8 #include <dm.h>
9 #include <clk.h>
10 #include <asm/clk.h>
11 
12 struct sandbox_clk_test {
13 	struct clk clks[SANDBOX_CLK_TEST_ID_COUNT];
14 	struct clk_bulk bulk;
15 };
16 
17 static const char * const sandbox_clk_test_names[] = {
18 	[SANDBOX_CLK_TEST_ID_FIXED] = "fixed",
19 	[SANDBOX_CLK_TEST_ID_SPI] = "spi",
20 	[SANDBOX_CLK_TEST_ID_I2C] = "i2c",
21 };
22 
23 int sandbox_clk_test_get(struct udevice *dev)
24 {
25 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
26 	int i, ret;
27 
28 	for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) {
29 		ret = clk_get_by_name(dev, sandbox_clk_test_names[i],
30 				      &sbct->clks[i]);
31 		if (ret)
32 			return ret;
33 	}
34 
35 	return 0;
36 }
37 
38 int sandbox_clk_test_get_bulk(struct udevice *dev)
39 {
40 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
41 
42 	return clk_get_bulk(dev, &sbct->bulk);
43 }
44 
45 ulong sandbox_clk_test_get_rate(struct udevice *dev, int id)
46 {
47 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
48 
49 	if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
50 		return -EINVAL;
51 
52 	return clk_get_rate(&sbct->clks[id]);
53 }
54 
55 ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate)
56 {
57 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
58 
59 	if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
60 		return -EINVAL;
61 
62 	return clk_set_rate(&sbct->clks[id], rate);
63 }
64 
65 int sandbox_clk_test_enable(struct udevice *dev, int id)
66 {
67 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
68 
69 	if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
70 		return -EINVAL;
71 
72 	return clk_enable(&sbct->clks[id]);
73 }
74 
75 int sandbox_clk_test_enable_bulk(struct udevice *dev)
76 {
77 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
78 
79 	return clk_enable_bulk(&sbct->bulk);
80 }
81 
82 int sandbox_clk_test_disable(struct udevice *dev, int id)
83 {
84 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
85 
86 	if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
87 		return -EINVAL;
88 
89 	return clk_disable(&sbct->clks[id]);
90 }
91 
92 int sandbox_clk_test_disable_bulk(struct udevice *dev)
93 {
94 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
95 
96 	return clk_disable_bulk(&sbct->bulk);
97 }
98 
99 int sandbox_clk_test_free(struct udevice *dev)
100 {
101 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
102 	int i, ret;
103 
104 	for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) {
105 		ret = clk_free(&sbct->clks[i]);
106 		if (ret)
107 			return ret;
108 	}
109 
110 	return 0;
111 }
112 
113 int sandbox_clk_test_release_bulk(struct udevice *dev)
114 {
115 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
116 
117 	return clk_release_bulk(&sbct->bulk);
118 }
119 
120 static const struct udevice_id sandbox_clk_test_ids[] = {
121 	{ .compatible = "sandbox,clk-test" },
122 	{ }
123 };
124 
125 U_BOOT_DRIVER(sandbox_clk_test) = {
126 	.name = "sandbox_clk_test",
127 	.id = UCLASS_MISC,
128 	.of_match = sandbox_clk_test_ids,
129 	.priv_auto_alloc_size = sizeof(struct sandbox_clk_test),
130 };
131