1 // SPDX-License-Identifier: GPL-2.0
3 // Spreadtrum multiplexer clock driver
5 // Copyright (C) 2017 Spreadtrum, Inc.
6 // Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
9 #include <linux/clk-provider.h>
10 #include <linux/regmap.h>
14 u8
sprd_mux_helper_get_parent(const struct sprd_clk_common
*common
,
15 const struct sprd_mux_ssel
*mux
)
22 regmap_read(common
->regmap
, common
->reg
, ®
);
23 parent
= reg
>> mux
->shift
;
24 parent
&= (1 << mux
->width
) - 1;
29 num_parents
= clk_hw_get_num_parents(&common
->hw
);
31 for (i
= 0; i
< num_parents
- 1; i
++)
32 if (parent
>= mux
->table
[i
] && parent
< mux
->table
[i
+ 1])
35 return num_parents
- 1;
37 EXPORT_SYMBOL_GPL(sprd_mux_helper_get_parent
);
39 static u8
sprd_mux_get_parent(struct clk_hw
*hw
)
41 struct sprd_mux
*cm
= hw_to_sprd_mux(hw
);
43 return sprd_mux_helper_get_parent(&cm
->common
, &cm
->mux
);
46 int sprd_mux_helper_set_parent(const struct sprd_clk_common
*common
,
47 const struct sprd_mux_ssel
*mux
,
53 index
= mux
->table
[index
];
55 regmap_read(common
->regmap
, common
->reg
, ®
);
56 reg
&= ~GENMASK(mux
->width
+ mux
->shift
- 1, mux
->shift
);
57 regmap_write(common
->regmap
, common
->reg
,
58 reg
| (index
<< mux
->shift
));
62 EXPORT_SYMBOL_GPL(sprd_mux_helper_set_parent
);
64 static int sprd_mux_set_parent(struct clk_hw
*hw
, u8 index
)
66 struct sprd_mux
*cm
= hw_to_sprd_mux(hw
);
68 return sprd_mux_helper_set_parent(&cm
->common
, &cm
->mux
, index
);
71 const struct clk_ops sprd_mux_ops
= {
72 .get_parent
= sprd_mux_get_parent
,
73 .set_parent
= sprd_mux_set_parent
,
74 .determine_rate
= __clk_mux_determine_rate
,
76 EXPORT_SYMBOL_GPL(sprd_mux_ops
);