xref: /linux/drivers/clk/sunxi-ng/ccu_mux.h (revision 10accd2e6890b57db8e717e9aee91b791f90fe14)
1 #ifndef _CCU_MUX_H_
2 #define _CCU_MUX_H_
3 
4 #include <linux/clk-provider.h>
5 
6 #include "ccu_common.h"
7 
8 struct ccu_mux_internal {
9 	u8	shift;
10 	u8	width;
11 
12 	struct {
13 		u8	index;
14 		u8	div;
15 	} fixed_prediv;
16 
17 	struct {
18 		u8	index;
19 		u8	shift;
20 		u8	width;
21 	} variable_prediv;
22 };
23 
24 #define SUNXI_CLK_MUX(_shift, _width)	\
25 	{					\
26 		.shift	= _shift,		\
27 		.width	= _width,		\
28 	}
29 
30 struct ccu_mux {
31 	u16			reg;
32 	u32			enable;
33 
34 	struct ccu_mux_internal	mux;
35 	struct ccu_common	common;
36 };
37 
38 #define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width, _flags) \
39 	struct ccu_mux _struct = {					\
40 		.mux	= SUNXI_CLK_MUX(_shift, _width),		\
41 		.common	= {						\
42 			.reg		= _reg,				\
43 			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\
44 							      _parents, \
45 							      &ccu_mux_ops, \
46 							      _flags),	\
47 		}							\
48 	}
49 
50 #define SUNXI_CCU_MUX_WITH_GATE(_struct, _name, _parents, _reg,		\
51 				_shift, _width, _gate, _flags)		\
52 	struct ccu_mux _struct = {					\
53 		.enable	= _gate,					\
54 		.mux	= SUNXI_CLK_MUX(_shift, _width),		\
55 		.common	= {						\
56 			.reg		= _reg,				\
57 			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\
58 							      _parents, \
59 							      &ccu_mux_ops, \
60 							      _flags),	\
61 		}							\
62 	}
63 
64 static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)
65 {
66 	struct ccu_common *common = hw_to_ccu_common(hw);
67 
68 	return container_of(common, struct ccu_mux, common);
69 }
70 
71 extern const struct clk_ops ccu_mux_ops;
72 
73 void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common,
74 					     struct ccu_mux_internal *cm,
75 					     int parent_index,
76 					     unsigned long *parent_rate);
77 int ccu_mux_helper_determine_rate(struct ccu_common *common,
78 				  struct ccu_mux_internal *cm,
79 				  struct clk_rate_request *req,
80 				  unsigned long (*round)(struct ccu_mux_internal *,
81 							 unsigned long,
82 							 unsigned long,
83 							 void *),
84 				  void *data);
85 u8 ccu_mux_helper_get_parent(struct ccu_common *common,
86 			     struct ccu_mux_internal *cm);
87 int ccu_mux_helper_set_parent(struct ccu_common *common,
88 			      struct ccu_mux_internal *cm,
89 			      u8 index);
90 
91 #endif /* _CCU_MUX_H_ */
92