Commit | Line | Data |
---|---|---|
6e908892 MY |
1 | /* |
2 | * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | */ | |
14 | ||
15 | #ifndef __PINCTRL_UNIPHIER_H__ | |
16 | #define __PINCTRL_UNIPHIER_H__ | |
17 | ||
18 | #include <linux/bug.h> | |
19 | #include <linux/kernel.h> | |
20 | #include <linux/types.h> | |
21 | ||
22 | #define UNIPHIER_PINCTRL_PINMUX_BASE 0x0 | |
23 | #define UNIPHIER_PINCTRL_LOAD_PINMUX 0x700 | |
24 | #define UNIPHIER_PINCTRL_DRVCTRL_BASE 0x800 | |
25 | #define UNIPHIER_PINCTRL_DRV2CTRL_BASE 0x900 | |
26 | #define UNIPHIER_PINCTRL_PUPDCTRL_BASE 0xa00 | |
27 | #define UNIPHIER_PINCTRL_IECTRL 0xd00 | |
28 | ||
29 | /* input enable control register bit */ | |
30 | #define UNIPHIER_PIN_IECTRL_SHIFT 0 | |
31 | #define UNIPHIER_PIN_IECTRL_BITS 8 | |
32 | #define UNIPHIER_PIN_IECTRL_MASK ((1UL << (UNIPHIER_PIN_IECTRL_BITS)) \ | |
33 | - 1) | |
34 | ||
35 | /* drive strength control register number */ | |
36 | #define UNIPHIER_PIN_DRVCTRL_SHIFT ((UNIPHIER_PIN_IECTRL_SHIFT) + \ | |
37 | (UNIPHIER_PIN_IECTRL_BITS)) | |
38 | #define UNIPHIER_PIN_DRVCTRL_BITS 9 | |
39 | #define UNIPHIER_PIN_DRVCTRL_MASK ((1UL << (UNIPHIER_PIN_DRVCTRL_BITS)) \ | |
40 | - 1) | |
41 | ||
42 | /* supported drive strength (mA) */ | |
43 | #define UNIPHIER_PIN_DRV_STR_SHIFT ((UNIPHIER_PIN_DRVCTRL_SHIFT) + \ | |
44 | (UNIPHIER_PIN_DRVCTRL_BITS)) | |
45 | #define UNIPHIER_PIN_DRV_STR_BITS 3 | |
46 | #define UNIPHIER_PIN_DRV_STR_MASK ((1UL << (UNIPHIER_PIN_DRV_STR_BITS)) \ | |
47 | - 1) | |
48 | ||
49 | /* pull-up / pull-down register number */ | |
50 | #define UNIPHIER_PIN_PUPDCTRL_SHIFT ((UNIPHIER_PIN_DRV_STR_SHIFT) + \ | |
51 | (UNIPHIER_PIN_DRV_STR_BITS)) | |
52 | #define UNIPHIER_PIN_PUPDCTRL_BITS 9 | |
53 | #define UNIPHIER_PIN_PUPDCTRL_MASK ((1UL << (UNIPHIER_PIN_PUPDCTRL_BITS))\ | |
54 | - 1) | |
55 | ||
56 | /* direction of pull register */ | |
57 | #define UNIPHIER_PIN_PULL_DIR_SHIFT ((UNIPHIER_PIN_PUPDCTRL_SHIFT) + \ | |
58 | (UNIPHIER_PIN_PUPDCTRL_BITS)) | |
59 | #define UNIPHIER_PIN_PULL_DIR_BITS 3 | |
60 | #define UNIPHIER_PIN_PULL_DIR_MASK ((1UL << (UNIPHIER_PIN_PULL_DIR_BITS))\ | |
61 | - 1) | |
62 | ||
63 | #if UNIPHIER_PIN_PULL_DIR_SHIFT + UNIPHIER_PIN_PULL_DIR_BITS > BITS_PER_LONG | |
64 | #error "unable to pack pin attributes." | |
65 | #endif | |
66 | ||
67 | #define UNIPHIER_PIN_IECTRL_NONE (UNIPHIER_PIN_IECTRL_MASK) | |
68 | ||
69 | /* selectable drive strength */ | |
70 | enum uniphier_pin_drv_str { | |
71 | UNIPHIER_PIN_DRV_4_8, /* 2 level control: 4/8 mA */ | |
72 | UNIPHIER_PIN_DRV_8_12_16_20, /* 4 level control: 8/12/16/20 mA */ | |
73 | UNIPHIER_PIN_DRV_FIXED_4, /* fixed to 4mA */ | |
74 | UNIPHIER_PIN_DRV_FIXED_5, /* fixed to 5mA */ | |
75 | UNIPHIER_PIN_DRV_FIXED_8, /* fixed to 8mA */ | |
76 | UNIPHIER_PIN_DRV_NONE, /* no support (input only pin) */ | |
77 | }; | |
78 | ||
79 | /* direction of pull register (no pin supports bi-directional pull biasing) */ | |
80 | enum uniphier_pin_pull_dir { | |
81 | UNIPHIER_PIN_PULL_UP, /* pull-up or disabled */ | |
82 | UNIPHIER_PIN_PULL_DOWN, /* pull-down or disabled */ | |
83 | UNIPHIER_PIN_PULL_UP_FIXED, /* always pull-up */ | |
84 | UNIPHIER_PIN_PULL_DOWN_FIXED, /* always pull-down */ | |
85 | UNIPHIER_PIN_PULL_NONE, /* no pull register */ | |
86 | }; | |
87 | ||
88 | #define UNIPHIER_PIN_IECTRL(x) \ | |
89 | (((x) & (UNIPHIER_PIN_IECTRL_MASK)) << (UNIPHIER_PIN_IECTRL_SHIFT)) | |
90 | #define UNIPHIER_PIN_DRVCTRL(x) \ | |
91 | (((x) & (UNIPHIER_PIN_DRVCTRL_MASK)) << (UNIPHIER_PIN_DRVCTRL_SHIFT)) | |
92 | #define UNIPHIER_PIN_DRV_STR(x) \ | |
93 | (((x) & (UNIPHIER_PIN_DRV_STR_MASK)) << (UNIPHIER_PIN_DRV_STR_SHIFT)) | |
94 | #define UNIPHIER_PIN_PUPDCTRL(x) \ | |
95 | (((x) & (UNIPHIER_PIN_PUPDCTRL_MASK)) << (UNIPHIER_PIN_PUPDCTRL_SHIFT)) | |
96 | #define UNIPHIER_PIN_PULL_DIR(x) \ | |
97 | (((x) & (UNIPHIER_PIN_PULL_DIR_MASK)) << (UNIPHIER_PIN_PULL_DIR_SHIFT)) | |
98 | ||
99 | #define UNIPHIER_PIN_ATTR_PACKED(iectrl, drvctrl, drv_str, pupdctrl, pull_dir)\ | |
100 | (UNIPHIER_PIN_IECTRL(iectrl) | \ | |
101 | UNIPHIER_PIN_DRVCTRL(drvctrl) | \ | |
102 | UNIPHIER_PIN_DRV_STR(drv_str) | \ | |
103 | UNIPHIER_PIN_PUPDCTRL(pupdctrl) | \ | |
104 | UNIPHIER_PIN_PULL_DIR(pull_dir)) | |
105 | ||
106 | static inline unsigned int uniphier_pin_get_iectrl(void *drv_data) | |
107 | { | |
108 | return ((unsigned long)drv_data >> UNIPHIER_PIN_IECTRL_SHIFT) & | |
109 | UNIPHIER_PIN_IECTRL_MASK; | |
110 | } | |
111 | ||
112 | static inline unsigned int uniphier_pin_get_drvctrl(void *drv_data) | |
113 | { | |
114 | return ((unsigned long)drv_data >> UNIPHIER_PIN_DRVCTRL_SHIFT) & | |
115 | UNIPHIER_PIN_DRVCTRL_MASK; | |
116 | } | |
117 | ||
118 | static inline unsigned int uniphier_pin_get_drv_str(void *drv_data) | |
119 | { | |
120 | return ((unsigned long)drv_data >> UNIPHIER_PIN_DRV_STR_SHIFT) & | |
121 | UNIPHIER_PIN_DRV_STR_MASK; | |
122 | } | |
123 | ||
124 | static inline unsigned int uniphier_pin_get_pupdctrl(void *drv_data) | |
125 | { | |
126 | return ((unsigned long)drv_data >> UNIPHIER_PIN_PUPDCTRL_SHIFT) & | |
127 | UNIPHIER_PIN_PUPDCTRL_MASK; | |
128 | } | |
129 | ||
130 | static inline unsigned int uniphier_pin_get_pull_dir(void *drv_data) | |
131 | { | |
132 | return ((unsigned long)drv_data >> UNIPHIER_PIN_PULL_DIR_SHIFT) & | |
133 | UNIPHIER_PIN_PULL_DIR_MASK; | |
134 | } | |
135 | ||
136 | enum uniphier_pinmux_gpio_range_type { | |
137 | UNIPHIER_PINMUX_GPIO_RANGE_PORT, | |
138 | UNIPHIER_PINMUX_GPIO_RANGE_IRQ, | |
139 | UNIPHIER_PINMUX_GPIO_RANGE_NONE, | |
140 | }; | |
141 | ||
142 | struct uniphier_pinctrl_group { | |
143 | const char *name; | |
144 | const unsigned *pins; | |
145 | unsigned num_pins; | |
146 | const unsigned *muxvals; | |
147 | enum uniphier_pinmux_gpio_range_type range_type; | |
148 | }; | |
149 | ||
150 | struct uniphier_pinmux_function { | |
151 | const char *name; | |
152 | const char * const *groups; | |
153 | unsigned num_groups; | |
154 | }; | |
155 | ||
156 | struct uniphier_pinctrl_socdata { | |
157 | const struct uniphier_pinctrl_group *groups; | |
158 | int groups_count; | |
159 | const struct uniphier_pinmux_function *functions; | |
160 | int functions_count; | |
161 | unsigned mux_bits; | |
162 | unsigned reg_stride; | |
163 | bool load_pinctrl; | |
164 | }; | |
165 | ||
166 | #define UNIPHIER_PINCTRL_PIN(a, b, c, d, e, f, g) \ | |
167 | { \ | |
168 | .number = a, \ | |
169 | .name = b, \ | |
170 | .drv_data = (void *)UNIPHIER_PIN_ATTR_PACKED(c, d, e, f, g), \ | |
171 | } | |
172 | ||
173 | #define __UNIPHIER_PINCTRL_GROUP(grp, type) \ | |
174 | { \ | |
175 | .name = #grp, \ | |
176 | .pins = grp##_pins, \ | |
177 | .num_pins = ARRAY_SIZE(grp##_pins), \ | |
178 | .muxvals = grp##_muxvals + \ | |
179 | BUILD_BUG_ON_ZERO(ARRAY_SIZE(grp##_pins) != \ | |
180 | ARRAY_SIZE(grp##_muxvals)), \ | |
181 | .range_type = type, \ | |
182 | } | |
183 | ||
184 | #define UNIPHIER_PINCTRL_GROUP(grp) \ | |
185 | __UNIPHIER_PINCTRL_GROUP(grp, UNIPHIER_PINMUX_GPIO_RANGE_NONE) | |
186 | ||
187 | #define UNIPHIER_PINCTRL_GROUP_GPIO_RANGE_PORT(grp) \ | |
188 | __UNIPHIER_PINCTRL_GROUP(grp, UNIPHIER_PINMUX_GPIO_RANGE_PORT) | |
189 | ||
190 | #define UNIPHIER_PINCTRL_GROUP_GPIO_RANGE_IRQ(grp) \ | |
191 | __UNIPHIER_PINCTRL_GROUP(grp, UNIPHIER_PINMUX_GPIO_RANGE_IRQ) | |
192 | ||
193 | #define UNIPHIER_PINCTRL_GROUP_SINGLE(grp, array, ofst) \ | |
194 | { \ | |
195 | .name = #grp, \ | |
196 | .pins = array##_pins + ofst, \ | |
197 | .num_pins = 1, \ | |
198 | .muxvals = array##_muxvals + ofst, \ | |
199 | } | |
200 | ||
201 | #define UNIPHIER_PINMUX_FUNCTION(func) \ | |
202 | { \ | |
203 | .name = #func, \ | |
204 | .groups = func##_groups, \ | |
205 | .num_groups = ARRAY_SIZE(func##_groups), \ | |
206 | } | |
207 | ||
208 | struct platform_device; | |
209 | struct pinctrl_desc; | |
210 | ||
211 | int uniphier_pinctrl_probe(struct platform_device *pdev, | |
212 | struct pinctrl_desc *desc, | |
213 | struct uniphier_pinctrl_socdata *socdata); | |
214 | ||
6e908892 | 215 | #endif /* __PINCTRL_UNIPHIER_H__ */ |