1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
2 | /* |
3 | * Marvell MVEBU pinctrl driver |
4 | * |
5 | * Authors: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> |
6 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> |
7 | */ |
8 | |
9 | #ifndef __PINCTRL_MVEBU_H__ |
10 | #define __PINCTRL_MVEBU_H__ |
11 | |
12 | /** |
13 | * struct mvebu_mpp_ctrl_data - private data for the mpp ctrl operations |
14 | * @base: base address of pinctrl hardware |
15 | * @regmap.map: regmap structure |
16 | * @regmap.offset: regmap offset |
17 | */ |
18 | struct mvebu_mpp_ctrl_data { |
19 | union { |
20 | void __iomem *base; |
21 | struct { |
22 | struct regmap *map; |
23 | u32 offset; |
24 | } regmap; |
25 | }; |
26 | }; |
27 | |
28 | /** |
29 | * struct mvebu_mpp_ctrl - describe a mpp control |
30 | * @name: name of the control group |
31 | * @pid: first pin id handled by this control |
32 | * @npins: number of pins controlled by this control |
33 | * @mpp_get: (optional) special function to get mpp setting |
34 | * @mpp_set: (optional) special function to set mpp setting |
35 | * @mpp_gpio_req: (optional) special function to request gpio |
36 | * @mpp_gpio_dir: (optional) special function to set gpio direction |
37 | * |
38 | * A mpp_ctrl describes a muxable unit, e.g. pin, group of pins, or |
39 | * internal function, inside the SoC. Each muxable unit can be switched |
40 | * between two or more different settings, e.g. assign mpp pin 13 to |
41 | * uart1 or sata. |
42 | * |
43 | * The mpp_get/_set functions are mandatory and are used to get/set a |
44 | * specific mode. The optional mpp_gpio_req/_dir functions can be used |
45 | * to allow pin settings with varying gpio pins. |
46 | */ |
47 | struct mvebu_mpp_ctrl { |
48 | const char *name; |
49 | u8 pid; |
50 | u8 npins; |
51 | unsigned *pins; |
52 | int (*mpp_get)(struct mvebu_mpp_ctrl_data *data, unsigned pid, |
53 | unsigned long *config); |
54 | int (*mpp_set)(struct mvebu_mpp_ctrl_data *data, unsigned pid, |
55 | unsigned long config); |
56 | int (*mpp_gpio_req)(struct mvebu_mpp_ctrl_data *data, unsigned pid); |
57 | int (*mpp_gpio_dir)(struct mvebu_mpp_ctrl_data *data, unsigned pid, |
58 | bool input); |
59 | }; |
60 | |
61 | /** |
62 | * struct mvebu_mpp_ctrl_setting - describe a mpp ctrl setting |
63 | * @val: ctrl setting value |
64 | * @name: ctrl setting name, e.g. uart2, spi0 - unique per mpp_mode |
65 | * @subname: (optional) additional ctrl setting name, e.g. rts, cts |
66 | * @variant: (optional) variant identifier mask |
67 | * @flags: (private) flags to store gpi/gpo/gpio capabilities |
68 | * |
69 | * A ctrl_setting describes a specific internal mux function that a mpp pin |
70 | * can be switched to. The value (val) will be written in the corresponding |
71 | * register for common mpp pin configuration registers on MVEBU. SoC specific |
72 | * mpp_get/_set function may use val to distinguish between different settings. |
73 | * |
74 | * The name will be used to switch to this setting in DT description, e.g. |
75 | * marvell,function = "uart2". subname is only for debugging purposes. |
76 | * |
77 | * If name is one of "gpi", "gpo", "gpio" gpio capabilities are |
78 | * parsed during initialization and stored in flags. |
79 | * |
80 | * The variant can be used to combine different revisions of one SoC to a |
81 | * common pinctrl driver. It is matched (AND) with variant of soc_info to |
82 | * determine if a setting is available on the current SoC revision. |
83 | */ |
84 | struct mvebu_mpp_ctrl_setting { |
85 | u8 val; |
86 | const char *name; |
87 | const char *subname; |
88 | u8 variant; |
89 | u8 flags; |
90 | #define MVEBU_SETTING_GPO (1 << 0) |
91 | #define MVEBU_SETTING_GPI (1 << 1) |
92 | }; |
93 | |
94 | /** |
95 | * struct mvebu_mpp_mode - link ctrl and settings |
96 | * @pid: first pin id handled by this mode |
97 | * @settings: list of settings available for this mode |
98 | * |
99 | * A mode connects all available settings with the corresponding mpp_ctrl |
100 | * given by pid. |
101 | */ |
102 | struct mvebu_mpp_mode { |
103 | u8 pid; |
104 | struct mvebu_mpp_ctrl_setting *settings; |
105 | }; |
106 | |
107 | /** |
108 | * struct mvebu_pinctrl_soc_info - SoC specific info passed to pinctrl-mvebu |
109 | * @variant: variant mask of soc_info |
110 | * @controls: list of available mvebu_mpp_ctrls |
111 | * @control_data: optional array, one entry for each control |
112 | * @ncontrols: number of available mvebu_mpp_ctrls |
113 | * @modes: list of available mvebu_mpp_modes |
114 | * @nmodes: number of available mvebu_mpp_modes |
115 | * @gpioranges: list of pinctrl_gpio_ranges |
116 | * @ngpioranges: number of available pinctrl_gpio_ranges |
117 | * |
118 | * This struct describes all pinctrl related information for a specific SoC. |
119 | * If variant is unequal 0 it will be matched (AND) with variant of each |
120 | * setting and allows to distinguish between different revisions of one SoC. |
121 | */ |
122 | struct mvebu_pinctrl_soc_info { |
123 | u8 variant; |
124 | const struct mvebu_mpp_ctrl *controls; |
125 | struct mvebu_mpp_ctrl_data *control_data; |
126 | int ncontrols; |
127 | struct mvebu_mpp_mode *modes; |
128 | int nmodes; |
129 | struct pinctrl_gpio_range *gpioranges; |
130 | int ngpioranges; |
131 | }; |
132 | |
133 | #define MPP_FUNC_CTRL(_idl, _idh, _name, _func) \ |
134 | { \ |
135 | .name = _name, \ |
136 | .pid = _idl, \ |
137 | .npins = _idh - _idl + 1, \ |
138 | .pins = (unsigned[_idh - _idl + 1]) { }, \ |
139 | .mpp_get = _func ## _get, \ |
140 | .mpp_set = _func ## _set, \ |
141 | .mpp_gpio_req = NULL, \ |
142 | .mpp_gpio_dir = NULL, \ |
143 | } |
144 | |
145 | #define MPP_FUNC_GPIO_CTRL(_idl, _idh, _name, _func) \ |
146 | { \ |
147 | .name = _name, \ |
148 | .pid = _idl, \ |
149 | .npins = _idh - _idl + 1, \ |
150 | .pins = (unsigned[_idh - _idl + 1]) { }, \ |
151 | .mpp_get = _func ## _get, \ |
152 | .mpp_set = _func ## _set, \ |
153 | .mpp_gpio_req = _func ## _gpio_req, \ |
154 | .mpp_gpio_dir = _func ## _gpio_dir, \ |
155 | } |
156 | |
157 | #define _MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ |
158 | { \ |
159 | .val = _val, \ |
160 | .name = _name, \ |
161 | .subname = _subname, \ |
162 | .variant = _mask, \ |
163 | .flags = 0, \ |
164 | } |
165 | |
166 | #if defined(CONFIG_DEBUG_FS) |
167 | #define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ |
168 | _MPP_VAR_FUNCTION(_val, _name, _subname, _mask) |
169 | #else |
170 | #define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ |
171 | _MPP_VAR_FUNCTION(_val, _name, NULL, _mask) |
172 | #endif |
173 | |
174 | #define MPP_FUNCTION(_val, _name, _subname) \ |
175 | MPP_VAR_FUNCTION(_val, _name, _subname, (u8)-1) |
176 | |
177 | #define MPP_MODE(_id, ...) \ |
178 | { \ |
179 | .pid = _id, \ |
180 | .settings = (struct mvebu_mpp_ctrl_setting[]){ \ |
181 | __VA_ARGS__, { } }, \ |
182 | } |
183 | |
184 | #define MPP_GPIO_RANGE(_id, _pinbase, _gpiobase, _npins) \ |
185 | { \ |
186 | .name = "mvebu-gpio", \ |
187 | .id = _id, \ |
188 | .pin_base = _pinbase, \ |
189 | .base = _gpiobase, \ |
190 | .npins = _npins, \ |
191 | } |
192 | |
193 | #define MVEBU_MPPS_PER_REG 8 |
194 | #define MVEBU_MPP_BITS 4 |
195 | #define MVEBU_MPP_MASK 0xf |
196 | |
197 | int mvebu_mmio_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid, |
198 | unsigned long *config); |
199 | int mvebu_mmio_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid, |
200 | unsigned long config); |
201 | int mvebu_regmap_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid, |
202 | unsigned long *config); |
203 | int mvebu_regmap_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid, |
204 | unsigned long config); |
205 | |
206 | int mvebu_pinctrl_probe(struct platform_device *pdev); |
207 | int mvebu_pinctrl_simple_mmio_probe(struct platform_device *pdev); |
208 | int mvebu_pinctrl_simple_regmap_probe(struct platform_device *pdev, |
209 | struct device *syscon_dev, u32 offset); |
210 | |
211 | #endif |
212 | |