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