1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2017 Sanechips Technology Co., Ltd.
4  * Copyright 2017 Linaro Ltd.
5  */
6 
7 #ifndef __PINCTRL_ZX_H
8 #define __PINCTRL_ZX_H
9 
10 /**
11  * struct zx_mux_desc - hardware mux descriptor
12  * @name: mux function name
13  * @muxval: mux register bit value
14  */
15 struct zx_mux_desc {
16 	const char *name;
17 	u8 muxval;
18 };
19 
20 /**
21  * struct zx_pin_data - hardware per-pin data
22  * @aon_pin: whether it's an AON pin
23  * @offset: register offset within TOP pinmux controller
24  * @bitpos: bit position within TOP pinmux register
25  * @width: bit width within TOP pinmux register
26  * @coffset: pinconf register offset within AON controller
27  * @cbitpos: pinconf bit position within AON register
28  * @muxes: available mux function names and corresponding register values
29  *
30  * Unlike TOP pinmux and AON pinconf registers which are arranged pretty
31  * arbitrarily, AON pinmux register bits are well organized per pin id, and
32  * each pin occupies two bits, so that we can calculate the AON register offset
33  * and bit position from pin id.  Thus, we only need to define TOP pinmux and
34  * AON pinconf register data for the pin.
35  */
36 struct zx_pin_data {
37 	bool aon_pin;
38 	u16 offset;
39 	u16 bitpos;
40 	u16 width;
41 	u16 coffset;
42 	u16 cbitpos;
43 	struct zx_mux_desc *muxes;
44 };
45 
46 struct zx_pinctrl_soc_info {
47 	const struct pinctrl_pin_desc *pins;
48 	unsigned int npins;
49 };
50 
51 #define TOP_PIN(pin, off, bp, wd, coff, cbp, ...) {		\
52 	.number = pin,						\
53 	.name = #pin,						\
54 	.drv_data = &(struct zx_pin_data) {			\
55 		.aon_pin = false,				\
56 		.offset = off,					\
57 		.bitpos = bp,					\
58 		.width = wd,					\
59 		.coffset = coff,				\
60 		.cbitpos = cbp,					\
61 		.muxes = (struct zx_mux_desc[]) {		\
62 			 __VA_ARGS__, { } },			\
63 	},							\
64 }
65 
66 #define AON_PIN(pin, off, bp, wd, coff, cbp, ...) {		\
67 	.number = pin,						\
68 	.name = #pin,						\
69 	.drv_data = &(struct zx_pin_data) {			\
70 		.aon_pin = true,				\
71 		.offset = off,					\
72 		.bitpos = bp,					\
73 		.width = wd,					\
74 		.coffset = coff,				\
75 		.cbitpos = cbp,					\
76 		.muxes = (struct zx_mux_desc[]) {		\
77 			 __VA_ARGS__, { } },			\
78 	},							\
79 }
80 
81 #define ZX_RESERVED(pin) PINCTRL_PIN(pin, #pin)
82 
83 #define TOP_MUX(_val, _name) {					\
84 	.name = _name,						\
85 	.muxval = _val,						\
86 }
87 
88 /*
89  * When the flag is set, it's a mux configuration for an AON pin that sits in
90  * AON register.  Otherwise, it's one for AON pin but sitting in TOP register.
91  */
92 #define AON_MUX_FLAG BIT(7)
93 
94 #define AON_MUX(_val, _name) {					\
95 	.name = _name,						\
96 	.muxval = _val | AON_MUX_FLAG,				\
97 }
98 
99 int zx_pinctrl_init(struct platform_device *pdev,
100 		    struct zx_pinctrl_soc_info *info);
101 
102 #endif /* __PINCTRL_ZX_H */
103