1 // SPDX-License-Identifier: GPL-2.0-only
3 * Clock driver for Hi655x
5 * Copyright (c) 2017, Linaro Ltd.
7 * Author: Daniel Lezcano <daniel.lezcano@linaro.org>
9 #include <linux/clk-provider.h>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/regmap.h>
13 #include <linux/slab.h>
14 #include <linux/mfd/core.h>
15 #include <linux/mfd/hi655x-pmic.h>
17 #define HI655X_CLK_BASE HI655X_BUS_ADDR(0x1c)
18 #define HI655X_CLK_SET BIT(6)
21 struct hi655x_pmic
*hi655x
;
25 static unsigned long hi655x_clk_recalc_rate(struct clk_hw
*hw
,
26 unsigned long parent_rate
)
31 static int hi655x_clk_enable(struct clk_hw
*hw
, bool enable
)
33 struct hi655x_clk
*hi655x_clk
=
34 container_of(hw
, struct hi655x_clk
, clk_hw
);
36 struct hi655x_pmic
*hi655x
= hi655x_clk
->hi655x
;
38 return regmap_update_bits(hi655x
->regmap
, HI655X_CLK_BASE
,
39 HI655X_CLK_SET
, enable
? HI655X_CLK_SET
: 0);
42 static int hi655x_clk_prepare(struct clk_hw
*hw
)
44 return hi655x_clk_enable(hw
, true);
47 static void hi655x_clk_unprepare(struct clk_hw
*hw
)
49 hi655x_clk_enable(hw
, false);
52 static int hi655x_clk_is_prepared(struct clk_hw
*hw
)
54 struct hi655x_clk
*hi655x_clk
=
55 container_of(hw
, struct hi655x_clk
, clk_hw
);
56 struct hi655x_pmic
*hi655x
= hi655x_clk
->hi655x
;
60 ret
= regmap_read(hi655x
->regmap
, HI655X_CLK_BASE
, &val
);
64 return val
& HI655X_CLK_BASE
;
67 static const struct clk_ops hi655x_clk_ops
= {
68 .prepare
= hi655x_clk_prepare
,
69 .unprepare
= hi655x_clk_unprepare
,
70 .is_prepared
= hi655x_clk_is_prepared
,
71 .recalc_rate
= hi655x_clk_recalc_rate
,
74 static int hi655x_clk_probe(struct platform_device
*pdev
)
76 struct device
*parent
= pdev
->dev
.parent
;
77 struct hi655x_pmic
*hi655x
= dev_get_drvdata(parent
);
78 struct hi655x_clk
*hi655x_clk
;
79 const char *clk_name
= "hi655x-clk";
80 struct clk_init_data init
= {
82 .ops
= &hi655x_clk_ops
86 hi655x_clk
= devm_kzalloc(&pdev
->dev
, sizeof(*hi655x_clk
), GFP_KERNEL
);
90 of_property_read_string_index(parent
->of_node
, "clock-output-names",
93 hi655x_clk
->clk_hw
.init
= &init
;
94 hi655x_clk
->hi655x
= hi655x
;
96 platform_set_drvdata(pdev
, hi655x_clk
);
98 ret
= devm_clk_hw_register(&pdev
->dev
, &hi655x_clk
->clk_hw
);
102 return devm_of_clk_add_hw_provider(&pdev
->dev
, of_clk_hw_simple_get
,
103 &hi655x_clk
->clk_hw
);
106 static struct platform_driver hi655x_clk_driver
= {
107 .probe
= hi655x_clk_probe
,
109 .name
= "hi655x-clk",
113 module_platform_driver(hi655x_clk_driver
);
115 MODULE_DESCRIPTION("Clk driver for the hi655x series PMICs");
116 MODULE_AUTHOR("Daniel Lezcano <daniel.lezcano@linaro.org>");
117 MODULE_LICENSE("GPL");
118 MODULE_ALIAS("platform:hi655x-clk");