1 /*
2 * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
3 *
4 * Base on code in drivers/clk/clk-gate.c.
5 * See clk-gate.c for further copyright information.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18 #include "clk-regmap.h"
19
20 #define to_clk_regmap_gate(_hw) container_of(_hw, struct clk_regmap_gate, hw)
21
clk_regmap_gate_prepare(struct clk_hw * hw)22 static int clk_regmap_gate_prepare(struct clk_hw *hw)
23 {
24 struct clk_regmap_gate *gate = to_clk_regmap_gate(hw);
25
26 return regmap_write(gate->regmap, gate->reg,
27 0 | BIT(gate->shift + 16));
28 }
29
clk_regmap_gate_unprepare(struct clk_hw * hw)30 static void clk_regmap_gate_unprepare(struct clk_hw *hw)
31 {
32 struct clk_regmap_gate *gate = to_clk_regmap_gate(hw);
33
34 regmap_write(gate->regmap, gate->reg,
35 BIT(gate->shift) | BIT(gate->shift + 16));
36 }
37
clk_regmap_gate_is_prepared(struct clk_hw * hw)38 static int clk_regmap_gate_is_prepared(struct clk_hw *hw)
39 {
40 struct clk_regmap_gate *gate = to_clk_regmap_gate(hw);
41 u32 val;
42
43 regmap_read(gate->regmap, gate->reg, &val);
44
45 return !(val & BIT(gate->shift));
46 }
47
48 const struct clk_ops clk_regmap_gate_ops = {
49 .prepare = clk_regmap_gate_prepare,
50 .unprepare = clk_regmap_gate_unprepare,
51 .is_prepared = clk_regmap_gate_is_prepared,
52 };
53 EXPORT_SYMBOL_GPL(clk_regmap_gate_ops);
54
55 struct clk *
devm_clk_regmap_register_gate(struct device * dev,const char * name,const char * parent_name,struct regmap * regmap,u32 reg,u8 shift,unsigned long flags)56 devm_clk_regmap_register_gate(struct device *dev, const char *name,
57 const char *parent_name,
58 struct regmap *regmap, u32 reg, u8 shift,
59 unsigned long flags)
60 {
61 struct clk_regmap_gate *gate;
62 struct clk_init_data init = {};
63
64 gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
65 if (!gate)
66 return ERR_PTR(-ENOMEM);
67
68 init.name = name;
69 init.ops = &clk_regmap_gate_ops;
70 init.flags = flags;
71 init.parent_names = (parent_name ? &parent_name : NULL);
72 init.num_parents = (parent_name ? 1 : 0);
73
74 gate->dev = dev;
75 gate->regmap = regmap;
76 gate->reg = reg;
77 gate->shift = shift;
78 gate->hw.init = &init;
79
80 return devm_clk_register(dev, &gate->hw);
81 }
82 EXPORT_SYMBOL_GPL(devm_clk_regmap_register_gate);
83