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