2 * Clock driver for Hi655x
4 * Copyright (c) 2017, Linaro Ltd.
6 * Author: Daniel Lezcano <daniel.lezcano@linaro.org>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 #include <linux/clk-provider.h>
18 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <linux/regmap.h>
21 #include <linux/slab.h>
22 #include <linux/mfd/core.h>
23 #include <linux/mfd/hi655x-pmic.h>
25 #define HI655X_CLK_BASE HI655X_BUS_ADDR(0x1c)
26 #define HI655X_CLK_SET BIT(6)
29 struct hi655x_pmic
*hi655x
;
33 static unsigned long hi655x_clk_recalc_rate(struct clk_hw
*hw
,
34 unsigned long parent_rate
)
39 static int hi655x_clk_enable(struct clk_hw
*hw
, bool enable
)
41 struct hi655x_clk
*hi655x_clk
=
42 container_of(hw
, struct hi655x_clk
, clk_hw
);
44 struct hi655x_pmic
*hi655x
= hi655x_clk
->hi655x
;
46 return regmap_update_bits(hi655x
->regmap
, HI655X_CLK_BASE
,
47 HI655X_CLK_SET
, enable
? HI655X_CLK_SET
: 0);
50 static int hi655x_clk_prepare(struct clk_hw
*hw
)
52 return hi655x_clk_enable(hw
, true);
55 static void hi655x_clk_unprepare(struct clk_hw
*hw
)
57 hi655x_clk_enable(hw
, false);
60 static int hi655x_clk_is_prepared(struct clk_hw
*hw
)
62 struct hi655x_clk
*hi655x_clk
=
63 container_of(hw
, struct hi655x_clk
, clk_hw
);
64 struct hi655x_pmic
*hi655x
= hi655x_clk
->hi655x
;
68 ret
= regmap_read(hi655x
->regmap
, HI655X_CLK_BASE
, &val
);
72 return val
& HI655X_CLK_BASE
;
75 static const struct clk_ops hi655x_clk_ops
= {
76 .prepare
= hi655x_clk_prepare
,
77 .unprepare
= hi655x_clk_unprepare
,
78 .is_prepared
= hi655x_clk_is_prepared
,
79 .recalc_rate
= hi655x_clk_recalc_rate
,
82 static int hi655x_clk_probe(struct platform_device
*pdev
)
84 struct device
*parent
= pdev
->dev
.parent
;
85 struct hi655x_pmic
*hi655x
= dev_get_drvdata(parent
);
86 struct hi655x_clk
*hi655x_clk
;
87 const char *clk_name
= "hi655x-clk";
88 struct clk_init_data init
= {
90 .ops
= &hi655x_clk_ops
94 hi655x_clk
= devm_kzalloc(&pdev
->dev
, sizeof(*hi655x_clk
), GFP_KERNEL
);
98 of_property_read_string_index(parent
->of_node
, "clock-output-names",
101 hi655x_clk
->clk_hw
.init
= &init
;
102 hi655x_clk
->hi655x
= hi655x
;
104 platform_set_drvdata(pdev
, hi655x_clk
);
106 ret
= devm_clk_hw_register(&pdev
->dev
, &hi655x_clk
->clk_hw
);
110 return devm_of_clk_add_hw_provider(&pdev
->dev
, of_clk_hw_simple_get
,
111 &hi655x_clk
->clk_hw
);
114 static struct platform_driver hi655x_clk_driver
= {
115 .probe
= hi655x_clk_probe
,
117 .name
= "hi655x-clk",
121 module_platform_driver(hi655x_clk_driver
);
123 MODULE_DESCRIPTION("Clk driver for the hi655x series PMICs");
124 MODULE_AUTHOR("Daniel Lezcano <daniel.lezcano@linaro.org>");
125 MODULE_LICENSE("GPL");
126 MODULE_ALIAS("platform:hi655x-clk");