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