1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2014, The Linux Foundation. All rights reserved. |
4 | */ |
5 | |
6 | #include <linux/kernel.h> |
7 | #include <linux/bitops.h> |
8 | #include <linux/regmap.h> |
9 | #include <linux/export.h> |
10 | |
11 | #include "clk-regmap-mux.h" |
12 | |
13 | static inline struct clk_regmap_mux *to_clk_regmap_mux(struct clk_hw *hw) |
14 | { |
15 | return container_of(to_clk_regmap(hw), struct clk_regmap_mux, clkr); |
16 | } |
17 | |
18 | static u8 mux_get_parent(struct clk_hw *hw) |
19 | { |
20 | struct clk_regmap_mux *mux = to_clk_regmap_mux(hw); |
21 | struct clk_regmap *clkr = to_clk_regmap(hw); |
22 | unsigned int mask = GENMASK(mux->width - 1, 0); |
23 | unsigned int val; |
24 | |
25 | regmap_read(map: clkr->regmap, reg: mux->reg, val: &val); |
26 | |
27 | val >>= mux->shift; |
28 | val &= mask; |
29 | |
30 | if (mux->parent_map) |
31 | return qcom_find_cfg_index(hw, map: mux->parent_map, cfg: val); |
32 | |
33 | return val; |
34 | } |
35 | |
36 | static int mux_set_parent(struct clk_hw *hw, u8 index) |
37 | { |
38 | struct clk_regmap_mux *mux = to_clk_regmap_mux(hw); |
39 | struct clk_regmap *clkr = to_clk_regmap(hw); |
40 | unsigned int mask = GENMASK(mux->width + mux->shift - 1, mux->shift); |
41 | unsigned int val; |
42 | |
43 | if (mux->parent_map) |
44 | index = mux->parent_map[index].cfg; |
45 | |
46 | val = index; |
47 | val <<= mux->shift; |
48 | |
49 | return regmap_update_bits(map: clkr->regmap, reg: mux->reg, mask, val); |
50 | } |
51 | |
52 | const struct clk_ops clk_regmap_mux_closest_ops = { |
53 | .get_parent = mux_get_parent, |
54 | .set_parent = mux_set_parent, |
55 | .determine_rate = __clk_mux_determine_rate_closest, |
56 | }; |
57 | EXPORT_SYMBOL_GPL(clk_regmap_mux_closest_ops); |
58 | |