1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Copyright (C) 2018 MediaTek Inc. |
4 | * |
5 | * Author: Sean Wang <sean.wang@mediatek.com> |
6 | * |
7 | */ |
8 | |
9 | #ifndef __PINCTRL_MTK_COMMON_V2_H |
10 | #define __PINCTRL_MTK_COMMON_V2_H |
11 | |
12 | #include <linux/gpio/driver.h> |
13 | |
14 | #define MTK_INPUT 0 |
15 | #define MTK_OUTPUT 1 |
16 | #define MTK_DISABLE 0 |
17 | #define MTK_ENABLE 1 |
18 | #define MTK_PULLDOWN 0 |
19 | #define MTK_PULLUP 1 |
20 | #define MTK_PULL_PU_PD_TYPE BIT(0) |
21 | #define MTK_PULL_PULLSEL_TYPE BIT(1) |
22 | #define MTK_PULL_PUPD_R1R0_TYPE BIT(2) |
23 | /* MTK_PULL_RSEL_TYPE can select resistance and can be |
24 | * turned on/off itself. But it can't be selected pull up/down |
25 | */ |
26 | #define MTK_PULL_RSEL_TYPE BIT(3) |
27 | /* MTK_PULL_PU_PD_RSEL_TYPE is a type which is controlled by |
28 | * MTK_PULL_PU_PD_TYPE and MTK_PULL_RSEL_TYPE. |
29 | */ |
30 | #define MTK_PULL_PU_PD_RSEL_TYPE (MTK_PULL_PU_PD_TYPE \ |
31 | | MTK_PULL_RSEL_TYPE) |
32 | #define MTK_PULL_TYPE_MASK (MTK_PULL_PU_PD_TYPE |\ |
33 | MTK_PULL_PULLSEL_TYPE |\ |
34 | MTK_PULL_PUPD_R1R0_TYPE |\ |
35 | MTK_PULL_RSEL_TYPE) |
36 | |
37 | #define EINT_NA U16_MAX |
38 | #define NO_EINT_SUPPORT EINT_NA |
39 | |
40 | #define PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, \ |
41 | _s_bit, _x_bits, _sz_reg, _fixed) { \ |
42 | .s_pin = _s_pin, \ |
43 | .e_pin = _e_pin, \ |
44 | .i_base = _i_base, \ |
45 | .s_addr = _s_addr, \ |
46 | .x_addrs = _x_addrs, \ |
47 | .s_bit = _s_bit, \ |
48 | .x_bits = _x_bits, \ |
49 | .sz_reg = _sz_reg, \ |
50 | .fixed = _fixed, \ |
51 | } |
52 | |
53 | #define PIN_FIELD(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \ |
54 | PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit, \ |
55 | _x_bits, 32, 0) |
56 | |
57 | #define PINS_FIELD(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \ |
58 | PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit, \ |
59 | _x_bits, 32, 1) |
60 | |
61 | #define PIN_RSEL(_s_pin, _e_pin, _rsel_index, _up_resl, _down_rsel) { \ |
62 | .s_pin = _s_pin, \ |
63 | .e_pin = _e_pin, \ |
64 | .rsel_index = _rsel_index, \ |
65 | .up_rsel = _up_resl, \ |
66 | .down_rsel = _down_rsel, \ |
67 | } |
68 | |
69 | /* List these attributes which could be modified for the pin */ |
70 | enum { |
71 | PINCTRL_PIN_REG_MODE, |
72 | PINCTRL_PIN_REG_DIR, |
73 | PINCTRL_PIN_REG_DI, |
74 | PINCTRL_PIN_REG_DO, |
75 | PINCTRL_PIN_REG_SR, |
76 | PINCTRL_PIN_REG_SMT, |
77 | PINCTRL_PIN_REG_PD, |
78 | PINCTRL_PIN_REG_PU, |
79 | PINCTRL_PIN_REG_E4, |
80 | PINCTRL_PIN_REG_E8, |
81 | PINCTRL_PIN_REG_TDSEL, |
82 | PINCTRL_PIN_REG_RDSEL, |
83 | PINCTRL_PIN_REG_DRV, |
84 | PINCTRL_PIN_REG_PUPD, |
85 | PINCTRL_PIN_REG_R0, |
86 | PINCTRL_PIN_REG_R1, |
87 | PINCTRL_PIN_REG_IES, |
88 | PINCTRL_PIN_REG_PULLEN, |
89 | PINCTRL_PIN_REG_PULLSEL, |
90 | PINCTRL_PIN_REG_DRV_EN, |
91 | PINCTRL_PIN_REG_DRV_E0, |
92 | PINCTRL_PIN_REG_DRV_E1, |
93 | PINCTRL_PIN_REG_DRV_ADV, |
94 | PINCTRL_PIN_REG_RSEL, |
95 | PINCTRL_PIN_REG_MAX, |
96 | }; |
97 | |
98 | /* Group the pins by the driving current */ |
99 | enum { |
100 | DRV_FIXED, |
101 | DRV_GRP0, |
102 | DRV_GRP1, |
103 | DRV_GRP2, |
104 | DRV_GRP3, |
105 | DRV_GRP4, |
106 | DRV_GRP_MAX, |
107 | }; |
108 | |
109 | static const char * const mtk_default_register_base_names[] __maybe_unused = { |
110 | "base" , |
111 | }; |
112 | |
113 | /* struct mtk_pin_field - the structure that holds the information of the field |
114 | * used to describe the attribute for the pin |
115 | * @base: the index pointing to the entry in base address list |
116 | * @offset: the register offset relative to the base address |
117 | * @mask: the mask used to filter out the field from the register |
118 | * @bitpos: the start bit relative to the register |
119 | * @next: the indication that the field would be extended to the |
120 | next register |
121 | */ |
122 | struct mtk_pin_field { |
123 | u8 index; |
124 | u32 offset; |
125 | u32 mask; |
126 | u8 bitpos; |
127 | u8 next; |
128 | }; |
129 | |
130 | /* struct mtk_pin_field_calc - the structure that holds the range providing |
131 | * the guide used to look up the relevant field |
132 | * @s_pin: the start pin within the range |
133 | * @e_pin: the end pin within the range |
134 | * @i_base: the index pointing to the entry in base address list |
135 | * @s_addr: the start address for the range |
136 | * @x_addrs: the address distance between two consecutive registers |
137 | * within the range |
138 | * @s_bit: the start bit for the first register within the range |
139 | * @x_bits: the bit distance between two consecutive pins within |
140 | * the range |
141 | * @sz_reg: the size of bits in a register |
142 | * @fixed: the consecutive pins share the same bits with the 1st |
143 | * pin |
144 | */ |
145 | struct mtk_pin_field_calc { |
146 | u16 s_pin; |
147 | u16 e_pin; |
148 | u8 i_base; |
149 | u32 s_addr; |
150 | u8 x_addrs; |
151 | u8 s_bit; |
152 | u8 x_bits; |
153 | u8 sz_reg; |
154 | u8 fixed; |
155 | }; |
156 | |
157 | /** |
158 | * struct mtk_pin_rsel - the structure that provides bias resistance selection. |
159 | * @s_pin: the start pin within the rsel range |
160 | * @e_pin: the end pin within the rsel range |
161 | * @rsel_index: the rsel bias resistance index |
162 | * @up_rsel: the pullup rsel bias resistance value |
163 | * @down_rsel: the pulldown rsel bias resistance value |
164 | */ |
165 | struct mtk_pin_rsel { |
166 | u16 s_pin; |
167 | u16 e_pin; |
168 | u16 rsel_index; |
169 | u32 up_rsel; |
170 | u32 down_rsel; |
171 | }; |
172 | |
173 | /* struct mtk_pin_reg_calc - the structure that holds all ranges used to |
174 | * determine which register the pin would make use of |
175 | * for certain pin attribute. |
176 | * @range: the start address for the range |
177 | * @nranges: the number of items in the range |
178 | */ |
179 | struct mtk_pin_reg_calc { |
180 | const struct mtk_pin_field_calc *range; |
181 | unsigned int nranges; |
182 | }; |
183 | |
184 | /** |
185 | * struct mtk_func_desc - the structure that providing information |
186 | * all the funcs for this pin |
187 | * @name: the name of function |
188 | * @muxval: the mux to the function |
189 | */ |
190 | struct mtk_func_desc { |
191 | const char *name; |
192 | u8 muxval; |
193 | }; |
194 | |
195 | /** |
196 | * struct mtk_eint_desc - the structure that providing information |
197 | * for eint data per pin |
198 | * @eint_m: the eint mux for this pin |
199 | * @eitn_n: the eint number for this pin |
200 | */ |
201 | struct mtk_eint_desc { |
202 | u16 eint_m; |
203 | u16 eint_n; |
204 | }; |
205 | |
206 | /** |
207 | * struct mtk_pin_desc - the structure that providing information |
208 | * for each pin of chips |
209 | * @number: unique pin number from the global pin number space |
210 | * @name: name for this pin |
211 | * @eint: the eint data for this pin |
212 | * @drv_n: the index with the driving group |
213 | * @funcs: all available functions for this pins (only used in |
214 | * those drivers compatible to pinctrl-mtk-common.c-like |
215 | * ones) |
216 | */ |
217 | struct mtk_pin_desc { |
218 | unsigned int number; |
219 | const char *name; |
220 | struct mtk_eint_desc eint; |
221 | u8 drv_n; |
222 | struct mtk_func_desc *funcs; |
223 | }; |
224 | |
225 | struct mtk_pinctrl_group { |
226 | const char *name; |
227 | unsigned long config; |
228 | unsigned pin; |
229 | }; |
230 | |
231 | struct mtk_pinctrl; |
232 | |
233 | /* struct mtk_pin_soc - the structure that holds SoC-specific data */ |
234 | struct mtk_pin_soc { |
235 | const struct mtk_pin_reg_calc *reg_cal; |
236 | const struct mtk_pin_desc *pins; |
237 | unsigned int npins; |
238 | const struct group_desc *grps; |
239 | unsigned int ngrps; |
240 | const struct function_desc *funcs; |
241 | unsigned int nfuncs; |
242 | const struct mtk_eint_regs *eint_regs; |
243 | const struct mtk_eint_hw *eint_hw; |
244 | |
245 | /* Specific parameters per SoC */ |
246 | u8 gpio_m; |
247 | bool ies_present; |
248 | const char * const *base_names; |
249 | unsigned int nbase_names; |
250 | const unsigned int *pull_type; |
251 | const struct mtk_pin_rsel *pin_rsel; |
252 | unsigned int npin_rsel; |
253 | |
254 | /* Specific pinconfig operations */ |
255 | int (*bias_disable_set)(struct mtk_pinctrl *hw, |
256 | const struct mtk_pin_desc *desc); |
257 | int (*bias_disable_get)(struct mtk_pinctrl *hw, |
258 | const struct mtk_pin_desc *desc, int *res); |
259 | int (*bias_set)(struct mtk_pinctrl *hw, |
260 | const struct mtk_pin_desc *desc, bool pullup); |
261 | int (*bias_get)(struct mtk_pinctrl *hw, |
262 | const struct mtk_pin_desc *desc, bool pullup, int *res); |
263 | |
264 | int (*bias_set_combo)(struct mtk_pinctrl *hw, |
265 | const struct mtk_pin_desc *desc, u32 pullup, u32 arg); |
266 | int (*bias_get_combo)(struct mtk_pinctrl *hw, |
267 | const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg); |
268 | |
269 | int (*drive_set)(struct mtk_pinctrl *hw, |
270 | const struct mtk_pin_desc *desc, u32 arg); |
271 | int (*drive_get)(struct mtk_pinctrl *hw, |
272 | const struct mtk_pin_desc *desc, int *val); |
273 | |
274 | int (*adv_pull_set)(struct mtk_pinctrl *hw, |
275 | const struct mtk_pin_desc *desc, bool pullup, |
276 | u32 arg); |
277 | int (*adv_pull_get)(struct mtk_pinctrl *hw, |
278 | const struct mtk_pin_desc *desc, bool pullup, |
279 | u32 *val); |
280 | int (*adv_drive_set)(struct mtk_pinctrl *hw, |
281 | const struct mtk_pin_desc *desc, u32 arg); |
282 | int (*adv_drive_get)(struct mtk_pinctrl *hw, |
283 | const struct mtk_pin_desc *desc, u32 *val); |
284 | |
285 | /* Specific driver data */ |
286 | void *driver_data; |
287 | }; |
288 | |
289 | struct mtk_pinctrl { |
290 | struct pinctrl_dev *pctrl; |
291 | void __iomem **base; |
292 | u8 nbase; |
293 | struct device *dev; |
294 | struct gpio_chip chip; |
295 | const struct mtk_pin_soc *soc; |
296 | struct mtk_eint *eint; |
297 | struct mtk_pinctrl_group *groups; |
298 | const char **grp_names; |
299 | /* lock pin's register resource to avoid multiple threads issue*/ |
300 | spinlock_t lock; |
301 | /* identify rsel setting by si unit or rsel define in dts node */ |
302 | bool rsel_si_unit; |
303 | }; |
304 | |
305 | void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set); |
306 | |
307 | int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, |
308 | int field, int value); |
309 | int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, |
310 | int field, int *value); |
311 | |
312 | int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev); |
313 | |
314 | int mtk_pinconf_bias_disable_set(struct mtk_pinctrl *hw, |
315 | const struct mtk_pin_desc *desc); |
316 | int mtk_pinconf_bias_disable_get(struct mtk_pinctrl *hw, |
317 | const struct mtk_pin_desc *desc, int *res); |
318 | int mtk_pinconf_bias_set(struct mtk_pinctrl *hw, |
319 | const struct mtk_pin_desc *desc, bool pullup); |
320 | int mtk_pinconf_bias_get(struct mtk_pinctrl *hw, |
321 | const struct mtk_pin_desc *desc, bool pullup, |
322 | int *res); |
323 | |
324 | int mtk_pinconf_bias_disable_set_rev1(struct mtk_pinctrl *hw, |
325 | const struct mtk_pin_desc *desc); |
326 | int mtk_pinconf_bias_disable_get_rev1(struct mtk_pinctrl *hw, |
327 | const struct mtk_pin_desc *desc, |
328 | int *res); |
329 | int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw, |
330 | const struct mtk_pin_desc *desc, bool pullup); |
331 | int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw, |
332 | const struct mtk_pin_desc *desc, bool pullup, |
333 | int *res); |
334 | int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw, |
335 | const struct mtk_pin_desc *desc, |
336 | u32 pullup, u32 enable); |
337 | int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw, |
338 | const struct mtk_pin_desc *desc, |
339 | u32 *pullup, u32 *enable); |
340 | |
341 | int mtk_pinconf_drive_set(struct mtk_pinctrl *hw, |
342 | const struct mtk_pin_desc *desc, u32 arg); |
343 | int mtk_pinconf_drive_get(struct mtk_pinctrl *hw, |
344 | const struct mtk_pin_desc *desc, int *val); |
345 | |
346 | int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw, |
347 | const struct mtk_pin_desc *desc, u32 arg); |
348 | int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw, |
349 | const struct mtk_pin_desc *desc, int *val); |
350 | |
351 | int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw, |
352 | const struct mtk_pin_desc *desc, u32 arg); |
353 | int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw, |
354 | const struct mtk_pin_desc *desc, int *val); |
355 | |
356 | int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, |
357 | const struct mtk_pin_desc *desc, bool pullup, |
358 | u32 arg); |
359 | int mtk_pinconf_adv_pull_get(struct mtk_pinctrl *hw, |
360 | const struct mtk_pin_desc *desc, bool pullup, |
361 | u32 *val); |
362 | int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw, |
363 | const struct mtk_pin_desc *desc, u32 arg); |
364 | int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw, |
365 | const struct mtk_pin_desc *desc, u32 *val); |
366 | int mtk_pinconf_adv_drive_set_raw(struct mtk_pinctrl *hw, |
367 | const struct mtk_pin_desc *desc, u32 arg); |
368 | int mtk_pinconf_adv_drive_get_raw(struct mtk_pinctrl *hw, |
369 | const struct mtk_pin_desc *desc, u32 *val); |
370 | |
371 | bool mtk_is_virt_gpio(struct mtk_pinctrl *hw, unsigned int gpio_n); |
372 | #endif /* __PINCTRL_MTK_COMMON_V2_H */ |
373 | |