1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2016 Socionext Inc.
4 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
7 #include <linux/clk-provider.h>
8 #include <linux/device.h>
9 #include <linux/regmap.h>
11 #include "clk-uniphier.h"
13 struct uniphier_clk_mux
{
15 struct regmap
*regmap
;
17 const unsigned int *masks
;
18 const unsigned int *vals
;
21 #define to_uniphier_clk_mux(_hw) container_of(_hw, struct uniphier_clk_mux, hw)
23 static int uniphier_clk_mux_set_parent(struct clk_hw
*hw
, u8 index
)
25 struct uniphier_clk_mux
*mux
= to_uniphier_clk_mux(hw
);
27 return regmap_write_bits(mux
->regmap
, mux
->reg
, mux
->masks
[index
],
31 static u8
uniphier_clk_mux_get_parent(struct clk_hw
*hw
)
33 struct uniphier_clk_mux
*mux
= to_uniphier_clk_mux(hw
);
34 unsigned int num_parents
= clk_hw_get_num_parents(hw
);
39 ret
= regmap_read(mux
->regmap
, mux
->reg
, &val
);
43 for (i
= 0; i
< num_parents
; i
++)
44 if ((mux
->masks
[i
] & val
) == mux
->vals
[i
])
50 static const struct clk_ops uniphier_clk_mux_ops
= {
51 .determine_rate
= __clk_mux_determine_rate
,
52 .set_parent
= uniphier_clk_mux_set_parent
,
53 .get_parent
= uniphier_clk_mux_get_parent
,
56 struct clk_hw
*uniphier_clk_register_mux(struct device
*dev
,
57 struct regmap
*regmap
,
59 const struct uniphier_clk_mux_data
*data
)
61 struct uniphier_clk_mux
*mux
;
62 struct clk_init_data init
;
65 mux
= devm_kzalloc(dev
, sizeof(*mux
), GFP_KERNEL
);
67 return ERR_PTR(-ENOMEM
);
70 init
.ops
= &uniphier_clk_mux_ops
;
71 init
.flags
= CLK_SET_RATE_PARENT
;
72 init
.parent_names
= data
->parent_names
;
73 init
.num_parents
= data
->num_parents
;
77 mux
->masks
= data
->masks
;
78 mux
->vals
= data
->vals
;
81 ret
= devm_clk_hw_register(dev
, &mux
->hw
);