Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1/* SPDX-License-Identifier: GPL-2.0 */
  2#ifndef _CCU_MUX_H_
  3#define _CCU_MUX_H_
  4
  5#include <linux/clk-provider.h>
  6
  7#include "ccu_common.h"
  8
  9struct ccu_mux_fixed_prediv {
 10	u8	index;
 11	u16	div;
 12};
 13
 14struct ccu_mux_var_prediv {
 15	u8	index;
 16	u8	shift;
 17	u8	width;
 18};
 19
 20struct ccu_mux_internal {
 21	u8		shift;
 22	u8		width;
 23	const u8	*table;
 24
 25	const struct ccu_mux_fixed_prediv	*fixed_predivs;
 26	u8		n_predivs;
 27
 28	const struct ccu_mux_var_prediv		*var_predivs;
 29	u8		n_var_predivs;
 30};
 31
 32#define _SUNXI_CCU_MUX_TABLE(_shift, _width, _table)	\
 33	{						\
 34		.shift	= _shift,			\
 35		.width	= _width,			\
 36		.table	= _table,			\
 37	}
 38
 39#define _SUNXI_CCU_MUX(_shift, _width) \
 40	_SUNXI_CCU_MUX_TABLE(_shift, _width, NULL)
 41
 42struct ccu_mux {
 43	u16			reg;
 44	u32			enable;
 45
 46	struct ccu_mux_internal	mux;
 47	struct ccu_common	common;
 48};
 49
 50#define SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, _table,	\
 51				     _reg, _shift, _width, _gate,	\
 52				     _flags)				\
 53	struct ccu_mux _struct = {					\
 54		.enable	= _gate,					\
 55		.mux	= _SUNXI_CCU_MUX_TABLE(_shift, _width, _table),	\
 56		.common	= {						\
 57			.reg		= _reg,				\
 58			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\
 59							      _parents, \
 60							      &ccu_mux_ops, \
 61							      _flags),	\
 62		}							\
 63	}
 64
 65#define SUNXI_CCU_MUX_WITH_GATE(_struct, _name, _parents, _reg,		\
 66				_shift, _width, _gate, _flags)		\
 67	SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL,	\
 68				      _reg, _shift, _width, _gate,	\
 69				      _flags)
 70
 71#define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width,	\
 72		      _flags)						\
 73	SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL,	\
 74				      _reg, _shift, _width, 0, _flags)
 75
 76static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)
 77{
 78	struct ccu_common *common = hw_to_ccu_common(hw);
 79
 80	return container_of(common, struct ccu_mux, common);
 81}
 82
 83extern const struct clk_ops ccu_mux_ops;
 84
 85unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common,
 86					  struct ccu_mux_internal *cm,
 87					  int parent_index,
 88					  unsigned long parent_rate);
 89int ccu_mux_helper_determine_rate(struct ccu_common *common,
 90				  struct ccu_mux_internal *cm,
 91				  struct clk_rate_request *req,
 92				  unsigned long (*round)(struct ccu_mux_internal *,
 93							 struct clk_hw *,
 94							 unsigned long *,
 95							 unsigned long,
 96							 void *),
 97				  void *data);
 98u8 ccu_mux_helper_get_parent(struct ccu_common *common,
 99			     struct ccu_mux_internal *cm);
100int ccu_mux_helper_set_parent(struct ccu_common *common,
101			      struct ccu_mux_internal *cm,
102			      u8 index);
103
104struct ccu_mux_nb {
105	struct notifier_block	clk_nb;
106	struct ccu_common	*common;
107	struct ccu_mux_internal	*cm;
108
109	u32	delay_us;	/* How many us to wait after reparenting */
110	u8	bypass_index;	/* Which parent to temporarily use */
111	u8	original_index;	/* This is set by the notifier callback */
112};
113
114#define to_ccu_mux_nb(_nb) container_of(_nb, struct ccu_mux_nb, clk_nb)
115
116int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb);
117
118#endif /* _CCU_MUX_H_ */