]>
Commit | Line | Data |
---|---|---|
2874c5fd | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
7e8d9415 SH |
2 | /* |
3 | * Marvell MVEBU pinctrl driver | |
4 | * | |
5 | * Authors: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | |
6 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | |
7e8d9415 SH |
7 | */ |
8 | ||
9 | #ifndef __PINCTRL_MVEBU_H__ | |
10 | #define __PINCTRL_MVEBU_H__ | |
11 | ||
20955c5f RK |
12 | /** |
13 | * struct mvebu_mpp_ctrl_data - private data for the mpp ctrl operations | |
14 | * @base: base address of pinctrl hardware | |
d068b098 RK |
15 | * @regmap.map: regmap structure |
16 | * @regmap.offset: regmap offset | |
20955c5f RK |
17 | */ |
18 | struct mvebu_mpp_ctrl_data { | |
d068b098 RK |
19 | union { |
20 | void __iomem *base; | |
21 | struct { | |
22 | struct regmap *map; | |
23 | u32 offset; | |
24 | } regmap; | |
25 | }; | |
20955c5f RK |
26 | }; |
27 | ||
7e8d9415 SH |
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 | * | |
cffa7a6b TP |
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. | |
7e8d9415 SH |
46 | */ |
47 | struct mvebu_mpp_ctrl { | |
48 | const char *name; | |
49 | u8 pid; | |
50 | u8 npins; | |
51 | unsigned *pins; | |
20955c5f RK |
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); | |
7e8d9415 SH |
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 | |
20955c5f | 111 | * @control_data: optional array, one entry for each control |
7e8d9415 SH |
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; | |
30be3fb9 | 124 | const struct mvebu_mpp_ctrl *controls; |
20955c5f | 125 | struct mvebu_mpp_ctrl_data *control_data; |
7e8d9415 SH |
126 | int ncontrols; |
127 | struct mvebu_mpp_mode *modes; | |
128 | int nmodes; | |
129 | struct pinctrl_gpio_range *gpioranges; | |
130 | int ngpioranges; | |
131 | }; | |
132 | ||
7e8d9415 SH |
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 | ||
f5b85e42 SH |
193 | #define MVEBU_MPPS_PER_REG 8 |
194 | #define MVEBU_MPP_BITS 4 | |
195 | #define MVEBU_MPP_MASK 0xf | |
196 | ||
44aa9d06 RK |
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); | |
d068b098 RK |
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); | |
44aa9d06 | 205 | |
7e8d9415 | 206 | int mvebu_pinctrl_probe(struct platform_device *pdev); |
44aa9d06 | 207 | int mvebu_pinctrl_simple_mmio_probe(struct platform_device *pdev); |
d068b098 | 208 | int mvebu_pinctrl_simple_regmap_probe(struct platform_device *pdev, |
ef088187 | 209 | struct device *syscon_dev, u32 offset); |
7e8d9415 SH |
210 | |
211 | #endif |