1/* SPDX-License-Identifier: GPL-2.0 */
2//
3// Spreadtrum multiplexer clock driver
4//
5// Copyright (C) 2017 Spreadtrum, Inc.
6// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
7
8#ifndef _SPRD_MUX_H_
9#define _SPRD_MUX_H_
10
11#include "common.h"
12
13/**
14 * struct sprd_mux_ssel - Mux clock's source select bits in its register
15 * @shift: Bit offset of the divider in its register
16 * @width: Width of the divider field in its register
17 * @table: For some mux clocks, not all sources are used on some special
18 *	   chips, this matches the value of mux clock's register and the
19 *	   sources which are used for this mux clock
20 */
21struct sprd_mux_ssel {
22	u8		shift;
23	u8		width;
24	const u8	*table;
25};
26
27struct sprd_mux {
28	struct sprd_mux_ssel mux;
29	struct sprd_clk_common	common;
30};
31
32#define _SPRD_MUX_CLK(_shift, _width, _table)		\
33	{						\
34		.shift	= _shift,			\
35		.width	= _width,			\
36		.table	= _table,			\
37	}
38
39#define SPRD_MUX_CLK_HW_INIT_FN(_struct, _name, _parents, _table,	\
40				_reg, _shift, _width, _flags, _fn)	\
41	struct sprd_mux _struct = {					\
42		.mux	= _SPRD_MUX_CLK(_shift, _width, _table),	\
43		.common	= {						\
44			.regmap		= NULL,				\
45			.reg		= _reg,				\
46			.hw.init = _fn(_name, _parents,			\
47				       &sprd_mux_ops, _flags),		\
48		}							\
49	}
50
51#define SPRD_MUX_CLK_TABLE(_struct, _name, _parents, _table,		\
52			   _reg, _shift, _width, _flags)		\
53	SPRD_MUX_CLK_HW_INIT_FN(_struct, _name, _parents, _table,	\
54				_reg, _shift, _width, _flags,		\
55				CLK_HW_INIT_PARENTS)
56
57#define SPRD_MUX_CLK(_struct, _name, _parents, _reg,		\
58		     _shift, _width, _flags)			\
59	SPRD_MUX_CLK_TABLE(_struct, _name, _parents, NULL,	\
60			   _reg, _shift, _width, _flags)
61
62#define SPRD_MUX_CLK_DATA_TABLE(_struct, _name, _parents, _table,	\
63				_reg, _shift, _width, _flags)		\
64	SPRD_MUX_CLK_HW_INIT_FN(_struct, _name, _parents, _table,	\
65				_reg, _shift, _width, _flags,		\
66				CLK_HW_INIT_PARENTS_DATA)
67
68#define SPRD_MUX_CLK_DATA(_struct, _name, _parents, _reg,		\
69			  _shift, _width, _flags)			\
70	SPRD_MUX_CLK_DATA_TABLE(_struct, _name, _parents, NULL,		\
71				_reg, _shift, _width, _flags)
72
73static inline struct sprd_mux *hw_to_sprd_mux(const struct clk_hw *hw)
74{
75	struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
76
77	return container_of(common, struct sprd_mux, common);
78}
79
80extern const struct clk_ops sprd_mux_ops;
81
82u8 sprd_mux_helper_get_parent(const struct sprd_clk_common *common,
83			      const struct sprd_mux_ssel *mux);
84int sprd_mux_helper_set_parent(const struct sprd_clk_common *common,
85			       const struct sprd_mux_ssel *mux,
86			       u8 index);
87
88#endif /* _SPRD_MUX_H_ */
89