16a1c7cefSSimon Glass /*
26a1c7cefSSimon Glass * (C) Copyright 2015 Google, Inc
36a1c7cefSSimon Glass *
46a1c7cefSSimon Glass * SPDX-License-Identifier: GPL-2.0
56a1c7cefSSimon Glass */
66a1c7cefSSimon Glass
76a1c7cefSSimon Glass #include <common.h>
8135aa950SStephen Warren #include <clk-uclass.h>
96a1c7cefSSimon Glass #include <dm.h>
106a1c7cefSSimon Glass #include <errno.h>
11135aa950SStephen Warren #include <asm/clk.h>
126a1c7cefSSimon Glass
136a1c7cefSSimon Glass struct sandbox_clk_priv {
14135aa950SStephen Warren ulong rate[SANDBOX_CLK_ID_COUNT];
15135aa950SStephen Warren bool enabled[SANDBOX_CLK_ID_COUNT];
166a1c7cefSSimon Glass };
176a1c7cefSSimon Glass
sandbox_clk_get_rate(struct clk * clk)18135aa950SStephen Warren static ulong sandbox_clk_get_rate(struct clk *clk)
196a1c7cefSSimon Glass {
20135aa950SStephen Warren struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
216a1c7cefSSimon Glass
22*df8b0a03SStephen Warren if (clk->id >= SANDBOX_CLK_ID_COUNT)
23135aa950SStephen Warren return -EINVAL;
24135aa950SStephen Warren
25135aa950SStephen Warren return priv->rate[clk->id];
266a1c7cefSSimon Glass }
276a1c7cefSSimon Glass
sandbox_clk_set_rate(struct clk * clk,ulong rate)28135aa950SStephen Warren static ulong sandbox_clk_set_rate(struct clk *clk, ulong rate)
296a1c7cefSSimon Glass {
30135aa950SStephen Warren struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
31135aa950SStephen Warren ulong old_rate;
32135aa950SStephen Warren
33*df8b0a03SStephen Warren if (clk->id >= SANDBOX_CLK_ID_COUNT)
34135aa950SStephen Warren return -EINVAL;
356a1c7cefSSimon Glass
366a1c7cefSSimon Glass if (!rate)
376a1c7cefSSimon Glass return -EINVAL;
386a1c7cefSSimon Glass
39135aa950SStephen Warren old_rate = priv->rate[clk->id];
40135aa950SStephen Warren priv->rate[clk->id] = rate;
416a1c7cefSSimon Glass
426a1c7cefSSimon Glass return old_rate;
436a1c7cefSSimon Glass }
446a1c7cefSSimon Glass
sandbox_clk_enable(struct clk * clk)45135aa950SStephen Warren static int sandbox_clk_enable(struct clk *clk)
466a1c7cefSSimon Glass {
47135aa950SStephen Warren struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
486a1c7cefSSimon Glass
49*df8b0a03SStephen Warren if (clk->id >= SANDBOX_CLK_ID_COUNT)
50135aa950SStephen Warren return -EINVAL;
51135aa950SStephen Warren
52135aa950SStephen Warren priv->enabled[clk->id] = true;
53135aa950SStephen Warren
54135aa950SStephen Warren return 0;
55135aa950SStephen Warren }
56135aa950SStephen Warren
sandbox_clk_disable(struct clk * clk)57135aa950SStephen Warren static int sandbox_clk_disable(struct clk *clk)
58135aa950SStephen Warren {
59135aa950SStephen Warren struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
60135aa950SStephen Warren
61*df8b0a03SStephen Warren if (clk->id >= SANDBOX_CLK_ID_COUNT)
62135aa950SStephen Warren return -EINVAL;
63135aa950SStephen Warren
64135aa950SStephen Warren priv->enabled[clk->id] = false;
656a1c7cefSSimon Glass
666a1c7cefSSimon Glass return 0;
676a1c7cefSSimon Glass }
686a1c7cefSSimon Glass
696a1c7cefSSimon Glass static struct clk_ops sandbox_clk_ops = {
706a1c7cefSSimon Glass .get_rate = sandbox_clk_get_rate,
716a1c7cefSSimon Glass .set_rate = sandbox_clk_set_rate,
72135aa950SStephen Warren .enable = sandbox_clk_enable,
73135aa950SStephen Warren .disable = sandbox_clk_disable,
746a1c7cefSSimon Glass };
756a1c7cefSSimon Glass
766a1c7cefSSimon Glass static const struct udevice_id sandbox_clk_ids[] = {
776a1c7cefSSimon Glass { .compatible = "sandbox,clk" },
786a1c7cefSSimon Glass { }
796a1c7cefSSimon Glass };
806a1c7cefSSimon Glass
816a1c7cefSSimon Glass U_BOOT_DRIVER(clk_sandbox) = {
826a1c7cefSSimon Glass .name = "clk_sandbox",
836a1c7cefSSimon Glass .id = UCLASS_CLK,
846a1c7cefSSimon Glass .of_match = sandbox_clk_ids,
856a1c7cefSSimon Glass .ops = &sandbox_clk_ops,
866a1c7cefSSimon Glass .priv_auto_alloc_size = sizeof(struct sandbox_clk_priv),
876a1c7cefSSimon Glass };
88135aa950SStephen Warren
sandbox_clk_query_rate(struct udevice * dev,int id)89135aa950SStephen Warren ulong sandbox_clk_query_rate(struct udevice *dev, int id)
90135aa950SStephen Warren {
91135aa950SStephen Warren struct sandbox_clk_priv *priv = dev_get_priv(dev);
92135aa950SStephen Warren
93135aa950SStephen Warren if (id < 0 || id >= SANDBOX_CLK_ID_COUNT)
94135aa950SStephen Warren return -EINVAL;
95135aa950SStephen Warren
96135aa950SStephen Warren return priv->rate[id];
97135aa950SStephen Warren }
98135aa950SStephen Warren
sandbox_clk_query_enable(struct udevice * dev,int id)99135aa950SStephen Warren int sandbox_clk_query_enable(struct udevice *dev, int id)
100135aa950SStephen Warren {
101135aa950SStephen Warren struct sandbox_clk_priv *priv = dev_get_priv(dev);
102135aa950SStephen Warren
103135aa950SStephen Warren if (id < 0 || id >= SANDBOX_CLK_ID_COUNT)
104135aa950SStephen Warren return -EINVAL;
105135aa950SStephen Warren
106135aa950SStephen Warren return priv->enabled[id];
107135aa950SStephen Warren }
108