xref: /openbmc/linux/drivers/clk/qcom/clk-regmap-phy-mux.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1*74e4190cSDmitry Baryshkov // SPDX-License-Identifier: GPL-2.0-only
2*74e4190cSDmitry Baryshkov /*
3*74e4190cSDmitry Baryshkov  * Copyright (c) 2022, Linaro Ltd.
4*74e4190cSDmitry Baryshkov  */
5*74e4190cSDmitry Baryshkov 
6*74e4190cSDmitry Baryshkov #include <linux/clk-provider.h>
7*74e4190cSDmitry Baryshkov #include <linux/bitfield.h>
8*74e4190cSDmitry Baryshkov #include <linux/regmap.h>
9*74e4190cSDmitry Baryshkov #include <linux/export.h>
10*74e4190cSDmitry Baryshkov 
11*74e4190cSDmitry Baryshkov #include "clk-regmap.h"
12*74e4190cSDmitry Baryshkov #include "clk-regmap-phy-mux.h"
13*74e4190cSDmitry Baryshkov 
14*74e4190cSDmitry Baryshkov #define PHY_MUX_MASK		GENMASK(1, 0)
15*74e4190cSDmitry Baryshkov #define PHY_MUX_PHY_SRC		0
16*74e4190cSDmitry Baryshkov #define PHY_MUX_REF_SRC		2
17*74e4190cSDmitry Baryshkov 
to_clk_regmap_phy_mux(struct clk_regmap * clkr)18*74e4190cSDmitry Baryshkov static inline struct clk_regmap_phy_mux *to_clk_regmap_phy_mux(struct clk_regmap *clkr)
19*74e4190cSDmitry Baryshkov {
20*74e4190cSDmitry Baryshkov 	return container_of(clkr, struct clk_regmap_phy_mux, clkr);
21*74e4190cSDmitry Baryshkov }
22*74e4190cSDmitry Baryshkov 
phy_mux_is_enabled(struct clk_hw * hw)23*74e4190cSDmitry Baryshkov static int phy_mux_is_enabled(struct clk_hw *hw)
24*74e4190cSDmitry Baryshkov {
25*74e4190cSDmitry Baryshkov 	struct clk_regmap *clkr = to_clk_regmap(hw);
26*74e4190cSDmitry Baryshkov 	struct clk_regmap_phy_mux *phy_mux = to_clk_regmap_phy_mux(clkr);
27*74e4190cSDmitry Baryshkov 	unsigned int val;
28*74e4190cSDmitry Baryshkov 
29*74e4190cSDmitry Baryshkov 	regmap_read(clkr->regmap, phy_mux->reg, &val);
30*74e4190cSDmitry Baryshkov 	val = FIELD_GET(PHY_MUX_MASK, val);
31*74e4190cSDmitry Baryshkov 
32*74e4190cSDmitry Baryshkov 	WARN_ON(val != PHY_MUX_PHY_SRC && val != PHY_MUX_REF_SRC);
33*74e4190cSDmitry Baryshkov 
34*74e4190cSDmitry Baryshkov 	return val == PHY_MUX_PHY_SRC;
35*74e4190cSDmitry Baryshkov }
36*74e4190cSDmitry Baryshkov 
phy_mux_enable(struct clk_hw * hw)37*74e4190cSDmitry Baryshkov static int phy_mux_enable(struct clk_hw *hw)
38*74e4190cSDmitry Baryshkov {
39*74e4190cSDmitry Baryshkov 	struct clk_regmap *clkr = to_clk_regmap(hw);
40*74e4190cSDmitry Baryshkov 	struct clk_regmap_phy_mux *phy_mux = to_clk_regmap_phy_mux(clkr);
41*74e4190cSDmitry Baryshkov 
42*74e4190cSDmitry Baryshkov 	return regmap_update_bits(clkr->regmap, phy_mux->reg,
43*74e4190cSDmitry Baryshkov 				  PHY_MUX_MASK,
44*74e4190cSDmitry Baryshkov 				  FIELD_PREP(PHY_MUX_MASK, PHY_MUX_PHY_SRC));
45*74e4190cSDmitry Baryshkov }
46*74e4190cSDmitry Baryshkov 
phy_mux_disable(struct clk_hw * hw)47*74e4190cSDmitry Baryshkov static void phy_mux_disable(struct clk_hw *hw)
48*74e4190cSDmitry Baryshkov {
49*74e4190cSDmitry Baryshkov 	struct clk_regmap *clkr = to_clk_regmap(hw);
50*74e4190cSDmitry Baryshkov 	struct clk_regmap_phy_mux *phy_mux = to_clk_regmap_phy_mux(clkr);
51*74e4190cSDmitry Baryshkov 
52*74e4190cSDmitry Baryshkov 	regmap_update_bits(clkr->regmap, phy_mux->reg,
53*74e4190cSDmitry Baryshkov 			   PHY_MUX_MASK,
54*74e4190cSDmitry Baryshkov 			   FIELD_PREP(PHY_MUX_MASK, PHY_MUX_REF_SRC));
55*74e4190cSDmitry Baryshkov }
56*74e4190cSDmitry Baryshkov 
57*74e4190cSDmitry Baryshkov const struct clk_ops clk_regmap_phy_mux_ops = {
58*74e4190cSDmitry Baryshkov 	.enable = phy_mux_enable,
59*74e4190cSDmitry Baryshkov 	.disable = phy_mux_disable,
60*74e4190cSDmitry Baryshkov 	.is_enabled = phy_mux_is_enabled,
61*74e4190cSDmitry Baryshkov };
62*74e4190cSDmitry Baryshkov EXPORT_SYMBOL_GPL(clk_regmap_phy_mux_ops);
63