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