Commit e9a03add0c6ed5341fc59ff9c76843c2888a33fa
Committed by
Linus Walleij
1 parent
272b98c645
Exists in
master
and in
16 other branches
pinctrl: ADI PIN control driver for the GPIO controller on bf54x and bf60x.
The new ADI GPIO2 controller was introduced since the BF548 and BF60x processors. It differs a lot from the old one on BF5xx processors. So, create a pinctrl driver under the pinctrl framework. - Define gpio ports and pin interrupt controllers as individual platform devices. - Register a pinctrl driver for the whole GPIO ports and pin interrupt devices. - Probe pint devices before port devices. Put device instances into the global gpio and pint lists. - Define peripheral, irq and gpio reservation bit masks for each gpio port as runtime resources. - Save and restore gpio port and pint status MMRs in syscore PM functions. - Create the plug-in subdrivers to hold the pinctrl soc data for bf54x and bf60x. Add soc data into struct adi_pinctrl. Initialize the soc data in pin controller probe function. Get the pin groups and functions via the soc data reference. - Call gpiochip_add_pin_range() in gpio device probe function to register range cross reference between gpio device and pin control device. - Get range by pinctrl_find_gpio_range_from_pin(), find gpio_port object by container_of() and find adi_pinctrl by pin control device name. - Handle peripheral and gpio requests in pinctrl operation functions. - Demux gpio IRQs via the irq_domain created by each GPIO port. v2-changes: - Remove unlinke() directive. v3-changes: - Rename struct adi_pmx to adi_pinctrl. - Fix the comments of struct gpio_pint. - Remove unused pin_base in struct gpio_port. - Change pint_assign into bool type. - Add comments about the relationship between pint device and port device to the driver header. - Use BIT macro to shift bit. - Remove all bitmap reservation help functions. Inline reservation functions into the actual code. - Remove gpio and offset mutual reference help functions. - Remove all help functions to find gpio_port and adi_pinctrl structs. Get range by pinctrl_find_gpio_range_from_pin(), find gpio_port object by container_of() and find adi_pinctrl by pin control device name. - Pass bool type usage variable to port_setup help function. - Separate long bit operations into several lines and add comments. - Use debugfs to output all GPIO request information. - Avoid to set drvdata to NULL - Add explanation to function adi_gpio_init_int() - Call gpiochip_add_pin_range() in gpio device probe function to register range cross reference between gpio device and pin control device. - Remove the reference to pin control device from the gpio_port struct. Remove the reference list to gpio device from the adi_pinctrl struct. Replace the global adi_pinctrl list with adi_gpio_port_list. Walk through the gpio list to do power suspend and resume operations. - Remove the global GPIO base from struct adi_pinctrl, define pin base in the platform data for each GPIO port device. - Initialize adi_pinctrl_setup in arch_initcall(). - print the status of triggers, whether it is in GPIO mode, if it is flagged to be used as IRQ, etc in adi_pin_dbg_show(). - Create the plug-in subdrivers to hold the pinctrl soc data for bf54x and bf60x. Add soc data into struct adi_pinctrl. Initialize the soc data in pin controller probe function. Get the pin groups and functions via the soc data reference. v4-changes: - remove useless system_state checking. - replace dev_err with dev_warn in both irq and gpio pin cases. - comment on relationship between irq type and invert operation. - It is not necessary to check the reservation mode of the requested pin in IRQ chip operation. Remove the reservation map. - Use existing gpio/pinctrl subsystem debugfs files. Remove pinctrl-adi2 driver specific debugfs output. - Add linkport group and function information for bf60x. - Separate uart and ctsrts pins into 2 groups. - Separate APAPI and alternative ATAPI pins into 2 groups. Signed-off-by: Sonic Zhang <sonic.zhang@analog.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Showing 7 changed files with 2432 additions and 0 deletions Side-by-side Diff
drivers/pinctrl/Kconfig
... | ... | @@ -49,6 +49,23 @@ |
49 | 49 | bool "AB8505 pin controller driver" |
50 | 50 | depends on PINCTRL_ABX500 && ARCH_U8500 |
51 | 51 | |
52 | +config PINCTRL_ADI2 | |
53 | + bool "ADI pin controller driver" | |
54 | + select PINMUX | |
55 | + select IRQ_DOMAIN | |
56 | + help | |
57 | + This is the pin controller and gpio driver for ADI BF54x, BF60x and | |
58 | + future processors. This option is selected automatically when specific | |
59 | + machine and arch are selected to build. | |
60 | + | |
61 | +config PINCTRL_BF54x | |
62 | + def_bool y if BF54x | |
63 | + select PINCTRL_ADI2 | |
64 | + | |
65 | +config PINCTRL_BF60x | |
66 | + def_bool y if BF60x | |
67 | + select PINCTRL_ADI2 | |
68 | + | |
52 | 69 | config PINCTRL_AT91 |
53 | 70 | bool "AT91 pinctrl driver" |
54 | 71 | depends on OF |
drivers/pinctrl/Makefile
... | ... | @@ -14,6 +14,9 @@ |
14 | 14 | obj-$(CONFIG_PINCTRL_AB8540) += pinctrl-ab8540.o |
15 | 15 | obj-$(CONFIG_PINCTRL_AB9540) += pinctrl-ab9540.o |
16 | 16 | obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.o |
17 | +obj-$(CONFIG_PINCTRL_ADI2) += pinctrl-adi2.o | |
18 | +obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o | |
19 | +obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o | |
17 | 20 | obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o |
18 | 21 | obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o |
19 | 22 | obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o |
drivers/pinctrl/pinctrl-adi2-bf54x.c
1 | +/* | |
2 | + * Pinctrl Driver for ADI GPIO2 controller | |
3 | + * | |
4 | + * Copyright 2007-2013 Analog Devices Inc. | |
5 | + * | |
6 | + * Licensed under the GPLv2 or later | |
7 | + */ | |
8 | + | |
9 | +#include <asm/portmux.h> | |
10 | +#include "pinctrl-adi2.h" | |
11 | + | |
12 | +static const struct pinctrl_pin_desc adi_pads[] = { | |
13 | + PINCTRL_PIN(0, "PA0"), | |
14 | + PINCTRL_PIN(1, "PA1"), | |
15 | + PINCTRL_PIN(2, "PA2"), | |
16 | + PINCTRL_PIN(3, "PG3"), | |
17 | + PINCTRL_PIN(4, "PA4"), | |
18 | + PINCTRL_PIN(5, "PA5"), | |
19 | + PINCTRL_PIN(6, "PA6"), | |
20 | + PINCTRL_PIN(7, "PA7"), | |
21 | + PINCTRL_PIN(8, "PA8"), | |
22 | + PINCTRL_PIN(9, "PA9"), | |
23 | + PINCTRL_PIN(10, "PA10"), | |
24 | + PINCTRL_PIN(11, "PA11"), | |
25 | + PINCTRL_PIN(12, "PA12"), | |
26 | + PINCTRL_PIN(13, "PA13"), | |
27 | + PINCTRL_PIN(14, "PA14"), | |
28 | + PINCTRL_PIN(15, "PA15"), | |
29 | + PINCTRL_PIN(16, "PB0"), | |
30 | + PINCTRL_PIN(17, "PB1"), | |
31 | + PINCTRL_PIN(18, "PB2"), | |
32 | + PINCTRL_PIN(19, "PB3"), | |
33 | + PINCTRL_PIN(20, "PB4"), | |
34 | + PINCTRL_PIN(21, "PB5"), | |
35 | + PINCTRL_PIN(22, "PB6"), | |
36 | + PINCTRL_PIN(23, "PB7"), | |
37 | + PINCTRL_PIN(24, "PB8"), | |
38 | + PINCTRL_PIN(25, "PB9"), | |
39 | + PINCTRL_PIN(26, "PB10"), | |
40 | + PINCTRL_PIN(27, "PB11"), | |
41 | + PINCTRL_PIN(28, "PB12"), | |
42 | + PINCTRL_PIN(29, "PB13"), | |
43 | + PINCTRL_PIN(30, "PB14"), | |
44 | + PINCTRL_PIN(32, "PC0"), | |
45 | + PINCTRL_PIN(33, "PC1"), | |
46 | + PINCTRL_PIN(34, "PC2"), | |
47 | + PINCTRL_PIN(35, "PC3"), | |
48 | + PINCTRL_PIN(36, "PC4"), | |
49 | + PINCTRL_PIN(37, "PC5"), | |
50 | + PINCTRL_PIN(38, "PC6"), | |
51 | + PINCTRL_PIN(39, "PC7"), | |
52 | + PINCTRL_PIN(40, "PC8"), | |
53 | + PINCTRL_PIN(41, "PC9"), | |
54 | + PINCTRL_PIN(42, "PC10"), | |
55 | + PINCTRL_PIN(43, "PC11"), | |
56 | + PINCTRL_PIN(44, "PC12"), | |
57 | + PINCTRL_PIN(45, "PC13"), | |
58 | + PINCTRL_PIN(48, "PD0"), | |
59 | + PINCTRL_PIN(49, "PD1"), | |
60 | + PINCTRL_PIN(50, "PD2"), | |
61 | + PINCTRL_PIN(51, "PD3"), | |
62 | + PINCTRL_PIN(52, "PD4"), | |
63 | + PINCTRL_PIN(53, "PD5"), | |
64 | + PINCTRL_PIN(54, "PD6"), | |
65 | + PINCTRL_PIN(55, "PD7"), | |
66 | + PINCTRL_PIN(56, "PD8"), | |
67 | + PINCTRL_PIN(57, "PD9"), | |
68 | + PINCTRL_PIN(58, "PD10"), | |
69 | + PINCTRL_PIN(59, "PD11"), | |
70 | + PINCTRL_PIN(60, "PD12"), | |
71 | + PINCTRL_PIN(61, "PD13"), | |
72 | + PINCTRL_PIN(62, "PD14"), | |
73 | + PINCTRL_PIN(63, "PD15"), | |
74 | + PINCTRL_PIN(64, "PE0"), | |
75 | + PINCTRL_PIN(65, "PE1"), | |
76 | + PINCTRL_PIN(66, "PE2"), | |
77 | + PINCTRL_PIN(67, "PE3"), | |
78 | + PINCTRL_PIN(68, "PE4"), | |
79 | + PINCTRL_PIN(69, "PE5"), | |
80 | + PINCTRL_PIN(70, "PE6"), | |
81 | + PINCTRL_PIN(71, "PE7"), | |
82 | + PINCTRL_PIN(72, "PE8"), | |
83 | + PINCTRL_PIN(73, "PE9"), | |
84 | + PINCTRL_PIN(74, "PE10"), | |
85 | + PINCTRL_PIN(75, "PE11"), | |
86 | + PINCTRL_PIN(76, "PE12"), | |
87 | + PINCTRL_PIN(77, "PE13"), | |
88 | + PINCTRL_PIN(78, "PE14"), | |
89 | + PINCTRL_PIN(79, "PE15"), | |
90 | + PINCTRL_PIN(80, "PF0"), | |
91 | + PINCTRL_PIN(81, "PF1"), | |
92 | + PINCTRL_PIN(82, "PF2"), | |
93 | + PINCTRL_PIN(83, "PF3"), | |
94 | + PINCTRL_PIN(84, "PF4"), | |
95 | + PINCTRL_PIN(85, "PF5"), | |
96 | + PINCTRL_PIN(86, "PF6"), | |
97 | + PINCTRL_PIN(87, "PF7"), | |
98 | + PINCTRL_PIN(88, "PF8"), | |
99 | + PINCTRL_PIN(89, "PF9"), | |
100 | + PINCTRL_PIN(90, "PF10"), | |
101 | + PINCTRL_PIN(91, "PF11"), | |
102 | + PINCTRL_PIN(92, "PF12"), | |
103 | + PINCTRL_PIN(93, "PF13"), | |
104 | + PINCTRL_PIN(94, "PF14"), | |
105 | + PINCTRL_PIN(95, "PF15"), | |
106 | + PINCTRL_PIN(96, "PG0"), | |
107 | + PINCTRL_PIN(97, "PG1"), | |
108 | + PINCTRL_PIN(98, "PG2"), | |
109 | + PINCTRL_PIN(99, "PG3"), | |
110 | + PINCTRL_PIN(100, "PG4"), | |
111 | + PINCTRL_PIN(101, "PG5"), | |
112 | + PINCTRL_PIN(102, "PG6"), | |
113 | + PINCTRL_PIN(103, "PG7"), | |
114 | + PINCTRL_PIN(104, "PG8"), | |
115 | + PINCTRL_PIN(105, "PG9"), | |
116 | + PINCTRL_PIN(106, "PG10"), | |
117 | + PINCTRL_PIN(107, "PG11"), | |
118 | + PINCTRL_PIN(108, "PG12"), | |
119 | + PINCTRL_PIN(109, "PG13"), | |
120 | + PINCTRL_PIN(110, "PG14"), | |
121 | + PINCTRL_PIN(111, "PG15"), | |
122 | + PINCTRL_PIN(112, "PH0"), | |
123 | + PINCTRL_PIN(113, "PH1"), | |
124 | + PINCTRL_PIN(114, "PH2"), | |
125 | + PINCTRL_PIN(115, "PH3"), | |
126 | + PINCTRL_PIN(116, "PH4"), | |
127 | + PINCTRL_PIN(117, "PH5"), | |
128 | + PINCTRL_PIN(118, "PH6"), | |
129 | + PINCTRL_PIN(119, "PH7"), | |
130 | + PINCTRL_PIN(120, "PH8"), | |
131 | + PINCTRL_PIN(121, "PH9"), | |
132 | + PINCTRL_PIN(122, "PH10"), | |
133 | + PINCTRL_PIN(123, "PH11"), | |
134 | + PINCTRL_PIN(124, "PH12"), | |
135 | + PINCTRL_PIN(125, "PH13"), | |
136 | + PINCTRL_PIN(128, "PI0"), | |
137 | + PINCTRL_PIN(129, "PI1"), | |
138 | + PINCTRL_PIN(130, "PI2"), | |
139 | + PINCTRL_PIN(131, "PI3"), | |
140 | + PINCTRL_PIN(132, "PI4"), | |
141 | + PINCTRL_PIN(133, "PI5"), | |
142 | + PINCTRL_PIN(134, "PI6"), | |
143 | + PINCTRL_PIN(135, "PI7"), | |
144 | + PINCTRL_PIN(136, "PI8"), | |
145 | + PINCTRL_PIN(137, "PI9"), | |
146 | + PINCTRL_PIN(138, "PI10"), | |
147 | + PINCTRL_PIN(139, "PI11"), | |
148 | + PINCTRL_PIN(140, "PI12"), | |
149 | + PINCTRL_PIN(141, "PI13"), | |
150 | + PINCTRL_PIN(142, "PI14"), | |
151 | + PINCTRL_PIN(143, "PI15"), | |
152 | + PINCTRL_PIN(144, "PJ0"), | |
153 | + PINCTRL_PIN(145, "PJ1"), | |
154 | + PINCTRL_PIN(146, "PJ2"), | |
155 | + PINCTRL_PIN(147, "PJ3"), | |
156 | + PINCTRL_PIN(148, "PJ4"), | |
157 | + PINCTRL_PIN(149, "PJ5"), | |
158 | + PINCTRL_PIN(150, "PJ6"), | |
159 | + PINCTRL_PIN(151, "PJ7"), | |
160 | + PINCTRL_PIN(152, "PJ8"), | |
161 | + PINCTRL_PIN(153, "PJ9"), | |
162 | + PINCTRL_PIN(154, "PJ10"), | |
163 | + PINCTRL_PIN(155, "PJ11"), | |
164 | + PINCTRL_PIN(156, "PJ12"), | |
165 | + PINCTRL_PIN(157, "PJ13"), | |
166 | +}; | |
167 | + | |
168 | +static const unsigned uart0_pins[] = { | |
169 | + GPIO_PE7, GPIO_PE8, | |
170 | +}; | |
171 | + | |
172 | +static const unsigned uart1_pins[] = { | |
173 | + GPIO_PH0, GPIO_PH1, | |
174 | +}; | |
175 | + | |
176 | +static const unsigned uart1_ctsrts_pins[] = { | |
177 | + GPIO_PE9, GPIO_PE10, | |
178 | +}; | |
179 | + | |
180 | +static const unsigned uart2_pins[] = { | |
181 | + GPIO_PB4, GPIO_PB5, | |
182 | +}; | |
183 | + | |
184 | +static const unsigned uart3_pins[] = { | |
185 | + GPIO_PB6, GPIO_PB7, | |
186 | +}; | |
187 | + | |
188 | +static const unsigned uart3_ctsrts_pins[] = { | |
189 | + GPIO_PB2, GPIO_PB3, | |
190 | +}; | |
191 | + | |
192 | +static const unsigned rsi0_pins[] = { | |
193 | + GPIO_PC8, GPIO_PC9, GPIO_PC10, GPIO_PC11, GPIO_PC12, GPIO_PC13, | |
194 | +}; | |
195 | + | |
196 | +static const unsigned spi0_pins[] = { | |
197 | + GPIO_PE0, GPIO_PE1, GPIO_PE2, | |
198 | +}; | |
199 | + | |
200 | +static const unsigned spi1_pins[] = { | |
201 | + GPIO_PG8, GPIO_PG9, GPIO_PG10, | |
202 | +}; | |
203 | + | |
204 | +static const unsigned twi0_pins[] = { | |
205 | + GPIO_PE14, GPIO_PE15, | |
206 | +}; | |
207 | + | |
208 | +static const unsigned twi1_pins[] = { | |
209 | + GPIO_PB0, GPIO_PB1, | |
210 | +}; | |
211 | + | |
212 | +static const unsigned rotary_pins[] = { | |
213 | + GPIO_PH4, GPIO_PH3, GPIO_PH5, | |
214 | +}; | |
215 | + | |
216 | +static const unsigned can0_pins[] = { | |
217 | + GPIO_PG13, GPIO_PG12, | |
218 | +}; | |
219 | + | |
220 | +static const unsigned can1_pins[] = { | |
221 | + GPIO_PG14, GPIO_PG15, | |
222 | +}; | |
223 | + | |
224 | +static const unsigned smc0_pins[] = { | |
225 | + GPIO_PH8, GPIO_PH9, GPIO_PH10, GPIO_PH11, GPIO_PH12, GPIO_PH13, | |
226 | + GPIO_PI0, GPIO_PI1, GPIO_PI2, GPIO_PI3, GPIO_PI4, GPIO_PI5, GPIO_PI6, | |
227 | + GPIO_PI7, GPIO_PI8, GPIO_PI9, GPIO_PI10, GPIO_PI11, | |
228 | + GPIO_PI12, GPIO_PI13, GPIO_PI14, GPIO_PI15, | |
229 | +}; | |
230 | + | |
231 | +static const unsigned sport0_pins[] = { | |
232 | + GPIO_PC0, GPIO_PC2, GPIO_PC3, GPIO_PC4, GPIO_PC6, GPIO_PC7, | |
233 | +}; | |
234 | + | |
235 | +static const unsigned sport1_pins[] = { | |
236 | + GPIO_PD0, GPIO_PD2, GPIO_PD3, GPIO_PD4, GPIO_PD6, GPIO_PD7, | |
237 | +}; | |
238 | + | |
239 | +static const unsigned sport2_pins[] = { | |
240 | + GPIO_PA0, GPIO_PA2, GPIO_PA3, GPIO_PA4, GPIO_PA6, GPIO_PA7, | |
241 | +}; | |
242 | + | |
243 | +static const unsigned sport3_pins[] = { | |
244 | + GPIO_PA8, GPIO_PA10, GPIO_PA11, GPIO_PA12, GPIO_PA14, GPIO_PA15, | |
245 | +}; | |
246 | + | |
247 | +static const unsigned ppi0_8b_pins[] = { | |
248 | + GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, GPIO_PF4, GPIO_PF5, GPIO_PF6, | |
249 | + GPIO_PF7, GPIO_PF13, GPIO_PG0, GPIO_PG1, GPIO_PG2, | |
250 | +}; | |
251 | + | |
252 | +static const unsigned ppi0_16b_pins[] = { | |
253 | + GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, GPIO_PF4, GPIO_PF5, GPIO_PF6, | |
254 | + GPIO_PF7, GPIO_PF9, GPIO_PF10, GPIO_PF11, GPIO_PF12, | |
255 | + GPIO_PF13, GPIO_PF14, GPIO_PF15, | |
256 | + GPIO_PG0, GPIO_PG1, GPIO_PG2, | |
257 | +}; | |
258 | + | |
259 | +static const unsigned ppi0_24b_pins[] = { | |
260 | + GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, GPIO_PF4, GPIO_PF5, GPIO_PF6, | |
261 | + GPIO_PF7, GPIO_PF8, GPIO_PF9, GPIO_PF10, GPIO_PF11, GPIO_PF12, | |
262 | + GPIO_PF13, GPIO_PF14, GPIO_PF15, GPIO_PD0, GPIO_PD1, GPIO_PD2, | |
263 | + GPIO_PD3, GPIO_PD4, GPIO_PD5, GPIO_PG3, GPIO_PG4, | |
264 | + GPIO_PG0, GPIO_PG1, GPIO_PG2, | |
265 | +}; | |
266 | + | |
267 | +static const unsigned ppi1_8b_pins[] = { | |
268 | + GPIO_PD0, GPIO_PD1, GPIO_PD2, GPIO_PD3, GPIO_PD4, GPIO_PD5, GPIO_PD6, | |
269 | + GPIO_PD7, GPIO_PE11, GPIO_PE12, GPIO_PE13, | |
270 | +}; | |
271 | + | |
272 | +static const unsigned ppi1_16b_pins[] = { | |
273 | + GPIO_PD0, GPIO_PD1, GPIO_PD2, GPIO_PD3, GPIO_PD4, GPIO_PD5, GPIO_PD6, | |
274 | + GPIO_PD7, GPIO_PD8, GPIO_PD9, GPIO_PD10, GPIO_PD11, GPIO_PD12, | |
275 | + GPIO_PD13, GPIO_PD14, GPIO_PD15, | |
276 | + GPIO_PE11, GPIO_PE12, GPIO_PE13, | |
277 | +}; | |
278 | + | |
279 | +static const unsigned ppi2_8b_pins[] = { | |
280 | + GPIO_PD8, GPIO_PD9, GPIO_PD10, GPIO_PD11, GPIO_PD12, | |
281 | + GPIO_PD13, GPIO_PD14, GPIO_PD15, | |
282 | + GPIO_PA7, GPIO_PB0, GPIO_PB1, GPIO_PB2, GPIO_PB3, | |
283 | +}; | |
284 | + | |
285 | +static const unsigned atapi_pins[] = { | |
286 | + GPIO_PH2, GPIO_PJ3, GPIO_PJ4, GPIO_PJ5, GPIO_PJ6, | |
287 | + GPIO_PJ7, GPIO_PJ8, GPIO_PJ9, GPIO_PJ10, | |
288 | +}; | |
289 | + | |
290 | +static const unsigned atapi_alter_pins[] = { | |
291 | + GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, GPIO_PF4, GPIO_PF5, GPIO_PF6, | |
292 | + GPIO_PF7, GPIO_PF8, GPIO_PF9, GPIO_PF10, GPIO_PF11, GPIO_PF12, | |
293 | + GPIO_PF13, GPIO_PF14, GPIO_PF15, GPIO_PG2, GPIO_PG3, GPIO_PG4, | |
294 | +}; | |
295 | + | |
296 | +static const unsigned nfc0_pins[] = { | |
297 | + GPIO_PJ1, GPIO_PJ2, | |
298 | +}; | |
299 | + | |
300 | +static const unsigned keys_4x4_pins[] = { | |
301 | + GPIO_PD8, GPIO_PD9, GPIO_PD10, GPIO_PD11, | |
302 | + GPIO_PD12, GPIO_PD13, GPIO_PD14, GPIO_PD15, | |
303 | +}; | |
304 | + | |
305 | +static const unsigned keys_8x8_pins[] = { | |
306 | + GPIO_PD8, GPIO_PD9, GPIO_PD10, GPIO_PD11, | |
307 | + GPIO_PD12, GPIO_PD13, GPIO_PD14, GPIO_PD15, | |
308 | + GPIO_PE0, GPIO_PE1, GPIO_PE2, GPIO_PE3, | |
309 | + GPIO_PE4, GPIO_PE5, GPIO_PE6, GPIO_PE7, | |
310 | +}; | |
311 | + | |
312 | +static const struct adi_pin_group adi_pin_groups[] = { | |
313 | + ADI_PIN_GROUP("uart0grp", uart0_pins), | |
314 | + ADI_PIN_GROUP("uart1grp", uart1_pins), | |
315 | + ADI_PIN_GROUP("uart1ctsrtsgrp", uart1_ctsrts_pins), | |
316 | + ADI_PIN_GROUP("uart2grp", uart2_pins), | |
317 | + ADI_PIN_GROUP("uart3grp", uart3_pins), | |
318 | + ADI_PIN_GROUP("uart3ctsrtsgrp", uart3_ctsrts_pins), | |
319 | + ADI_PIN_GROUP("rsi0grp", rsi0_pins), | |
320 | + ADI_PIN_GROUP("spi0grp", spi0_pins), | |
321 | + ADI_PIN_GROUP("spi1grp", spi1_pins), | |
322 | + ADI_PIN_GROUP("twi0grp", twi0_pins), | |
323 | + ADI_PIN_GROUP("twi1grp", twi1_pins), | |
324 | + ADI_PIN_GROUP("rotarygrp", rotary_pins), | |
325 | + ADI_PIN_GROUP("can0grp", can0_pins), | |
326 | + ADI_PIN_GROUP("can1grp", can1_pins), | |
327 | + ADI_PIN_GROUP("smc0grp", smc0_pins), | |
328 | + ADI_PIN_GROUP("sport0grp", sport0_pins), | |
329 | + ADI_PIN_GROUP("sport1grp", sport1_pins), | |
330 | + ADI_PIN_GROUP("sport2grp", sport2_pins), | |
331 | + ADI_PIN_GROUP("sport3grp", sport3_pins), | |
332 | + ADI_PIN_GROUP("ppi0_8bgrp", ppi0_8b_pins), | |
333 | + ADI_PIN_GROUP("ppi0_16bgrp", ppi0_16b_pins), | |
334 | + ADI_PIN_GROUP("ppi0_24bgrp", ppi0_24b_pins), | |
335 | + ADI_PIN_GROUP("ppi1_8bgrp", ppi1_8b_pins), | |
336 | + ADI_PIN_GROUP("ppi1_16bgrp", ppi1_16b_pins), | |
337 | + ADI_PIN_GROUP("ppi2_8bgrp", ppi2_8b_pins), | |
338 | + ADI_PIN_GROUP("atapigrp", atapi_pins), | |
339 | + ADI_PIN_GROUP("atapialtergrp", atapi_alter_pins), | |
340 | + ADI_PIN_GROUP("nfc0grp", nfc0_pins), | |
341 | + ADI_PIN_GROUP("keys_4x4grp", keys_4x4_pins), | |
342 | + ADI_PIN_GROUP("keys_8x8grp", keys_8x8_pins), | |
343 | +}; | |
344 | + | |
345 | +static const unsigned short uart0_mux[] = { | |
346 | + P_UART0_TX, P_UART0_RX, | |
347 | + 0 | |
348 | +}; | |
349 | + | |
350 | +static const unsigned short uart1_mux[] = { | |
351 | + P_UART1_TX, P_UART1_RX, | |
352 | + 0 | |
353 | +}; | |
354 | + | |
355 | +static const unsigned short uart1_ctsrts_mux[] = { | |
356 | + P_UART1_RTS, P_UART1_CTS, | |
357 | + 0 | |
358 | +}; | |
359 | + | |
360 | +static const unsigned short uart2_mux[] = { | |
361 | + P_UART2_TX, P_UART2_RX, | |
362 | + 0 | |
363 | +}; | |
364 | + | |
365 | +static const unsigned short uart3_mux[] = { | |
366 | + P_UART3_TX, P_UART3_RX, | |
367 | + 0 | |
368 | +}; | |
369 | + | |
370 | +static const unsigned short uart3_ctsrts_mux[] = { | |
371 | + P_UART3_RTS, P_UART3_CTS, | |
372 | + 0 | |
373 | +}; | |
374 | + | |
375 | +static const unsigned short rsi0_mux[] = { | |
376 | + P_SD_D0, P_SD_D1, P_SD_D2, P_SD_D3, P_SD_CLK, P_SD_CMD, | |
377 | + 0 | |
378 | +}; | |
379 | + | |
380 | +static const unsigned short spi0_mux[] = { | |
381 | + P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0 | |
382 | +}; | |
383 | + | |
384 | +static const unsigned short spi1_mux[] = { | |
385 | + P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0 | |
386 | +}; | |
387 | + | |
388 | +static const unsigned short twi0_mux[] = { | |
389 | + P_TWI0_SCL, P_TWI0_SDA, 0 | |
390 | +}; | |
391 | + | |
392 | +static const unsigned short twi1_mux[] = { | |
393 | + P_TWI1_SCL, P_TWI1_SDA, 0 | |
394 | +}; | |
395 | + | |
396 | +static const unsigned short rotary_mux[] = { | |
397 | + P_CNT_CUD, P_CNT_CDG, P_CNT_CZM, 0 | |
398 | +}; | |
399 | + | |
400 | +static const unsigned short sport0_mux[] = { | |
401 | + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, | |
402 | + P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0 | |
403 | +}; | |
404 | + | |
405 | +static const unsigned short sport1_mux[] = { | |
406 | + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, | |
407 | + P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0 | |
408 | +}; | |
409 | + | |
410 | +static const unsigned short sport2_mux[] = { | |
411 | + P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS, | |
412 | + P_SPORT2_DRPRI, P_SPORT2_RSCLK, 0 | |
413 | +}; | |
414 | + | |
415 | +static const unsigned short sport3_mux[] = { | |
416 | + P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS, | |
417 | + P_SPORT3_DRPRI, P_SPORT3_RSCLK, 0 | |
418 | +}; | |
419 | + | |
420 | +static const unsigned short can0_mux[] = { | |
421 | + P_CAN0_RX, P_CAN0_TX, 0 | |
422 | +}; | |
423 | + | |
424 | +static const unsigned short can1_mux[] = { | |
425 | + P_CAN1_RX, P_CAN1_TX, 0 | |
426 | +}; | |
427 | + | |
428 | +static const unsigned short smc0_mux[] = { | |
429 | + P_A4, P_A5, P_A6, P_A7, P_A8, P_A9, P_A10, P_A11, P_A12, | |
430 | + P_A13, P_A14, P_A15, P_A16, P_A17, P_A18, P_A19, P_A20, P_A21, | |
431 | + P_A22, P_A23, P_A24, P_A25, P_NOR_CLK, 0, | |
432 | +}; | |
433 | + | |
434 | +static const unsigned short ppi0_8b_mux[] = { | |
435 | + P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, | |
436 | + P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, | |
437 | + P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, | |
438 | + 0, | |
439 | +}; | |
440 | + | |
441 | +static const unsigned short ppi0_16b_mux[] = { | |
442 | + P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, | |
443 | + P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, | |
444 | + P_PPI0_D8, P_PPI0_D9, P_PPI0_D10, P_PPI0_D11, | |
445 | + P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, P_PPI0_D15, | |
446 | + P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, | |
447 | + 0, | |
448 | +}; | |
449 | + | |
450 | +static const unsigned short ppi0_24b_mux[] = { | |
451 | + P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, | |
452 | + P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, | |
453 | + P_PPI0_D8, P_PPI0_D9, P_PPI0_D10, P_PPI0_D11, | |
454 | + P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, P_PPI0_D15, | |
455 | + P_PPI0_D16, P_PPI0_D17, P_PPI0_D18, P_PPI0_D19, | |
456 | + P_PPI0_D20, P_PPI0_D21, P_PPI0_D22, P_PPI0_D23, | |
457 | + P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, | |
458 | + 0, | |
459 | +}; | |
460 | + | |
461 | +static const unsigned short ppi1_8b_mux[] = { | |
462 | + P_PPI1_D0, P_PPI1_D1, P_PPI1_D2, P_PPI1_D3, | |
463 | + P_PPI1_D4, P_PPI1_D5, P_PPI1_D6, P_PPI1_D7, | |
464 | + P_PPI1_CLK, P_PPI1_FS1, P_PPI1_FS2, | |
465 | + 0, | |
466 | +}; | |
467 | + | |
468 | +static const unsigned short ppi1_16b_mux[] = { | |
469 | + P_PPI1_D0, P_PPI1_D1, P_PPI1_D2, P_PPI1_D3, | |
470 | + P_PPI1_D4, P_PPI1_D5, P_PPI1_D6, P_PPI1_D7, | |
471 | + P_PPI1_D8, P_PPI1_D9, P_PPI1_D10, P_PPI1_D11, | |
472 | + P_PPI1_D12, P_PPI1_D13, P_PPI1_D14, P_PPI1_D15, | |
473 | + P_PPI1_CLK, P_PPI1_FS1, P_PPI1_FS2, | |
474 | + 0, | |
475 | +}; | |
476 | + | |
477 | +static const unsigned short ppi2_8b_mux[] = { | |
478 | + P_PPI2_D0, P_PPI2_D1, P_PPI2_D2, P_PPI2_D3, | |
479 | + P_PPI2_D4, P_PPI2_D5, P_PPI2_D6, P_PPI2_D7, | |
480 | + P_PPI2_CLK, P_PPI2_FS1, P_PPI2_FS2, | |
481 | + 0, | |
482 | +}; | |
483 | + | |
484 | +static const unsigned short atapi_mux[] = { | |
485 | + P_ATAPI_RESET, P_ATAPI_DIOR, P_ATAPI_DIOW, P_ATAPI_CS0, P_ATAPI_CS1, | |
486 | + P_ATAPI_DMACK, P_ATAPI_DMARQ, P_ATAPI_INTRQ, P_ATAPI_IORDY, | |
487 | +}; | |
488 | + | |
489 | +static const unsigned short atapi_alter_mux[] = { | |
490 | + P_ATAPI_D0A, P_ATAPI_D1A, P_ATAPI_D2A, P_ATAPI_D3A, P_ATAPI_D4A, | |
491 | + P_ATAPI_D5A, P_ATAPI_D6A, P_ATAPI_D7A, P_ATAPI_D8A, P_ATAPI_D9A, | |
492 | + P_ATAPI_D10A, P_ATAPI_D11A, P_ATAPI_D12A, P_ATAPI_D13A, P_ATAPI_D14A, | |
493 | + P_ATAPI_D15A, P_ATAPI_A0A, P_ATAPI_A1A, P_ATAPI_A2A, | |
494 | + 0 | |
495 | +}; | |
496 | + | |
497 | +static const unsigned short nfc0_mux[] = { | |
498 | + P_NAND_CE, P_NAND_RB, | |
499 | + 0 | |
500 | +}; | |
501 | + | |
502 | +static const unsigned short keys_4x4_mux[] = { | |
503 | + P_KEY_ROW3, P_KEY_ROW2, P_KEY_ROW1, P_KEY_ROW0, | |
504 | + P_KEY_COL3, P_KEY_COL2, P_KEY_COL1, P_KEY_COL0, | |
505 | + 0 | |
506 | +}; | |
507 | + | |
508 | +static const unsigned short keys_8x8_mux[] = { | |
509 | + P_KEY_ROW7, P_KEY_ROW6, P_KEY_ROW5, P_KEY_ROW4, | |
510 | + P_KEY_ROW3, P_KEY_ROW2, P_KEY_ROW1, P_KEY_ROW0, | |
511 | + P_KEY_COL7, P_KEY_COL6, P_KEY_COL5, P_KEY_COL4, | |
512 | + P_KEY_COL3, P_KEY_COL2, P_KEY_COL1, P_KEY_COL0, | |
513 | + 0 | |
514 | +}; | |
515 | + | |
516 | +static const char * const uart0grp[] = { "uart0grp" }; | |
517 | +static const char * const uart1grp[] = { "uart1grp" }; | |
518 | +static const char * const uart1ctsrtsgrp[] = { "uart1ctsrtsgrp" }; | |
519 | +static const char * const uart2grp[] = { "uart2grp" }; | |
520 | +static const char * const uart3grp[] = { "uart3grp" }; | |
521 | +static const char * const uart3ctsrtsgrp[] = { "uart3ctsrtsgrp" }; | |
522 | +static const char * const rsi0grp[] = { "rsi0grp" }; | |
523 | +static const char * const spi0grp[] = { "spi0grp" }; | |
524 | +static const char * const spi1grp[] = { "spi1grp" }; | |
525 | +static const char * const twi0grp[] = { "twi0grp" }; | |
526 | +static const char * const twi1grp[] = { "twi1grp" }; | |
527 | +static const char * const rotarygrp[] = { "rotarygrp" }; | |
528 | +static const char * const can0grp[] = { "can0grp" }; | |
529 | +static const char * const can1grp[] = { "can1grp" }; | |
530 | +static const char * const smc0grp[] = { "smc0grp" }; | |
531 | +static const char * const sport0grp[] = { "sport0grp" }; | |
532 | +static const char * const sport1grp[] = { "sport1grp" }; | |
533 | +static const char * const sport2grp[] = { "sport2grp" }; | |
534 | +static const char * const sport3grp[] = { "sport3grp" }; | |
535 | +static const char * const ppi0_8bgrp[] = { "ppi0_8bgrp" }; | |
536 | +static const char * const ppi0_16bgrp[] = { "ppi0_16bgrp" }; | |
537 | +static const char * const ppi0_24bgrp[] = { "ppi0_24bgrp" }; | |
538 | +static const char * const ppi1_8bgrp[] = { "ppi1_8bgrp" }; | |
539 | +static const char * const ppi1_16bgrp[] = { "ppi1_16bgrp" }; | |
540 | +static const char * const ppi2_8bgrp[] = { "ppi2_8bgrp" }; | |
541 | +static const char * const atapigrp[] = { "atapigrp" }; | |
542 | +static const char * const atapialtergrp[] = { "atapialtergrp" }; | |
543 | +static const char * const nfc0grp[] = { "nfc0grp" }; | |
544 | +static const char * const keys_4x4grp[] = { "keys_4x4grp" }; | |
545 | +static const char * const keys_8x8grp[] = { "keys_8x8grp" }; | |
546 | + | |
547 | +static const struct adi_pmx_func adi_pmx_functions[] = { | |
548 | + ADI_PMX_FUNCTION("uart0", uart0grp, uart0_mux), | |
549 | + ADI_PMX_FUNCTION("uart1", uart1grp, uart1_mux), | |
550 | + ADI_PMX_FUNCTION("uart1_ctsrts", uart1ctsrtsgrp, uart1_ctsrts_mux), | |
551 | + ADI_PMX_FUNCTION("uart2", uart2grp, uart2_mux), | |
552 | + ADI_PMX_FUNCTION("uart3", uart3grp, uart3_mux), | |
553 | + ADI_PMX_FUNCTION("uart3_ctsrts", uart3ctsrtsgrp, uart3_ctsrts_mux), | |
554 | + ADI_PMX_FUNCTION("rsi0", rsi0grp, rsi0_mux), | |
555 | + ADI_PMX_FUNCTION("spi0", spi0grp, spi0_mux), | |
556 | + ADI_PMX_FUNCTION("spi1", spi1grp, spi1_mux), | |
557 | + ADI_PMX_FUNCTION("twi0", twi0grp, twi0_mux), | |
558 | + ADI_PMX_FUNCTION("twi1", twi1grp, twi1_mux), | |
559 | + ADI_PMX_FUNCTION("rotary", rotarygrp, rotary_mux), | |
560 | + ADI_PMX_FUNCTION("can0", can0grp, can0_mux), | |
561 | + ADI_PMX_FUNCTION("can1", can1grp, can1_mux), | |
562 | + ADI_PMX_FUNCTION("smc0", smc0grp, smc0_mux), | |
563 | + ADI_PMX_FUNCTION("sport0", sport0grp, sport0_mux), | |
564 | + ADI_PMX_FUNCTION("sport1", sport1grp, sport1_mux), | |
565 | + ADI_PMX_FUNCTION("sport2", sport2grp, sport2_mux), | |
566 | + ADI_PMX_FUNCTION("sport3", sport3grp, sport3_mux), | |
567 | + ADI_PMX_FUNCTION("ppi0_8b", ppi0_8bgrp, ppi0_8b_mux), | |
568 | + ADI_PMX_FUNCTION("ppi0_16b", ppi0_16bgrp, ppi0_16b_mux), | |
569 | + ADI_PMX_FUNCTION("ppi0_24b", ppi0_24bgrp, ppi0_24b_mux), | |
570 | + ADI_PMX_FUNCTION("ppi1_8b", ppi1_8bgrp, ppi1_8b_mux), | |
571 | + ADI_PMX_FUNCTION("ppi1_16b", ppi1_16bgrp, ppi1_16b_mux), | |
572 | + ADI_PMX_FUNCTION("ppi2_8b", ppi2_8bgrp, ppi2_8b_mux), | |
573 | + ADI_PMX_FUNCTION("atapi", atapigrp, atapi_mux), | |
574 | + ADI_PMX_FUNCTION("atapi_alter", atapialtergrp, atapi_alter_mux), | |
575 | + ADI_PMX_FUNCTION("nfc0", nfc0grp, nfc0_mux), | |
576 | + ADI_PMX_FUNCTION("keys_4x4", keys_4x4grp, keys_4x4_mux), | |
577 | + ADI_PMX_FUNCTION("keys_8x8", keys_8x8grp, keys_8x8_mux), | |
578 | +}; | |
579 | + | |
580 | +static const struct adi_pinctrl_soc_data adi_bf54x_soc = { | |
581 | + .functions = adi_pmx_functions, | |
582 | + .nfunctions = ARRAY_SIZE(adi_pmx_functions), | |
583 | + .groups = adi_pin_groups, | |
584 | + .ngroups = ARRAY_SIZE(adi_pin_groups), | |
585 | + .pins = adi_pads, | |
586 | + .npins = ARRAY_SIZE(adi_pads), | |
587 | +}; | |
588 | + | |
589 | +void adi_pinctrl_soc_init(const struct adi_pinctrl_soc_data **soc) | |
590 | +{ | |
591 | + *soc = &adi_bf54x_soc; | |
592 | +} |
drivers/pinctrl/pinctrl-adi2-bf60x.c
1 | +/* | |
2 | + * Pinctrl Driver for ADI GPIO2 controller | |
3 | + * | |
4 | + * Copyright 2007-2013 Analog Devices Inc. | |
5 | + * | |
6 | + * Licensed under the GPLv2 or later | |
7 | + */ | |
8 | + | |
9 | +#include <asm/portmux.h> | |
10 | +#include "pinctrl-adi2.h" | |
11 | + | |
12 | +static const struct pinctrl_pin_desc adi_pads[] = { | |
13 | + PINCTRL_PIN(0, "PA0"), | |
14 | + PINCTRL_PIN(1, "PA1"), | |
15 | + PINCTRL_PIN(2, "PA2"), | |
16 | + PINCTRL_PIN(3, "PG3"), | |
17 | + PINCTRL_PIN(4, "PA4"), | |
18 | + PINCTRL_PIN(5, "PA5"), | |
19 | + PINCTRL_PIN(6, "PA6"), | |
20 | + PINCTRL_PIN(7, "PA7"), | |
21 | + PINCTRL_PIN(8, "PA8"), | |
22 | + PINCTRL_PIN(9, "PA9"), | |
23 | + PINCTRL_PIN(10, "PA10"), | |
24 | + PINCTRL_PIN(11, "PA11"), | |
25 | + PINCTRL_PIN(12, "PA12"), | |
26 | + PINCTRL_PIN(13, "PA13"), | |
27 | + PINCTRL_PIN(14, "PA14"), | |
28 | + PINCTRL_PIN(15, "PA15"), | |
29 | + PINCTRL_PIN(16, "PB0"), | |
30 | + PINCTRL_PIN(17, "PB1"), | |
31 | + PINCTRL_PIN(18, "PB2"), | |
32 | + PINCTRL_PIN(19, "PB3"), | |
33 | + PINCTRL_PIN(20, "PB4"), | |
34 | + PINCTRL_PIN(21, "PB5"), | |
35 | + PINCTRL_PIN(22, "PB6"), | |
36 | + PINCTRL_PIN(23, "PB7"), | |
37 | + PINCTRL_PIN(24, "PB8"), | |
38 | + PINCTRL_PIN(25, "PB9"), | |
39 | + PINCTRL_PIN(26, "PB10"), | |
40 | + PINCTRL_PIN(27, "PB11"), | |
41 | + PINCTRL_PIN(28, "PB12"), | |
42 | + PINCTRL_PIN(29, "PB13"), | |
43 | + PINCTRL_PIN(30, "PB14"), | |
44 | + PINCTRL_PIN(31, "PB15"), | |
45 | + PINCTRL_PIN(32, "PC0"), | |
46 | + PINCTRL_PIN(33, "PC1"), | |
47 | + PINCTRL_PIN(34, "PC2"), | |
48 | + PINCTRL_PIN(35, "PC3"), | |
49 | + PINCTRL_PIN(36, "PC4"), | |
50 | + PINCTRL_PIN(37, "PC5"), | |
51 | + PINCTRL_PIN(38, "PC6"), | |
52 | + PINCTRL_PIN(39, "PC7"), | |
53 | + PINCTRL_PIN(40, "PC8"), | |
54 | + PINCTRL_PIN(41, "PC9"), | |
55 | + PINCTRL_PIN(42, "PC10"), | |
56 | + PINCTRL_PIN(43, "PC11"), | |
57 | + PINCTRL_PIN(44, "PC12"), | |
58 | + PINCTRL_PIN(45, "PC13"), | |
59 | + PINCTRL_PIN(46, "PC14"), | |
60 | + PINCTRL_PIN(47, "PC15"), | |
61 | + PINCTRL_PIN(48, "PD0"), | |
62 | + PINCTRL_PIN(49, "PD1"), | |
63 | + PINCTRL_PIN(50, "PD2"), | |
64 | + PINCTRL_PIN(51, "PD3"), | |
65 | + PINCTRL_PIN(52, "PD4"), | |
66 | + PINCTRL_PIN(53, "PD5"), | |
67 | + PINCTRL_PIN(54, "PD6"), | |
68 | + PINCTRL_PIN(55, "PD7"), | |
69 | + PINCTRL_PIN(56, "PD8"), | |
70 | + PINCTRL_PIN(57, "PD9"), | |
71 | + PINCTRL_PIN(58, "PD10"), | |
72 | + PINCTRL_PIN(59, "PD11"), | |
73 | + PINCTRL_PIN(60, "PD12"), | |
74 | + PINCTRL_PIN(61, "PD13"), | |
75 | + PINCTRL_PIN(62, "PD14"), | |
76 | + PINCTRL_PIN(63, "PD15"), | |
77 | + PINCTRL_PIN(64, "PE0"), | |
78 | + PINCTRL_PIN(65, "PE1"), | |
79 | + PINCTRL_PIN(66, "PE2"), | |
80 | + PINCTRL_PIN(67, "PE3"), | |
81 | + PINCTRL_PIN(68, "PE4"), | |
82 | + PINCTRL_PIN(69, "PE5"), | |
83 | + PINCTRL_PIN(70, "PE6"), | |
84 | + PINCTRL_PIN(71, "PE7"), | |
85 | + PINCTRL_PIN(72, "PE8"), | |
86 | + PINCTRL_PIN(73, "PE9"), | |
87 | + PINCTRL_PIN(74, "PE10"), | |
88 | + PINCTRL_PIN(75, "PE11"), | |
89 | + PINCTRL_PIN(76, "PE12"), | |
90 | + PINCTRL_PIN(77, "PE13"), | |
91 | + PINCTRL_PIN(78, "PE14"), | |
92 | + PINCTRL_PIN(79, "PE15"), | |
93 | + PINCTRL_PIN(80, "PF0"), | |
94 | + PINCTRL_PIN(81, "PF1"), | |
95 | + PINCTRL_PIN(82, "PF2"), | |
96 | + PINCTRL_PIN(83, "PF3"), | |
97 | + PINCTRL_PIN(84, "PF4"), | |
98 | + PINCTRL_PIN(85, "PF5"), | |
99 | + PINCTRL_PIN(86, "PF6"), | |
100 | + PINCTRL_PIN(87, "PF7"), | |
101 | + PINCTRL_PIN(88, "PF8"), | |
102 | + PINCTRL_PIN(89, "PF9"), | |
103 | + PINCTRL_PIN(90, "PF10"), | |
104 | + PINCTRL_PIN(91, "PF11"), | |
105 | + PINCTRL_PIN(92, "PF12"), | |
106 | + PINCTRL_PIN(93, "PF13"), | |
107 | + PINCTRL_PIN(94, "PF14"), | |
108 | + PINCTRL_PIN(95, "PF15"), | |
109 | + PINCTRL_PIN(96, "PG0"), | |
110 | + PINCTRL_PIN(97, "PG1"), | |
111 | + PINCTRL_PIN(98, "PG2"), | |
112 | + PINCTRL_PIN(99, "PG3"), | |
113 | + PINCTRL_PIN(100, "PG4"), | |
114 | + PINCTRL_PIN(101, "PG5"), | |
115 | + PINCTRL_PIN(102, "PG6"), | |
116 | + PINCTRL_PIN(103, "PG7"), | |
117 | + PINCTRL_PIN(104, "PG8"), | |
118 | + PINCTRL_PIN(105, "PG9"), | |
119 | + PINCTRL_PIN(106, "PG10"), | |
120 | + PINCTRL_PIN(107, "PG11"), | |
121 | + PINCTRL_PIN(108, "PG12"), | |
122 | + PINCTRL_PIN(109, "PG13"), | |
123 | + PINCTRL_PIN(110, "PG14"), | |
124 | + PINCTRL_PIN(111, "PG15"), | |
125 | +}; | |
126 | + | |
127 | +static const unsigned uart0_pins[] = { | |
128 | + GPIO_PD7, GPIO_PD8, | |
129 | +}; | |
130 | + | |
131 | +static const unsigned uart0_ctsrts_pins[] = { | |
132 | + GPIO_PD9, GPIO_PD10, | |
133 | +}; | |
134 | + | |
135 | +static const unsigned uart1_pins[] = { | |
136 | + GPIO_PG15, GPIO_PG14, | |
137 | +}; | |
138 | + | |
139 | +static const unsigned uart1_ctsrts_pins[] = { | |
140 | + GPIO_PG10, GPIO_PG13, | |
141 | +}; | |
142 | + | |
143 | +static const unsigned rsi0_pins[] = { | |
144 | + GPIO_PG3, GPIO_PG2, GPIO_PG0, GPIO_PE15, GPIO_PG5, GPIO_PG6, | |
145 | +}; | |
146 | + | |
147 | +static const unsigned eth0_pins[] = { | |
148 | + GPIO_PC6, GPIO_PC7, GPIO_PC2, GPIO_PC0, GPIO_PC3, GPIO_PC1, | |
149 | + GPIO_PB13, GPIO_PD6, GPIO_PC5, GPIO_PC4, GPIO_PB14, GPIO_PB15, | |
150 | +}; | |
151 | + | |
152 | +static const unsigned eth1_pins[] = { | |
153 | + GPIO_PE10, GPIO_PE11, GPIO_PG3, GPIO_PG0, GPIO_PG2, GPIO_PE15, | |
154 | + GPIO_PG5, GPIO_PE12, GPIO_PE13, GPIO_PE14, GPIO_PG6, GPIO_PC9, | |
155 | +}; | |
156 | + | |
157 | +static const unsigned spi0_pins[] = { | |
158 | + GPIO_PD4, GPIO_PD2, GPIO_PD3, | |
159 | +}; | |
160 | + | |
161 | +static const unsigned spi1_pins[] = { | |
162 | + GPIO_PD5, GPIO_PD14, GPIO_PD13, | |
163 | +}; | |
164 | + | |
165 | +static const unsigned twi0_pins[] = { | |
166 | +}; | |
167 | + | |
168 | +static const unsigned twi1_pins[] = { | |
169 | +}; | |
170 | + | |
171 | +static const unsigned rotary_pins[] = { | |
172 | + GPIO_PG7, GPIO_PG11, GPIO_PG12, | |
173 | +}; | |
174 | + | |
175 | +static const unsigned can0_pins[] = { | |
176 | + GPIO_PG1, GPIO_PG4, | |
177 | +}; | |
178 | + | |
179 | +static const unsigned smc0_pins[] = { | |
180 | + GPIO_PA0, GPIO_PA1, GPIO_PA2, GPIO_PA3, GPIO_PA4, GPIO_PA5, GPIO_PA6, | |
181 | + GPIO_PA7, GPIO_PA8, GPIO_PA9, GPIO_PB2, GPIO_PA10, GPIO_PA11, | |
182 | + GPIO_PB3, GPIO_PA12, GPIO_PA13, GPIO_PA14, GPIO_PA15, GPIO_PB6, | |
183 | + GPIO_PB7, GPIO_PB8, GPIO_PB10, GPIO_PB11, GPIO_PB0, | |
184 | +}; | |
185 | + | |
186 | +static const unsigned sport0_pins[] = { | |
187 | + GPIO_PB5, GPIO_PB4, GPIO_PB9, GPIO_PB8, GPIO_PB7, GPIO_PB11, | |
188 | +}; | |
189 | + | |
190 | +static const unsigned sport1_pins[] = { | |
191 | + GPIO_PE2, GPIO_PE5, GPIO_PD15, GPIO_PE4, GPIO_PE3, GPIO_PE1, | |
192 | +}; | |
193 | + | |
194 | +static const unsigned sport2_pins[] = { | |
195 | + GPIO_PG4, GPIO_PG1, GPIO_PG9, GPIO_PG10, GPIO_PG7, GPIO_PB12, | |
196 | +}; | |
197 | + | |
198 | +static const unsigned ppi0_8b_pins[] = { | |
199 | + GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, GPIO_PF4, GPIO_PF5, GPIO_PF6, | |
200 | + GPIO_PF7, GPIO_PF13, GPIO_PF14, GPIO_PF15, | |
201 | + GPIO_PE6, GPIO_PE7, GPIO_PE8, GPIO_PE9, | |
202 | +}; | |
203 | + | |
204 | +static const unsigned ppi0_16b_pins[] = { | |
205 | + GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, GPIO_PF4, GPIO_PF5, GPIO_PF6, | |
206 | + GPIO_PF7, GPIO_PF9, GPIO_PF10, GPIO_PF11, GPIO_PF12, | |
207 | + GPIO_PF13, GPIO_PF14, GPIO_PF15, | |
208 | + GPIO_PE6, GPIO_PE7, GPIO_PE8, GPIO_PE9, | |
209 | +}; | |
210 | + | |
211 | +static const unsigned ppi0_24b_pins[] = { | |
212 | + GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, GPIO_PF4, GPIO_PF5, GPIO_PF6, | |
213 | + GPIO_PF7, GPIO_PF8, GPIO_PF9, GPIO_PF10, GPIO_PF11, GPIO_PF12, | |
214 | + GPIO_PF13, GPIO_PF14, GPIO_PF15, GPIO_PE0, GPIO_PE1, GPIO_PE2, | |
215 | + GPIO_PE3, GPIO_PE4, GPIO_PE5, GPIO_PE6, GPIO_PE7, GPIO_PE8, | |
216 | + GPIO_PE9, GPIO_PD12, GPIO_PD15, | |
217 | +}; | |
218 | + | |
219 | +static const unsigned ppi1_8b_pins[] = { | |
220 | + GPIO_PC0, GPIO_PC1, GPIO_PC2, GPIO_PC3, GPIO_PC4, GPIO_PC5, GPIO_PC6, | |
221 | + GPIO_PC7, GPIO_PC8, GPIO_PB13, GPIO_PB14, GPIO_PB15, GPIO_PD6, | |
222 | +}; | |
223 | + | |
224 | +static const unsigned ppi1_16b_pins[] = { | |
225 | + GPIO_PC0, GPIO_PC1, GPIO_PC2, GPIO_PC3, GPIO_PC4, GPIO_PC5, GPIO_PC6, | |
226 | + GPIO_PC7, GPIO_PC9, GPIO_PC10, GPIO_PC11, GPIO_PC12, | |
227 | + GPIO_PC13, GPIO_PC14, GPIO_PC15, | |
228 | + GPIO_PB13, GPIO_PB14, GPIO_PB15, GPIO_PD6, | |
229 | +}; | |
230 | + | |
231 | +static const unsigned ppi2_8b_pins[] = { | |
232 | + GPIO_PA0, GPIO_PA1, GPIO_PA2, GPIO_PA3, GPIO_PA4, GPIO_PA5, GPIO_PA6, | |
233 | + GPIO_PA7, GPIO_PB0, GPIO_PB1, GPIO_PB2, GPIO_PB3, | |
234 | +}; | |
235 | + | |
236 | +static const unsigned ppi2_16b_pins[] = { | |
237 | + GPIO_PA0, GPIO_PA1, GPIO_PA2, GPIO_PA3, GPIO_PA4, GPIO_PA5, GPIO_PA6, | |
238 | + GPIO_PA7, GPIO_PA8, GPIO_PA9, GPIO_PA10, GPIO_PA11, GPIO_PA12, | |
239 | + GPIO_PA13, GPIO_PA14, GPIO_PA15, | |
240 | + GPIO_PA7, GPIO_PB0, GPIO_PB1, GPIO_PB2, GPIO_PB3, | |
241 | +}; | |
242 | + | |
243 | +static const unsigned lp0_pins[] = { | |
244 | + GPIO_PB0, GPIO_PB1, GPIO_PA0, GPIO_PA1, GPIO_PA2, GPIO_PA3, | |
245 | + GPIO_PA4, GPIO_PA5, GPIO_PA6, GPIO_PA7, | |
246 | +}; | |
247 | + | |
248 | +static const unsigned lp1_pins[] = { | |
249 | + GPIO_PB3, GPIO_PB2, GPIO_PA8, GPIO_PA9, GPIO_PA10, GPIO_PA11, | |
250 | + GPIO_PA12, GPIO_PA13, GPIO_PA14, GPIO_PA15, | |
251 | +}; | |
252 | + | |
253 | +static const unsigned lp2_pins[] = { | |
254 | + GPIO_PE6, GPIO_PE7, GPIO_PF0, GPIO_PF1, GPIO_PF2, GPIO_PF3, | |
255 | + GPIO_PF4, GPIO_PF5, GPIO_PF6, GPIO_PF7, | |
256 | +}; | |
257 | + | |
258 | +static const unsigned lp3_pins[] = { | |
259 | + GPIO_PE9, GPIO_PE8, GPIO_PF8, GPIO_PF9, GPIO_PF10, GPIO_PF11, | |
260 | + GPIO_PF12, GPIO_PF13, GPIO_PF14, GPIO_PF15, | |
261 | +}; | |
262 | + | |
263 | +static const struct adi_pin_group adi_pin_groups[] = { | |
264 | + ADI_PIN_GROUP("uart0grp", uart0_pins), | |
265 | + ADI_PIN_GROUP("uart0ctsrtsgrp", uart0_ctsrts_pins), | |
266 | + ADI_PIN_GROUP("uart1grp", uart1_pins), | |
267 | + ADI_PIN_GROUP("uart1ctsrtsgrp", uart1_ctsrts_pins), | |
268 | + ADI_PIN_GROUP("rsi0grp", rsi0_pins), | |
269 | + ADI_PIN_GROUP("eth0grp", eth0_pins), | |
270 | + ADI_PIN_GROUP("eth1grp", eth1_pins), | |
271 | + ADI_PIN_GROUP("spi0grp", spi0_pins), | |
272 | + ADI_PIN_GROUP("spi1grp", spi1_pins), | |
273 | + ADI_PIN_GROUP("twi0grp", twi0_pins), | |
274 | + ADI_PIN_GROUP("twi1grp", twi1_pins), | |
275 | + ADI_PIN_GROUP("rotarygrp", rotary_pins), | |
276 | + ADI_PIN_GROUP("can0grp", can0_pins), | |
277 | + ADI_PIN_GROUP("smc0grp", smc0_pins), | |
278 | + ADI_PIN_GROUP("sport0grp", sport0_pins), | |
279 | + ADI_PIN_GROUP("sport1grp", sport1_pins), | |
280 | + ADI_PIN_GROUP("sport2grp", sport2_pins), | |
281 | + ADI_PIN_GROUP("ppi0_8bgrp", ppi0_8b_pins), | |
282 | + ADI_PIN_GROUP("ppi0_16bgrp", ppi0_16b_pins), | |
283 | + ADI_PIN_GROUP("ppi0_24bgrp", ppi0_24b_pins), | |
284 | + ADI_PIN_GROUP("ppi1_8bgrp", ppi1_8b_pins), | |
285 | + ADI_PIN_GROUP("ppi1_16bgrp", ppi1_16b_pins), | |
286 | + ADI_PIN_GROUP("ppi2_8bgrp", ppi2_8b_pins), | |
287 | + ADI_PIN_GROUP("ppi2_16bgrp", ppi2_16b_pins), | |
288 | + ADI_PIN_GROUP("lp0grp", lp0_pins), | |
289 | + ADI_PIN_GROUP("lp1grp", lp1_pins), | |
290 | + ADI_PIN_GROUP("lp2grp", lp2_pins), | |
291 | + ADI_PIN_GROUP("lp3grp", lp3_pins), | |
292 | +}; | |
293 | + | |
294 | +static const unsigned short uart0_mux[] = { | |
295 | + P_UART0_TX, P_UART0_RX, | |
296 | + 0 | |
297 | +}; | |
298 | + | |
299 | +static const unsigned short uart0_ctsrts_mux[] = { | |
300 | + P_UART0_RTS, P_UART0_CTS, | |
301 | + 0 | |
302 | +}; | |
303 | + | |
304 | +static const unsigned short uart1_mux[] = { | |
305 | + P_UART1_TX, P_UART1_RX, | |
306 | + 0 | |
307 | +}; | |
308 | + | |
309 | +static const unsigned short uart1_ctsrts_mux[] = { | |
310 | + P_UART1_RTS, P_UART1_CTS, | |
311 | + 0 | |
312 | +}; | |
313 | + | |
314 | +static const unsigned short rsi0_mux[] = { | |
315 | + P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3, | |
316 | + P_RSI_CMD, P_RSI_CLK, 0 | |
317 | +}; | |
318 | + | |
319 | +static const unsigned short eth0_mux[] = P_RMII0; | |
320 | +static const unsigned short eth1_mux[] = P_RMII1; | |
321 | + | |
322 | +static const unsigned short spi0_mux[] = { | |
323 | + P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0 | |
324 | +}; | |
325 | + | |
326 | +static const unsigned short spi1_mux[] = { | |
327 | + P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0 | |
328 | +}; | |
329 | + | |
330 | +static const unsigned short twi0_mux[] = { | |
331 | + P_TWI0_SCL, P_TWI0_SDA, 0 | |
332 | +}; | |
333 | + | |
334 | +static const unsigned short twi1_mux[] = { | |
335 | + P_TWI1_SCL, P_TWI1_SDA, 0 | |
336 | +}; | |
337 | + | |
338 | +static const unsigned short rotary_mux[] = { | |
339 | + P_CNT_CUD, P_CNT_CDG, P_CNT_CZM, 0 | |
340 | +}; | |
341 | + | |
342 | +static const unsigned short sport0_mux[] = { | |
343 | + P_SPORT0_ACLK, P_SPORT0_AFS, P_SPORT0_AD0, P_SPORT0_BCLK, | |
344 | + P_SPORT0_BFS, P_SPORT0_BD0, 0, | |
345 | +}; | |
346 | + | |
347 | +static const unsigned short sport1_mux[] = { | |
348 | + P_SPORT1_ACLK, P_SPORT1_AFS, P_SPORT1_AD0, P_SPORT1_BCLK, | |
349 | + P_SPORT1_BFS, P_SPORT1_BD0, 0, | |
350 | +}; | |
351 | + | |
352 | +static const unsigned short sport2_mux[] = { | |
353 | + P_SPORT2_ACLK, P_SPORT2_AFS, P_SPORT2_AD0, P_SPORT2_BCLK, | |
354 | + P_SPORT2_BFS, P_SPORT2_BD0, 0, | |
355 | +}; | |
356 | + | |
357 | +static const unsigned short can0_mux[] = { | |
358 | + P_CAN0_RX, P_CAN0_TX, 0 | |
359 | +}; | |
360 | + | |
361 | +static const unsigned short smc0_mux[] = { | |
362 | + P_A3, P_A4, P_A5, P_A6, P_A7, P_A8, P_A9, P_A10, P_A11, P_A12, | |
363 | + P_A13, P_A14, P_A15, P_A16, P_A17, P_A18, P_A19, P_A20, P_A21, | |
364 | + P_A22, P_A23, P_A24, P_A25, P_NORCK, 0, | |
365 | +}; | |
366 | + | |
367 | +static const unsigned short ppi0_8b_mux[] = { | |
368 | + P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, | |
369 | + P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, | |
370 | + P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, | |
371 | + 0, | |
372 | +}; | |
373 | + | |
374 | +static const unsigned short ppi0_16b_mux[] = { | |
375 | + P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, | |
376 | + P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, | |
377 | + P_PPI0_D8, P_PPI0_D9, P_PPI0_D10, P_PPI0_D11, | |
378 | + P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, P_PPI0_D15, | |
379 | + P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, | |
380 | + 0, | |
381 | +}; | |
382 | + | |
383 | +static const unsigned short ppi0_24b_mux[] = { | |
384 | + P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, | |
385 | + P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, | |
386 | + P_PPI0_D8, P_PPI0_D9, P_PPI0_D10, P_PPI0_D11, | |
387 | + P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, P_PPI0_D15, | |
388 | + P_PPI0_D16, P_PPI0_D17, P_PPI0_D18, P_PPI0_D19, | |
389 | + P_PPI0_D20, P_PPI0_D21, P_PPI0_D22, P_PPI0_D23, | |
390 | + P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, | |
391 | + 0, | |
392 | +}; | |
393 | + | |
394 | +static const unsigned short ppi1_8b_mux[] = { | |
395 | + P_PPI1_D0, P_PPI1_D1, P_PPI1_D2, P_PPI1_D3, | |
396 | + P_PPI1_D4, P_PPI1_D5, P_PPI1_D6, P_PPI1_D7, | |
397 | + P_PPI1_CLK, P_PPI1_FS1, P_PPI1_FS2, | |
398 | + 0, | |
399 | +}; | |
400 | + | |
401 | +static const unsigned short ppi1_16b_mux[] = { | |
402 | + P_PPI1_D0, P_PPI1_D1, P_PPI1_D2, P_PPI1_D3, | |
403 | + P_PPI1_D4, P_PPI1_D5, P_PPI1_D6, P_PPI1_D7, | |
404 | + P_PPI1_D8, P_PPI1_D9, P_PPI1_D10, P_PPI1_D11, | |
405 | + P_PPI1_D12, P_PPI1_D13, P_PPI1_D14, P_PPI1_D15, | |
406 | + P_PPI1_CLK, P_PPI1_FS1, P_PPI1_FS2, | |
407 | + 0, | |
408 | +}; | |
409 | + | |
410 | +static const unsigned short ppi2_8b_mux[] = { | |
411 | + P_PPI2_D0, P_PPI2_D1, P_PPI2_D2, P_PPI2_D3, | |
412 | + P_PPI2_D4, P_PPI2_D5, P_PPI2_D6, P_PPI2_D7, | |
413 | + P_PPI2_CLK, P_PPI2_FS1, P_PPI2_FS2, | |
414 | + 0, | |
415 | +}; | |
416 | + | |
417 | +static const unsigned short ppi2_16b_mux[] = { | |
418 | + P_PPI2_D0, P_PPI2_D1, P_PPI2_D2, P_PPI2_D3, | |
419 | + P_PPI2_D4, P_PPI2_D5, P_PPI2_D6, P_PPI2_D7, | |
420 | + P_PPI2_D8, P_PPI2_D9, P_PPI2_D10, P_PPI2_D11, | |
421 | + P_PPI2_D12, P_PPI2_D13, P_PPI2_D14, P_PPI2_D15, | |
422 | + P_PPI2_CLK, P_PPI2_FS1, P_PPI2_FS2, | |
423 | + 0, | |
424 | +}; | |
425 | + | |
426 | +static const unsigned short lp0_mux[] = { | |
427 | + P_LP0_CLK, P_LP0_ACK, P_LP0_D0, P_LP0_D1, P_LP0_D2, | |
428 | + P_LP0_D3, P_LP0_D4, P_LP0_D5, P_LP0_D6, P_LP0_D7, | |
429 | + 0 | |
430 | +}; | |
431 | + | |
432 | +static const unsigned short lp1_mux[] = { | |
433 | + P_LP1_CLK, P_LP1_ACK, P_LP1_D0, P_LP1_D1, P_LP1_D2, | |
434 | + P_LP1_D3, P_LP1_D4, P_LP1_D5, P_LP1_D6, P_LP1_D7, | |
435 | + 0 | |
436 | +}; | |
437 | + | |
438 | +static const unsigned short lp2_mux[] = { | |
439 | + P_LP2_CLK, P_LP2_ACK, P_LP2_D0, P_LP2_D1, P_LP2_D2, | |
440 | + P_LP2_D3, P_LP2_D4, P_LP2_D5, P_LP2_D6, P_LP2_D7, | |
441 | + 0 | |
442 | +}; | |
443 | + | |
444 | +static const unsigned short lp3_mux[] = { | |
445 | + P_LP3_CLK, P_LP3_ACK, P_LP3_D0, P_LP3_D1, P_LP3_D2, | |
446 | + P_LP3_D3, P_LP3_D4, P_LP3_D5, P_LP3_D6, P_LP3_D7, | |
447 | + 0 | |
448 | +}; | |
449 | + | |
450 | +static const char * const uart0grp[] = { "uart0grp" }; | |
451 | +static const char * const uart0ctsrtsgrp[] = { "uart0ctsrtsgrp" }; | |
452 | +static const char * const uart1grp[] = { "uart1grp" }; | |
453 | +static const char * const uart1ctsrtsgrp[] = { "uart1ctsrtsgrp" }; | |
454 | +static const char * const rsi0grp[] = { "rsi0grp" }; | |
455 | +static const char * const eth0grp[] = { "eth0grp" }; | |
456 | +static const char * const eth1grp[] = { "eth1grp" }; | |
457 | +static const char * const spi0grp[] = { "spi0grp" }; | |
458 | +static const char * const spi1grp[] = { "spi1grp" }; | |
459 | +static const char * const twi0grp[] = { "twi0grp" }; | |
460 | +static const char * const twi1grp[] = { "twi1grp" }; | |
461 | +static const char * const rotarygrp[] = { "rotarygrp" }; | |
462 | +static const char * const can0grp[] = { "can0grp" }; | |
463 | +static const char * const smc0grp[] = { "smc0grp" }; | |
464 | +static const char * const sport0grp[] = { "sport0grp" }; | |
465 | +static const char * const sport1grp[] = { "sport1grp" }; | |
466 | +static const char * const sport2grp[] = { "sport2grp" }; | |
467 | +static const char * const ppi0_8bgrp[] = { "ppi0_8bgrp" }; | |
468 | +static const char * const ppi0_16bgrp[] = { "ppi0_16bgrp" }; | |
469 | +static const char * const ppi0_24bgrp[] = { "ppi0_24bgrp" }; | |
470 | +static const char * const ppi1_8bgrp[] = { "ppi1_8bgrp" }; | |
471 | +static const char * const ppi1_16bgrp[] = { "ppi1_16bgrp" }; | |
472 | +static const char * const ppi2_8bgrp[] = { "ppi2_8bgrp" }; | |
473 | +static const char * const ppi2_16bgrp[] = { "ppi2_16bgrp" }; | |
474 | +static const char * const lp0grp[] = { "lp0grp" }; | |
475 | +static const char * const lp1grp[] = { "lp1grp" }; | |
476 | +static const char * const lp2grp[] = { "lp2grp" }; | |
477 | +static const char * const lp3grp[] = { "lp3grp" }; | |
478 | + | |
479 | +static const struct adi_pmx_func adi_pmx_functions[] = { | |
480 | + ADI_PMX_FUNCTION("uart0", uart0grp, uart0_mux), | |
481 | + ADI_PMX_FUNCTION("uart0_ctsrts", uart0ctsrtsgrp, uart0_ctsrts_mux), | |
482 | + ADI_PMX_FUNCTION("uart1", uart1grp, uart1_mux), | |
483 | + ADI_PMX_FUNCTION("uart1_ctsrts", uart1ctsrtsgrp, uart1_ctsrts_mux), | |
484 | + ADI_PMX_FUNCTION("rsi0", rsi0grp, rsi0_mux), | |
485 | + ADI_PMX_FUNCTION("eth0", eth0grp, eth0_mux), | |
486 | + ADI_PMX_FUNCTION("eth1", eth1grp, eth1_mux), | |
487 | + ADI_PMX_FUNCTION("spi0", spi0grp, spi0_mux), | |
488 | + ADI_PMX_FUNCTION("spi1", spi1grp, spi1_mux), | |
489 | + ADI_PMX_FUNCTION("twi0", twi0grp, twi0_mux), | |
490 | + ADI_PMX_FUNCTION("twi1", twi1grp, twi1_mux), | |
491 | + ADI_PMX_FUNCTION("rotary", rotarygrp, rotary_mux), | |
492 | + ADI_PMX_FUNCTION("can0", can0grp, can0_mux), | |
493 | + ADI_PMX_FUNCTION("smc0", smc0grp, smc0_mux), | |
494 | + ADI_PMX_FUNCTION("sport0", sport0grp, sport0_mux), | |
495 | + ADI_PMX_FUNCTION("sport1", sport1grp, sport1_mux), | |
496 | + ADI_PMX_FUNCTION("sport2", sport2grp, sport2_mux), | |
497 | + ADI_PMX_FUNCTION("ppi0_8b", ppi0_8bgrp, ppi0_8b_mux), | |
498 | + ADI_PMX_FUNCTION("ppi0_16b", ppi0_16bgrp, ppi0_16b_mux), | |
499 | + ADI_PMX_FUNCTION("ppi0_24b", ppi0_24bgrp, ppi0_24b_mux), | |
500 | + ADI_PMX_FUNCTION("ppi1_8b", ppi1_8bgrp, ppi1_8b_mux), | |
501 | + ADI_PMX_FUNCTION("ppi1_16b", ppi1_16bgrp, ppi1_16b_mux), | |
502 | + ADI_PMX_FUNCTION("ppi2_8b", ppi2_8bgrp, ppi2_8b_mux), | |
503 | + ADI_PMX_FUNCTION("ppi2_16b", ppi2_16bgrp, ppi2_16b_mux), | |
504 | + ADI_PMX_FUNCTION("lp0", lp0grp, lp0_mux), | |
505 | + ADI_PMX_FUNCTION("lp1", lp1grp, lp1_mux), | |
506 | + ADI_PMX_FUNCTION("lp2", lp2grp, lp2_mux), | |
507 | + ADI_PMX_FUNCTION("lp3", lp3grp, lp3_mux), | |
508 | +}; | |
509 | + | |
510 | +static const struct adi_pinctrl_soc_data adi_bf60x_soc = { | |
511 | + .functions = adi_pmx_functions, | |
512 | + .nfunctions = ARRAY_SIZE(adi_pmx_functions), | |
513 | + .groups = adi_pin_groups, | |
514 | + .ngroups = ARRAY_SIZE(adi_pin_groups), | |
515 | + .pins = adi_pads, | |
516 | + .npins = ARRAY_SIZE(adi_pads), | |
517 | +}; | |
518 | + | |
519 | +void adi_pinctrl_soc_init(const struct adi_pinctrl_soc_data **soc) | |
520 | +{ | |
521 | + *soc = &adi_bf60x_soc; | |
522 | +} |
drivers/pinctrl/pinctrl-adi2.c
Changes suppressed. Click to show
1 | +/* | |
2 | + * Pinctrl Driver for ADI GPIO2 controller | |
3 | + * | |
4 | + * Copyright 2007-2013 Analog Devices Inc. | |
5 | + * | |
6 | + * Licensed under the GPLv2 or later | |
7 | + */ | |
8 | + | |
9 | +#include <linux/bitops.h> | |
10 | +#include <linux/delay.h> | |
11 | +#include <linux/module.h> | |
12 | +#include <linux/err.h> | |
13 | +#include <linux/debugfs.h> | |
14 | +#include <linux/seq_file.h> | |
15 | +#include <linux/irq.h> | |
16 | +#include <linux/platform_data/pinctrl-adi2.h> | |
17 | +#include <linux/irqdomain.h> | |
18 | +#include <linux/irqchip/chained_irq.h> | |
19 | +#include <linux/pinctrl/pinctrl.h> | |
20 | +#include <linux/pinctrl/pinmux.h> | |
21 | +#include <linux/pinctrl/consumer.h> | |
22 | +#include <linux/pinctrl/machine.h> | |
23 | +#include <linux/syscore_ops.h> | |
24 | +#include <linux/gpio.h> | |
25 | +#include <asm/portmux.h> | |
26 | +#include "pinctrl-adi2.h" | |
27 | +#include "core.h" | |
28 | + | |
29 | +/* | |
30 | +According to the BF54x HRM, pint means "pin interrupt". | |
31 | +http://www.analog.com/static/imported-files/processor_manuals/ADSP-BF54x_hwr_rev1.2.pdf | |
32 | + | |
33 | +ADSP-BF54x processor Blackfin processors have four SIC interrupt chan- | |
34 | +nels dedicated to pin interrupt purposes. These channels are managed by | |
35 | +four hardware blocks, called PINT0, PINT1, PINT2, and PINT3. Every PINTx | |
36 | +block can sense to up to 32 pins. While PINT0 and PINT1 can sense the | |
37 | +pins of port A and port B, PINT2 and PINT3 manage all the pins from port | |
38 | +C to port J as shown in Figure 9-2. | |
39 | + | |
40 | +n BF54x HRM: | |
41 | +The ten GPIO ports are subdivided into 8-bit half ports, resulting in lower and | |
42 | +upper half 8-bit units. The PINTx_ASSIGN registers control the 8-bit multi- | |
43 | +plexers shown in Figure 9-3. Lower half units of eight pins can be | |
44 | +forwarded to either byte 0 or byte 2 of either associated PINTx block. | |
45 | +Upper half units can be forwarded to either byte 1 or byte 3 of the pin | |
46 | +interrupt blocks, without further restrictions. | |
47 | + | |
48 | +All MMR registers in the pin interrupt module are 32 bits wide. To simply the | |
49 | +mapping logic, this driver only maps a 16-bit gpio port to the upper or lower | |
50 | +16 bits of a PINTx block. You can find the Figure 9-3 on page 583. | |
51 | + | |
52 | +Each IRQ domain is binding to a GPIO bank device. 2 GPIO bank devices can map | |
53 | +to one PINT device. Two in "struct gpio_pint" are used to ease the PINT | |
54 | +interrupt handler. | |
55 | + | |
56 | +The GPIO bank mapping to the lower 16 bits of the PINT device set its IRQ | |
57 | +domain pointer in domain[0]. The IRQ domain pointer of the other bank is set | |
58 | +to domain[1]. PINT interrupt handler adi_gpio_handle_pint_irq() finds out | |
59 | +the current domain pointer according to whether the interrupt request mask | |
60 | +is in lower 16 bits (domain[0]) or upper 16bits (domain[1]). | |
61 | + | |
62 | +A PINT device is not part of a GPIO port device in Blackfin. Multiple GPIO | |
63 | +port devices can be mapped to the same PINT device. | |
64 | + | |
65 | +*/ | |
66 | + | |
67 | +static LIST_HEAD(adi_pint_list); | |
68 | +static LIST_HEAD(adi_gpio_port_list); | |
69 | + | |
70 | +#define DRIVER_NAME "pinctrl-adi2" | |
71 | + | |
72 | +#define PINT_HI_OFFSET 16 | |
73 | + | |
74 | +/** | |
75 | + * struct gpio_port_saved - GPIO port registers that should be saved between | |
76 | + * power suspend and resume operations. | |
77 | + * | |
78 | + * @fer: PORTx_FER register | |
79 | + * @data: PORTx_DATA register | |
80 | + * @dir: PORTx_DIR register | |
81 | + * @inen: PORTx_INEN register | |
82 | + * @mux: PORTx_MUX register | |
83 | + */ | |
84 | +struct gpio_port_saved { | |
85 | + u16 fer; | |
86 | + u16 data; | |
87 | + u16 dir; | |
88 | + u16 inen; | |
89 | + u32 mux; | |
90 | +}; | |
91 | + | |
92 | +/** | |
93 | + * struct gpio_pint - Pin interrupt controller device. Multiple ADI GPIO | |
94 | + * banks can be mapped into one Pin interrupt controller. | |
95 | + * | |
96 | + * @node: All gpio_pint instances are added to a global list. | |
97 | + * @base: PINT device register base address | |
98 | + * @irq: IRQ of the PINT device, it is the parent IRQ of all | |
99 | + * GPIO IRQs mapping to this device. | |
100 | + * @domain: [0] irq domain of the gpio port, whose hardware interrupts are | |
101 | + * mapping to the low 16-bit of the pint registers. | |
102 | + * [1] irq domain of the gpio port, whose hardware interrupts are | |
103 | + * mapping to the high 16-bit of the pint registers. | |
104 | + * @regs: address pointer to the PINT device | |
105 | + * @map_count: No more than 2 GPIO banks can be mapped to this PINT device. | |
106 | + * @lock: This lock make sure the irq_chip operations to one PINT device | |
107 | + * for different GPIO interrrupts are atomic. | |
108 | + * @pint_map_port: Set up the mapping between one PINT device and | |
109 | + * multiple GPIO banks. | |
110 | + */ | |
111 | +struct gpio_pint { | |
112 | + struct list_head node; | |
113 | + void __iomem *base; | |
114 | + int irq; | |
115 | + struct irq_domain *domain[2]; | |
116 | + struct gpio_pint_regs *regs; | |
117 | + struct adi_pm_pint_save saved_data; | |
118 | + int map_count; | |
119 | + spinlock_t lock; | |
120 | + | |
121 | + int (*pint_map_port)(struct gpio_pint *pint, bool assign, | |
122 | + u8 map, struct irq_domain *domain); | |
123 | +}; | |
124 | + | |
125 | +/** | |
126 | + * ADI pin controller | |
127 | + * | |
128 | + * @dev: a pointer back to containing device | |
129 | + * @pctl: the pinctrl device | |
130 | + * @soc: SoC data for this specific chip | |
131 | + */ | |
132 | +struct adi_pinctrl { | |
133 | + struct device *dev; | |
134 | + struct pinctrl_dev *pctl; | |
135 | + const struct adi_pinctrl_soc_data *soc; | |
136 | +}; | |
137 | + | |
138 | +/** | |
139 | + * struct gpio_port - GPIO bank device. Multiple ADI GPIO banks can be mapped | |
140 | + * into one pin interrupt controller. | |
141 | + * | |
142 | + * @node: All gpio_port instances are added to a list. | |
143 | + * @base: GPIO bank device register base address | |
144 | + * @irq_base: base IRQ of the GPIO bank device | |
145 | + * @width: PIN number of the GPIO bank device | |
146 | + * @regs: address pointer to the GPIO bank device | |
147 | + * @saved_data: registers that should be saved between PM operations. | |
148 | + * @dev: device structure of this GPIO bank | |
149 | + * @pint: GPIO PINT device that this GPIO bank mapped to | |
150 | + * @pint_map: GIOP bank mapping code in PINT device | |
151 | + * @pint_assign: The 32-bit PINT registers can be divided into 2 parts. A | |
152 | + * GPIO bank can be mapped into either low 16 bits[0] or high 16 | |
153 | + * bits[1] of each PINT register. | |
154 | + * @lock: This lock make sure the irq_chip operations to one PINT device | |
155 | + * for different GPIO interrrupts are atomic. | |
156 | + * @chip: abstract a GPIO controller | |
157 | + * @domain: The irq domain owned by the GPIO port. | |
158 | + * @rsvmap: Reservation map array for each pin in the GPIO bank | |
159 | + */ | |
160 | +struct gpio_port { | |
161 | + struct list_head node; | |
162 | + void __iomem *base; | |
163 | + unsigned int irq_base; | |
164 | + unsigned int width; | |
165 | + struct gpio_port_t *regs; | |
166 | + struct gpio_port_saved saved_data; | |
167 | + struct device *dev; | |
168 | + | |
169 | + struct gpio_pint *pint; | |
170 | + u8 pint_map; | |
171 | + bool pint_assign; | |
172 | + | |
173 | + spinlock_t lock; | |
174 | + struct gpio_chip chip; | |
175 | + struct irq_domain *domain; | |
176 | +}; | |
177 | + | |
178 | +static inline u8 pin_to_offset(struct pinctrl_gpio_range *range, unsigned pin) | |
179 | +{ | |
180 | + return pin - range->pin_base; | |
181 | +} | |
182 | + | |
183 | +static inline u32 hwirq_to_pintbit(struct gpio_port *port, int hwirq) | |
184 | +{ | |
185 | + return port->pint_assign ? BIT(hwirq) << PINT_HI_OFFSET : BIT(hwirq); | |
186 | +} | |
187 | + | |
188 | +static struct gpio_pint *find_gpio_pint(unsigned id) | |
189 | +{ | |
190 | + struct gpio_pint *pint; | |
191 | + int i = 0; | |
192 | + | |
193 | + list_for_each_entry(pint, &adi_pint_list, node) { | |
194 | + if (id == i) | |
195 | + return pint; | |
196 | + i++; | |
197 | + } | |
198 | + | |
199 | + return NULL; | |
200 | +} | |
201 | + | |
202 | +static inline void port_setup(struct gpio_port *port, unsigned offset, | |
203 | + bool use_for_gpio) | |
204 | +{ | |
205 | + struct gpio_port_t *regs = port->regs; | |
206 | + | |
207 | + if (use_for_gpio) | |
208 | + writew(readw(®s->port_fer) & ~BIT(offset), | |
209 | + ®s->port_fer); | |
210 | + else | |
211 | + writew(readw(®s->port_fer) | BIT(offset), ®s->port_fer); | |
212 | +} | |
213 | + | |
214 | +static inline void portmux_setup(struct gpio_port *port, unsigned offset, | |
215 | + unsigned short function) | |
216 | +{ | |
217 | + struct gpio_port_t *regs = port->regs; | |
218 | + u32 pmux; | |
219 | + | |
220 | + pmux = readl(®s->port_mux); | |
221 | + | |
222 | + /* The function field of each pin has 2 consecutive bits in | |
223 | + * the mux register. | |
224 | + */ | |
225 | + pmux &= ~(0x3 << (2 * offset)); | |
226 | + pmux |= (function & 0x3) << (2 * offset); | |
227 | + | |
228 | + writel(pmux, ®s->port_mux); | |
229 | +} | |
230 | + | |
231 | +static inline u16 get_portmux(struct gpio_port *port, unsigned offset) | |
232 | +{ | |
233 | + struct gpio_port_t *regs = port->regs; | |
234 | + u32 pmux = readl(®s->port_mux); | |
235 | + | |
236 | + /* The function field of each pin has 2 consecutive bits in | |
237 | + * the mux register. | |
238 | + */ | |
239 | + return pmux >> (2 * offset) & 0x3; | |
240 | +} | |
241 | + | |
242 | +static void adi_gpio_ack_irq(struct irq_data *d) | |
243 | +{ | |
244 | + unsigned long flags; | |
245 | + struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
246 | + struct gpio_pint_regs *regs = port->pint->regs; | |
247 | + unsigned pintbit = hwirq_to_pintbit(port, d->hwirq); | |
248 | + | |
249 | + spin_lock_irqsave(&port->lock, flags); | |
250 | + spin_lock_irqsave(&port->pint->lock, flags); | |
251 | + | |
252 | + if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) { | |
253 | + if (readl(®s->invert_set) & pintbit) | |
254 | + writel(pintbit, ®s->invert_clear); | |
255 | + else | |
256 | + writel(pintbit, ®s->invert_set); | |
257 | + } | |
258 | + | |
259 | + writel(pintbit, ®s->request); | |
260 | + | |
261 | + spin_unlock_irqrestore(&port->pint->lock, flags); | |
262 | + spin_unlock_irqrestore(&port->lock, flags); | |
263 | +} | |
264 | + | |
265 | +static void adi_gpio_mask_ack_irq(struct irq_data *d) | |
266 | +{ | |
267 | + unsigned long flags; | |
268 | + struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
269 | + struct gpio_pint_regs *regs = port->pint->regs; | |
270 | + unsigned pintbit = hwirq_to_pintbit(port, d->hwirq); | |
271 | + | |
272 | + spin_lock_irqsave(&port->lock, flags); | |
273 | + spin_lock_irqsave(&port->pint->lock, flags); | |
274 | + | |
275 | + if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) { | |
276 | + if (readl(®s->invert_set) & pintbit) | |
277 | + writel(pintbit, ®s->invert_clear); | |
278 | + else | |
279 | + writel(pintbit, ®s->invert_set); | |
280 | + } | |
281 | + | |
282 | + writel(pintbit, ®s->request); | |
283 | + writel(pintbit, ®s->mask_clear); | |
284 | + | |
285 | + spin_unlock_irqrestore(&port->pint->lock, flags); | |
286 | + spin_unlock_irqrestore(&port->lock, flags); | |
287 | +} | |
288 | + | |
289 | +static void adi_gpio_mask_irq(struct irq_data *d) | |
290 | +{ | |
291 | + unsigned long flags; | |
292 | + struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
293 | + struct gpio_pint_regs *regs = port->pint->regs; | |
294 | + | |
295 | + spin_lock_irqsave(&port->lock, flags); | |
296 | + spin_lock_irqsave(&port->pint->lock, flags); | |
297 | + | |
298 | + writel(hwirq_to_pintbit(port, d->hwirq), ®s->mask_clear); | |
299 | + | |
300 | + spin_unlock_irqrestore(&port->pint->lock, flags); | |
301 | + spin_unlock_irqrestore(&port->lock, flags); | |
302 | +} | |
303 | + | |
304 | +static void adi_gpio_unmask_irq(struct irq_data *d) | |
305 | +{ | |
306 | + unsigned long flags; | |
307 | + struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
308 | + struct gpio_pint_regs *regs = port->pint->regs; | |
309 | + | |
310 | + spin_lock_irqsave(&port->lock, flags); | |
311 | + spin_lock_irqsave(&port->pint->lock, flags); | |
312 | + | |
313 | + writel(hwirq_to_pintbit(port, d->hwirq), ®s->mask_set); | |
314 | + | |
315 | + spin_unlock_irqrestore(&port->pint->lock, flags); | |
316 | + spin_unlock_irqrestore(&port->lock, flags); | |
317 | +} | |
318 | + | |
319 | +static unsigned int adi_gpio_irq_startup(struct irq_data *d) | |
320 | +{ | |
321 | + unsigned long flags; | |
322 | + struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
323 | + struct gpio_pint_regs *regs = port->pint->regs; | |
324 | + | |
325 | + if (!port) { | |
326 | + dev_err(port->dev, "GPIO IRQ %d :Not exist\n", d->irq); | |
327 | + return -ENODEV; | |
328 | + } | |
329 | + | |
330 | + spin_lock_irqsave(&port->lock, flags); | |
331 | + spin_lock_irqsave(&port->pint->lock, flags); | |
332 | + | |
333 | + port_setup(port, d->hwirq, true); | |
334 | + writew(BIT(d->hwirq), &port->regs->dir_clear); | |
335 | + writew(readw(&port->regs->inen) | BIT(d->hwirq), &port->regs->inen); | |
336 | + | |
337 | + writel(hwirq_to_pintbit(port, d->hwirq), ®s->mask_set); | |
338 | + | |
339 | + spin_unlock_irqrestore(&port->pint->lock, flags); | |
340 | + spin_unlock_irqrestore(&port->lock, flags); | |
341 | + | |
342 | + return 0; | |
343 | +} | |
344 | + | |
345 | +static void adi_gpio_irq_shutdown(struct irq_data *d) | |
346 | +{ | |
347 | + unsigned long flags; | |
348 | + struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
349 | + struct gpio_pint_regs *regs = port->pint->regs; | |
350 | + | |
351 | + spin_lock_irqsave(&port->lock, flags); | |
352 | + spin_lock_irqsave(&port->pint->lock, flags); | |
353 | + | |
354 | + writel(hwirq_to_pintbit(port, d->hwirq), ®s->mask_clear); | |
355 | + | |
356 | + spin_unlock_irqrestore(&port->pint->lock, flags); | |
357 | + spin_unlock_irqrestore(&port->lock, flags); | |
358 | +} | |
359 | + | |
360 | +static int adi_gpio_irq_type(struct irq_data *d, unsigned int type) | |
361 | +{ | |
362 | + unsigned long flags; | |
363 | + struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
364 | + struct gpio_pint_regs *pint_regs = port->pint->regs; | |
365 | + unsigned pintmask; | |
366 | + unsigned int irq = d->irq; | |
367 | + int ret = 0; | |
368 | + char buf[16]; | |
369 | + | |
370 | + if (!port) { | |
371 | + dev_err(port->dev, "GPIO IRQ %d :Not exist\n", irq); | |
372 | + return -ENODEV; | |
373 | + } | |
374 | + | |
375 | + pintmask = hwirq_to_pintbit(port, d->hwirq); | |
376 | + | |
377 | + spin_lock_irqsave(&port->lock, flags); | |
378 | + spin_lock_irqsave(&port->pint->lock, flags); | |
379 | + | |
380 | + /* In case of interrupt autodetect, set irq type to edge sensitive. */ | |
381 | + if (type == IRQ_TYPE_PROBE) | |
382 | + type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | |
383 | + | |
384 | + if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | | |
385 | + IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { | |
386 | + snprintf(buf, 16, "gpio-irq%d", irq); | |
387 | + port_setup(port, d->hwirq, true); | |
388 | + } else | |
389 | + goto out; | |
390 | + | |
391 | + /* The GPIO interrupt is triggered only when its input value | |
392 | + * transfer from 0 to 1. So, invert the input value if the | |
393 | + * irq type is low or falling | |
394 | + */ | |
395 | + if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) | |
396 | + writel(pintmask, &pint_regs->invert_set); | |
397 | + else | |
398 | + writel(pintmask, &pint_regs->invert_clear); | |
399 | + | |
400 | + /* In edge sensitive case, if the input value of the requested irq | |
401 | + * is already 1, invert it. | |
402 | + */ | |
403 | + if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) { | |
404 | + if (gpio_get_value(port->chip.base + d->hwirq)) | |
405 | + writel(pintmask, &pint_regs->invert_set); | |
406 | + else | |
407 | + writel(pintmask, &pint_regs->invert_clear); | |
408 | + } | |
409 | + | |
410 | + if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { | |
411 | + writel(pintmask, &pint_regs->edge_set); | |
412 | + __irq_set_handler_locked(irq, handle_edge_irq); | |
413 | + } else { | |
414 | + writel(pintmask, &pint_regs->edge_clear); | |
415 | + __irq_set_handler_locked(irq, handle_level_irq); | |
416 | + } | |
417 | + | |
418 | +out: | |
419 | + spin_unlock_irqrestore(&port->pint->lock, flags); | |
420 | + spin_unlock_irqrestore(&port->lock, flags); | |
421 | + | |
422 | + return ret; | |
423 | +} | |
424 | + | |
425 | +#ifdef CONFIG_PM | |
426 | +static int adi_gpio_set_wake(struct irq_data *d, unsigned int state) | |
427 | +{ | |
428 | + struct gpio_port *port = irq_data_get_irq_chip_data(d); | |
429 | + | |
430 | + if (!port || !port->pint || port->pint->irq != d->irq) | |
431 | + return -EINVAL; | |
432 | + | |
433 | +#ifndef SEC_GCTL | |
434 | + adi_internal_set_wake(port->pint->irq, state); | |
435 | +#endif | |
436 | + | |
437 | + return 0; | |
438 | +} | |
439 | + | |
440 | +static int adi_pint_suspend(void) | |
441 | +{ | |
442 | + struct gpio_pint *pint; | |
443 | + | |
444 | + list_for_each_entry(pint, &adi_pint_list, node) { | |
445 | + writel(0xffffffff, &pint->regs->mask_clear); | |
446 | + pint->saved_data.assign = readl(&pint->regs->assign); | |
447 | + pint->saved_data.edge_set = readl(&pint->regs->edge_set); | |
448 | + pint->saved_data.invert_set = readl(&pint->regs->invert_set); | |
449 | + } | |
450 | + | |
451 | + return 0; | |
452 | +} | |
453 | + | |
454 | +static void adi_pint_resume(void) | |
455 | +{ | |
456 | + struct gpio_pint *pint; | |
457 | + | |
458 | + list_for_each_entry(pint, &adi_pint_list, node) { | |
459 | + writel(pint->saved_data.assign, &pint->regs->assign); | |
460 | + writel(pint->saved_data.edge_set, &pint->regs->edge_set); | |
461 | + writel(pint->saved_data.invert_set, &pint->regs->invert_set); | |
462 | + } | |
463 | +} | |
464 | + | |
465 | +static int adi_gpio_suspend(void) | |
466 | +{ | |
467 | + struct gpio_port *port; | |
468 | + | |
469 | + list_for_each_entry(port, &adi_gpio_port_list, node) { | |
470 | + port->saved_data.fer = readw(&port->regs->port_fer); | |
471 | + port->saved_data.mux = readl(&port->regs->port_mux); | |
472 | + port->saved_data.data = readw(&port->regs->data); | |
473 | + port->saved_data.inen = readw(&port->regs->inen); | |
474 | + port->saved_data.dir = readw(&port->regs->dir_set); | |
475 | + } | |
476 | + | |
477 | + return adi_pint_suspend(); | |
478 | +} | |
479 | + | |
480 | +static void adi_gpio_resume(void) | |
481 | +{ | |
482 | + struct gpio_port *port; | |
483 | + | |
484 | + adi_pint_resume(); | |
485 | + | |
486 | + list_for_each_entry(port, &adi_gpio_port_list, node) { | |
487 | + writel(port->saved_data.mux, &port->regs->port_mux); | |
488 | + writew(port->saved_data.fer, &port->regs->port_fer); | |
489 | + writew(port->saved_data.inen, &port->regs->inen); | |
490 | + writew(port->saved_data.data & port->saved_data.dir, | |
491 | + &port->regs->data_set); | |
492 | + writew(port->saved_data.dir, &port->regs->dir_set); | |
493 | + } | |
494 | + | |
495 | +} | |
496 | + | |
497 | +static struct syscore_ops gpio_pm_syscore_ops = { | |
498 | + .suspend = adi_gpio_suspend, | |
499 | + .resume = adi_gpio_resume, | |
500 | +}; | |
501 | +#else /* CONFIG_PM */ | |
502 | +#define adi_gpio_set_wake NULL | |
503 | +#endif /* CONFIG_PM */ | |
504 | + | |
505 | +#ifdef CONFIG_IRQ_PREFLOW_FASTEOI | |
506 | +static inline void preflow_handler(struct irq_desc *desc) | |
507 | +{ | |
508 | + if (desc->preflow_handler) | |
509 | + desc->preflow_handler(&desc->irq_data); | |
510 | +} | |
511 | +#else | |
512 | +static inline void preflow_handler(struct irq_desc *desc) { } | |
513 | +#endif | |
514 | + | |
515 | +static void adi_gpio_handle_pint_irq(unsigned int inta_irq, | |
516 | + struct irq_desc *desc) | |
517 | +{ | |
518 | + u32 request; | |
519 | + u32 level_mask, hwirq; | |
520 | + bool umask = false; | |
521 | + struct gpio_pint *pint = irq_desc_get_handler_data(desc); | |
522 | + struct irq_chip *chip = irq_desc_get_chip(desc); | |
523 | + struct gpio_pint_regs *regs = pint->regs; | |
524 | + struct irq_domain *domain; | |
525 | + | |
526 | + preflow_handler(desc); | |
527 | + chained_irq_enter(chip, desc); | |
528 | + | |
529 | + request = readl(®s->request); | |
530 | + level_mask = readl(®s->edge_set) & request; | |
531 | + | |
532 | + hwirq = 0; | |
533 | + domain = pint->domain[0]; | |
534 | + while (request) { | |
535 | + /* domain pointer need to be changed only once at IRQ 16 when | |
536 | + * we go through IRQ requests from bit 0 to bit 31. | |
537 | + */ | |
538 | + if (hwirq == PINT_HI_OFFSET) | |
539 | + domain = pint->domain[1]; | |
540 | + | |
541 | + if (request & 1) { | |
542 | + if (level_mask & BIT(hwirq)) { | |
543 | + umask = true; | |
544 | + chained_irq_exit(chip, desc); | |
545 | + } | |
546 | + generic_handle_irq(irq_find_mapping(domain, | |
547 | + hwirq % PINT_HI_OFFSET)); | |
548 | + } | |
549 | + | |
550 | + hwirq++; | |
551 | + request >>= 1; | |
552 | + } | |
553 | + | |
554 | + if (!umask) | |
555 | + chained_irq_exit(chip, desc); | |
556 | +} | |
557 | + | |
558 | +static struct irq_chip adi_gpio_irqchip = { | |
559 | + .name = "GPIO", | |
560 | + .irq_ack = adi_gpio_ack_irq, | |
561 | + .irq_mask = adi_gpio_mask_irq, | |
562 | + .irq_mask_ack = adi_gpio_mask_ack_irq, | |
563 | + .irq_unmask = adi_gpio_unmask_irq, | |
564 | + .irq_disable = adi_gpio_mask_irq, | |
565 | + .irq_enable = adi_gpio_unmask_irq, | |
566 | + .irq_set_type = adi_gpio_irq_type, | |
567 | + .irq_startup = adi_gpio_irq_startup, | |
568 | + .irq_shutdown = adi_gpio_irq_shutdown, | |
569 | + .irq_set_wake = adi_gpio_set_wake, | |
570 | +}; | |
571 | + | |
572 | +static int adi_get_groups_count(struct pinctrl_dev *pctldev) | |
573 | +{ | |
574 | + struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
575 | + | |
576 | + return pinctrl->soc->ngroups; | |
577 | +} | |
578 | + | |
579 | +static const char *adi_get_group_name(struct pinctrl_dev *pctldev, | |
580 | + unsigned selector) | |
581 | +{ | |
582 | + struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
583 | + | |
584 | + return pinctrl->soc->groups[selector].name; | |
585 | +} | |
586 | + | |
587 | +static int adi_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, | |
588 | + const unsigned **pins, | |
589 | + unsigned *num_pins) | |
590 | +{ | |
591 | + struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
592 | + | |
593 | + *pins = pinctrl->soc->groups[selector].pins; | |
594 | + *num_pins = pinctrl->soc->groups[selector].num; | |
595 | + return 0; | |
596 | +} | |
597 | + | |
598 | +static struct pinctrl_ops adi_pctrl_ops = { | |
599 | + .get_groups_count = adi_get_groups_count, | |
600 | + .get_group_name = adi_get_group_name, | |
601 | + .get_group_pins = adi_get_group_pins, | |
602 | +}; | |
603 | + | |
604 | +static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector, | |
605 | + unsigned group) | |
606 | +{ | |
607 | + struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
608 | + struct gpio_port *port; | |
609 | + struct pinctrl_gpio_range *range; | |
610 | + unsigned long flags; | |
611 | + unsigned short *mux, pin; | |
612 | + | |
613 | + mux = (unsigned short *)pinctrl->soc->functions[selector].mux; | |
614 | + | |
615 | + while (*mux) { | |
616 | + pin = P_IDENT(*mux); | |
617 | + | |
618 | + range = pinctrl_find_gpio_range_from_pin(pctldev, pin); | |
619 | + if (range == NULL) /* should not happen */ | |
620 | + return -ENODEV; | |
621 | + | |
622 | + port = container_of(range->gc, struct gpio_port, chip); | |
623 | + | |
624 | + spin_lock_irqsave(&port->lock, flags); | |
625 | + | |
626 | + portmux_setup(port, pin_to_offset(range, pin), | |
627 | + P_FUNCT2MUX(*mux)); | |
628 | + port_setup(port, pin_to_offset(range, pin), false); | |
629 | + mux++; | |
630 | + | |
631 | + spin_unlock_irqrestore(&port->lock, flags); | |
632 | + } | |
633 | + | |
634 | + return 0; | |
635 | +} | |
636 | + | |
637 | +static void adi_pinmux_disable(struct pinctrl_dev *pctldev, unsigned selector, | |
638 | + unsigned group) | |
639 | +{ | |
640 | + struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
641 | + struct gpio_port *port; | |
642 | + struct pinctrl_gpio_range *range; | |
643 | + unsigned long flags; | |
644 | + unsigned short *mux, pin; | |
645 | + | |
646 | + mux = (unsigned short *)pinctrl->soc->functions[selector].mux; | |
647 | + | |
648 | + while (*mux) { | |
649 | + pin = P_IDENT(*mux); | |
650 | + | |
651 | + range = pinctrl_find_gpio_range_from_pin(pctldev, pin); | |
652 | + if (range == NULL) /* should not happen */ | |
653 | + return; | |
654 | + | |
655 | + port = container_of(range->gc, struct gpio_port, chip); | |
656 | + | |
657 | + spin_lock_irqsave(&port->lock, flags); | |
658 | + | |
659 | + port_setup(port, pin_to_offset(range, pin), true); | |
660 | + mux++; | |
661 | + | |
662 | + spin_unlock_irqrestore(&port->lock, flags); | |
663 | + } | |
664 | +} | |
665 | + | |
666 | +static int adi_pinmux_get_funcs_count(struct pinctrl_dev *pctldev) | |
667 | +{ | |
668 | + struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
669 | + | |
670 | + return pinctrl->soc->nfunctions; | |
671 | +} | |
672 | + | |
673 | +static const char *adi_pinmux_get_func_name(struct pinctrl_dev *pctldev, | |
674 | + unsigned selector) | |
675 | +{ | |
676 | + struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
677 | + | |
678 | + return pinctrl->soc->functions[selector].name; | |
679 | +} | |
680 | + | |
681 | +static int adi_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned selector, | |
682 | + const char * const **groups, | |
683 | + unsigned * const num_groups) | |
684 | +{ | |
685 | + struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev); | |
686 | + | |
687 | + *groups = pinctrl->soc->functions[selector].groups; | |
688 | + *num_groups = pinctrl->soc->functions[selector].num_groups; | |
689 | + return 0; | |
690 | +} | |
691 | + | |
692 | +static int adi_pinmux_request_gpio(struct pinctrl_dev *pctldev, | |
693 | + struct pinctrl_gpio_range *range, unsigned pin) | |
694 | +{ | |
695 | + struct gpio_port *port; | |
696 | + unsigned long flags; | |
697 | + u8 offset; | |
698 | + | |
699 | + port = container_of(range->gc, struct gpio_port, chip); | |
700 | + offset = pin_to_offset(range, pin); | |
701 | + | |
702 | + spin_lock_irqsave(&port->lock, flags); | |
703 | + | |
704 | + port_setup(port, offset, true); | |
705 | + | |
706 | + spin_unlock_irqrestore(&port->lock, flags); | |
707 | + | |
708 | + return 0; | |
709 | +} | |
710 | + | |
711 | +static struct pinmux_ops adi_pinmux_ops = { | |
712 | + .enable = adi_pinmux_enable, | |
713 | + .disable = adi_pinmux_disable, | |
714 | + .get_functions_count = adi_pinmux_get_funcs_count, | |
715 | + .get_function_name = adi_pinmux_get_func_name, | |
716 | + .get_function_groups = adi_pinmux_get_groups, | |
717 | + .gpio_request_enable = adi_pinmux_request_gpio, | |
718 | +}; | |
719 | + | |
720 | + | |
721 | +static struct pinctrl_desc adi_pinmux_desc = { | |
722 | + .name = DRIVER_NAME, | |
723 | + .pctlops = &adi_pctrl_ops, | |
724 | + .pmxops = &adi_pinmux_ops, | |
725 | + .owner = THIS_MODULE, | |
726 | +}; | |
727 | + | |
728 | +static int adi_gpio_request(struct gpio_chip *chip, unsigned offset) | |
729 | +{ | |
730 | + return pinctrl_request_gpio(chip->base + offset); | |
731 | +} | |
732 | + | |
733 | +static void adi_gpio_free(struct gpio_chip *chip, unsigned offset) | |
734 | +{ | |
735 | + pinctrl_free_gpio(chip->base + offset); | |
736 | +} | |
737 | + | |
738 | +static int adi_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | |
739 | +{ | |
740 | + struct gpio_port *port; | |
741 | + unsigned long flags; | |
742 | + | |
743 | + port = container_of(chip, struct gpio_port, chip); | |
744 | + | |
745 | + spin_lock_irqsave(&port->lock, flags); | |
746 | + | |
747 | + writew(BIT(offset), &port->regs->dir_clear); | |
748 | + writew(readw(&port->regs->inen) | BIT(offset), &port->regs->inen); | |
749 | + | |
750 | + spin_unlock_irqrestore(&port->lock, flags); | |
751 | + | |
752 | + return 0; | |
753 | +} | |
754 | + | |
755 | +static void adi_gpio_set_value(struct gpio_chip *chip, unsigned offset, | |
756 | + int value) | |
757 | +{ | |
758 | + struct gpio_port *port = container_of(chip, struct gpio_port, chip); | |
759 | + struct gpio_port_t *regs = port->regs; | |
760 | + unsigned long flags; | |
761 | + | |
762 | + spin_lock_irqsave(&port->lock, flags); | |
763 | + | |
764 | + if (value) | |
765 | + writew(1 << offset, ®s->data_set); | |
766 | + else | |
767 | + writew(1 << offset, ®s->data_clear); | |
768 | + | |
769 | + spin_unlock_irqrestore(&port->lock, flags); | |
770 | +} | |
771 | + | |
772 | +static int adi_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | |
773 | + int value) | |
774 | +{ | |
775 | + struct gpio_port *port = container_of(chip, struct gpio_port, chip); | |
776 | + struct gpio_port_t *regs = port->regs; | |
777 | + unsigned long flags; | |
778 | + | |
779 | + spin_lock_irqsave(&port->lock, flags); | |
780 | + | |
781 | + writew(readw(®s->inen) & ~(1 << offset), ®s->inen); | |
782 | + adi_gpio_set_value(chip, offset, value); | |
783 | + writew(1 << offset, ®s->dir_set); | |
784 | + | |
785 | + spin_unlock_irqrestore(&port->lock, flags); | |
786 | + | |
787 | + return 0; | |
788 | +} | |
789 | + | |
790 | +static int adi_gpio_get_value(struct gpio_chip *chip, unsigned offset) | |
791 | +{ | |
792 | + struct gpio_port *port = container_of(chip, struct gpio_port, chip); | |
793 | + struct gpio_port_t *regs = port->regs; | |
794 | + unsigned long flags; | |
795 | + int ret; | |
796 | + | |
797 | + spin_lock_irqsave(&port->lock, flags); | |
798 | + | |
799 | + ret = !!(readw(®s->data) & BIT(offset)); | |
800 | + | |
801 | + spin_unlock_irqrestore(&port->lock, flags); | |
802 | + | |
803 | + return ret; | |
804 | +} | |
805 | + | |
806 | +static int adi_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |
807 | +{ | |
808 | + struct gpio_port *port = container_of(chip, struct gpio_port, chip); | |
809 | + | |
810 | + if (port->irq_base >= 0) | |
811 | + return irq_find_mapping(port->domain, offset); | |
812 | + else | |
813 | + return irq_create_mapping(port->domain, offset); | |
814 | +} | |
815 | + | |
816 | +static int adi_pint_map_port(struct gpio_pint *pint, bool assign, u8 map, | |
817 | + struct irq_domain *domain) | |
818 | +{ | |
819 | + struct gpio_pint_regs *regs = pint->regs; | |
820 | + u32 map_mask; | |
821 | + | |
822 | + if (pint->map_count > 1) | |
823 | + return -EINVAL; | |
824 | + | |
825 | + pint->map_count++; | |
826 | + | |
827 | + /* The map_mask of each gpio port is a 16-bit duplicate | |
828 | + * of the 8-bit map. It can be set to either high 16 bits or low | |
829 | + * 16 bits of the pint assignment register. | |
830 | + */ | |
831 | + map_mask = (map << 8) | map; | |
832 | + if (assign) { | |
833 | + map_mask <<= PINT_HI_OFFSET; | |
834 | + writel((readl(®s->assign) & 0xFFFF) | map_mask, | |
835 | + ®s->assign); | |
836 | + } else | |
837 | + writel((readl(®s->assign) & 0xFFFF0000) | map_mask, | |
838 | + ®s->assign); | |
839 | + | |
840 | + pint->domain[assign] = domain; | |
841 | + | |
842 | + return 0; | |
843 | +} | |
844 | + | |
845 | +static int adi_gpio_pint_probe(struct platform_device *pdev) | |
846 | +{ | |
847 | + struct device *dev = &pdev->dev; | |
848 | + struct resource *res; | |
849 | + struct gpio_pint *pint; | |
850 | + | |
851 | + pint = devm_kzalloc(dev, sizeof(struct gpio_pint), GFP_KERNEL); | |
852 | + if (!pint) { | |
853 | + dev_err(dev, "Memory alloc failed\n"); | |
854 | + return -ENOMEM; | |
855 | + } | |
856 | + | |
857 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
858 | + if (!res) { | |
859 | + dev_err(dev, "Invalid mem resource\n"); | |
860 | + return -ENODEV; | |
861 | + } | |
862 | + | |
863 | + if (!devm_request_mem_region(dev, res->start, resource_size(res), | |
864 | + pdev->name)) { | |
865 | + dev_err(dev, "Region already claimed\n"); | |
866 | + return -EBUSY; | |
867 | + } | |
868 | + | |
869 | + pint->base = devm_ioremap(dev, res->start, resource_size(res)); | |
870 | + if (!pint->base) { | |
871 | + dev_err(dev, "Could not ioremap\n"); | |
872 | + return -ENOMEM; | |
873 | + } | |
874 | + | |
875 | + pint->regs = (struct gpio_pint_regs *)pint->base; | |
876 | + | |
877 | + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | |
878 | + if (!res) { | |
879 | + dev_err(dev, "Invalid IRQ resource\n"); | |
880 | + return -ENODEV; | |
881 | + } | |
882 | + | |
883 | + spin_lock_init(&pint->lock); | |
884 | + | |
885 | + pint->irq = res->start; | |
886 | + pint->pint_map_port = adi_pint_map_port; | |
887 | + platform_set_drvdata(pdev, pint); | |
888 | + | |
889 | + irq_set_chained_handler(pint->irq, adi_gpio_handle_pint_irq); | |
890 | + irq_set_handler_data(pint->irq, pint); | |
891 | + | |
892 | + list_add_tail(&pint->node, &adi_pint_list); | |
893 | + | |
894 | + return 0; | |
895 | +} | |
896 | + | |
897 | +static int adi_gpio_pint_remove(struct platform_device *pdev) | |
898 | +{ | |
899 | + struct gpio_pint *pint = platform_get_drvdata(pdev); | |
900 | + | |
901 | + list_del(&pint->node); | |
902 | + irq_set_handler(pint->irq, handle_simple_irq); | |
903 | + | |
904 | + return 0; | |
905 | +} | |
906 | + | |
907 | +static int adi_gpio_irq_map(struct irq_domain *d, unsigned int irq, | |
908 | + irq_hw_number_t hwirq) | |
909 | +{ | |
910 | + struct gpio_port *port = d->host_data; | |
911 | + | |
912 | + if (!port) | |
913 | + return -EINVAL; | |
914 | + | |
915 | + irq_set_chip_data(irq, port); | |
916 | + irq_set_chip_and_handler(irq, &adi_gpio_irqchip, | |
917 | + handle_level_irq); | |
918 | + | |
919 | + return 0; | |
920 | +} | |
921 | + | |
922 | +const struct irq_domain_ops adi_gpio_irq_domain_ops = { | |
923 | + .map = adi_gpio_irq_map, | |
924 | + .xlate = irq_domain_xlate_onecell, | |
925 | +}; | |
926 | + | |
927 | +static int adi_gpio_init_int(struct gpio_port *port) | |
928 | +{ | |
929 | + struct device_node *node = port->dev->of_node; | |
930 | + struct gpio_pint *pint = port->pint; | |
931 | + int ret; | |
932 | + | |
933 | + port->domain = irq_domain_add_linear(node, port->width, | |
934 | + &adi_gpio_irq_domain_ops, port); | |
935 | + if (!port->domain) { | |
936 | + dev_err(port->dev, "Failed to create irqdomain\n"); | |
937 | + return -ENOSYS; | |
938 | + } | |
939 | + | |
940 | + /* According to BF54x and BF60x HRM, pin interrupt devices are not | |
941 | + * part of the GPIO port device. in GPIO interrupt mode, the GPIO | |
942 | + * pins of multiple port devices can be routed into one pin interrupt | |
943 | + * device. The mapping can be configured by setting pint assignment | |
944 | + * register with the mapping value of different GPIO port. This is | |
945 | + * done via function pint_map_port(). | |
946 | + */ | |
947 | + ret = pint->pint_map_port(port->pint, port->pint_assign, | |
948 | + port->pint_map, port->domain); | |
949 | + if (ret) | |
950 | + return ret; | |
951 | + | |
952 | + if (port->irq_base >= 0) { | |
953 | + ret = irq_create_strict_mappings(port->domain, port->irq_base, | |
954 | + 0, port->width); | |
955 | + if (ret) { | |
956 | + dev_err(port->dev, "Couldn't associate to domain\n"); | |
957 | + return ret; | |
958 | + } | |
959 | + } | |
960 | + | |
961 | + return 0; | |
962 | +} | |
963 | + | |
964 | +#define DEVNAME_SIZE 16 | |
965 | + | |
966 | +static int adi_gpio_probe(struct platform_device *pdev) | |
967 | +{ | |
968 | + struct device *dev = &pdev->dev; | |
969 | + const struct adi_pinctrl_gpio_platform_data *pdata; | |
970 | + struct resource *res; | |
971 | + struct gpio_port *port; | |
972 | + char pinctrl_devname[DEVNAME_SIZE]; | |
973 | + static int gpio; | |
974 | + int ret = 0, ret1; | |
975 | + | |
976 | + pdata = dev->platform_data; | |
977 | + if (!pdata) | |
978 | + return -EINVAL; | |
979 | + | |
980 | + port = devm_kzalloc(dev, sizeof(struct gpio_port), GFP_KERNEL); | |
981 | + if (!port) { | |
982 | + dev_err(dev, "Memory alloc failed\n"); | |
983 | + return -ENOMEM; | |
984 | + } | |
985 | + | |
986 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
987 | + if (!res) { | |
988 | + dev_err(dev, "Invalid mem resource\n"); | |
989 | + return -ENODEV; | |
990 | + } | |
991 | + | |
992 | + if (!devm_request_mem_region(dev, res->start, resource_size(res), | |
993 | + pdev->name)) { | |
994 | + dev_err(dev, "Region already claimed\n"); | |
995 | + return -EBUSY; | |
996 | + } | |
997 | + | |
998 | + port->base = devm_ioremap(dev, res->start, resource_size(res)); | |
999 | + if (!port->base) { | |
1000 | + dev_err(dev, "Could not ioremap\n"); | |
1001 | + return -ENOMEM; | |
1002 | + } | |
1003 | + | |
1004 | + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | |
1005 | + if (!res) | |
1006 | + port->irq_base = -1; | |
1007 | + else | |
1008 | + port->irq_base = res->start; | |
1009 | + | |
1010 | + port->width = pdata->port_width; | |
1011 | + port->dev = dev; | |
1012 | + port->regs = (struct gpio_port_t *)port->base; | |
1013 | + port->pint_assign = pdata->pint_assign; | |
1014 | + port->pint_map = pdata->pint_map; | |
1015 | + | |
1016 | + port->pint = find_gpio_pint(pdata->pint_id); | |
1017 | + if (port->pint) { | |
1018 | + ret = adi_gpio_init_int(port); | |
1019 | + if (ret) | |
1020 | + return ret; | |
1021 | + } | |
1022 | + | |
1023 | + spin_lock_init(&port->lock); | |
1024 | + | |
1025 | + platform_set_drvdata(pdev, port); | |
1026 | + | |
1027 | + port->chip.label = "adi-gpio"; | |
1028 | + port->chip.direction_input = adi_gpio_direction_input; | |
1029 | + port->chip.get = adi_gpio_get_value; | |
1030 | + port->chip.direction_output = adi_gpio_direction_output; | |
1031 | + port->chip.set = adi_gpio_set_value; | |
1032 | + port->chip.request = adi_gpio_request; | |
1033 | + port->chip.free = adi_gpio_free; | |
1034 | + port->chip.to_irq = adi_gpio_to_irq; | |
1035 | + if (pdata->port_gpio_base > 0) | |
1036 | + port->chip.base = pdata->port_gpio_base; | |
1037 | + else | |
1038 | + port->chip.base = gpio; | |
1039 | + port->chip.ngpio = port->width; | |
1040 | + gpio = port->chip.base + port->width; | |
1041 | + | |
1042 | + ret = gpiochip_add(&port->chip); | |
1043 | + if (ret) { | |
1044 | + dev_err(&pdev->dev, "Fail to add GPIO chip.\n"); | |
1045 | + goto out_remove_domain; | |
1046 | + } | |
1047 | + | |
1048 | + /* Add gpio pin range */ | |
1049 | + snprintf(pinctrl_devname, DEVNAME_SIZE, "pinctrl-adi2.%d", | |
1050 | + pdata->pinctrl_id); | |
1051 | + pinctrl_devname[DEVNAME_SIZE - 1] = 0; | |
1052 | + ret = gpiochip_add_pin_range(&port->chip, pinctrl_devname, | |
1053 | + 0, pdata->port_pin_base, port->width); | |
1054 | + if (ret) { | |
1055 | + dev_err(&pdev->dev, "Fail to add pin range to %s.\n", | |
1056 | + pinctrl_devname); | |
1057 | + goto out_remove_gpiochip; | |
1058 | + } | |
1059 | + | |
1060 | + list_add_tail(&port->node, &adi_gpio_port_list); | |
1061 | + | |
1062 | + return 0; | |
1063 | + | |
1064 | +out_remove_gpiochip: | |
1065 | + ret1 = gpiochip_remove(&port->chip); | |
1066 | +out_remove_domain: | |
1067 | + if (port->pint) | |
1068 | + irq_domain_remove(port->domain); | |
1069 | + | |
1070 | + return ret; | |
1071 | +} | |
1072 | + | |
1073 | +static int adi_gpio_remove(struct platform_device *pdev) | |
1074 | +{ | |
1075 | + struct gpio_port *port = platform_get_drvdata(pdev); | |
1076 | + int ret; | |
1077 | + u8 offset; | |
1078 | + | |
1079 | + list_del(&port->node); | |
1080 | + gpiochip_remove_pin_ranges(&port->chip); | |
1081 | + ret = gpiochip_remove(&port->chip); | |
1082 | + if (port->pint) { | |
1083 | + for (offset = 0; offset < port->width; offset++) | |
1084 | + irq_dispose_mapping(irq_find_mapping(port->domain, | |
1085 | + offset)); | |
1086 | + irq_domain_remove(port->domain); | |
1087 | + } | |
1088 | + | |
1089 | + return ret; | |
1090 | +} | |
1091 | + | |
1092 | +static int adi_pinctrl_probe(struct platform_device *pdev) | |
1093 | +{ | |
1094 | + struct adi_pinctrl *pinctrl; | |
1095 | + | |
1096 | + pinctrl = devm_kzalloc(&pdev->dev, sizeof(*pinctrl), GFP_KERNEL); | |
1097 | + if (!pinctrl) | |
1098 | + return -ENOMEM; | |
1099 | + | |
1100 | + pinctrl->dev = &pdev->dev; | |
1101 | + | |
1102 | + adi_pinctrl_soc_init(&pinctrl->soc); | |
1103 | + | |
1104 | + adi_pinmux_desc.pins = pinctrl->soc->pins; | |
1105 | + adi_pinmux_desc.npins = pinctrl->soc->npins; | |
1106 | + | |
1107 | + /* Now register the pin controller and all pins it handles */ | |
1108 | + pinctrl->pctl = pinctrl_register(&adi_pinmux_desc, &pdev->dev, pinctrl); | |
1109 | + if (!pinctrl->pctl) { | |
1110 | + dev_err(&pdev->dev, "could not register pinctrl ADI2 driver\n"); | |
1111 | + return -EINVAL; | |
1112 | + } | |
1113 | + | |
1114 | + platform_set_drvdata(pdev, pinctrl); | |
1115 | + | |
1116 | + return 0; | |
1117 | +} | |
1118 | + | |
1119 | +static int adi_pinctrl_remove(struct platform_device *pdev) | |
1120 | +{ | |
1121 | + struct adi_pinctrl *pinctrl = platform_get_drvdata(pdev); | |
1122 | + | |
1123 | + pinctrl_unregister(pinctrl->pctl); | |
1124 | + | |
1125 | + return 0; | |
1126 | +} | |
1127 | + | |
1128 | +static struct platform_driver adi_pinctrl_driver = { | |
1129 | + .probe = adi_pinctrl_probe, | |
1130 | + .remove = adi_pinctrl_remove, | |
1131 | + .driver = { | |
1132 | + .name = DRIVER_NAME, | |
1133 | + }, | |
1134 | +}; | |
1135 | + | |
1136 | +static struct platform_driver adi_gpio_pint_driver = { | |
1137 | + .probe = adi_gpio_pint_probe, | |
1138 | + .remove = adi_gpio_pint_remove, | |
1139 | + .driver = { | |
1140 | + .name = "adi-gpio-pint", | |
1141 | + }, | |
1142 | +}; | |
1143 | + | |
1144 | +static struct platform_driver adi_gpio_driver = { | |
1145 | + .probe = adi_gpio_probe, | |
1146 | + .remove = adi_gpio_remove, | |
1147 | + .driver = { | |
1148 | + .name = "adi-gpio", | |
1149 | + }, | |
1150 | +}; | |
1151 | + | |
1152 | +static int __init adi_pinctrl_setup(void) | |
1153 | +{ | |
1154 | + int ret; | |
1155 | + | |
1156 | + ret = platform_driver_register(&adi_pinctrl_driver); | |
1157 | + if (ret) | |
1158 | + return ret; | |
1159 | + | |
1160 | + ret = platform_driver_register(&adi_gpio_pint_driver); | |
1161 | + if (ret) | |
1162 | + goto pint_error; | |
1163 | + | |
1164 | + ret = platform_driver_register(&adi_gpio_driver); | |
1165 | + if (ret) | |
1166 | + goto gpio_error; | |
1167 | + | |
1168 | +#ifdef CONFIG_PM | |
1169 | + register_syscore_ops(&gpio_pm_syscore_ops); | |
1170 | +#endif | |
1171 | + return ret; | |
1172 | +gpio_error: | |
1173 | + platform_driver_unregister(&adi_gpio_pint_driver); | |
1174 | +pint_error: | |
1175 | + platform_driver_unregister(&adi_pinctrl_driver); | |
1176 | + | |
1177 | + return ret; | |
1178 | +} | |
1179 | +arch_initcall(adi_pinctrl_setup); | |
1180 | + | |
1181 | +MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); | |
1182 | +MODULE_DESCRIPTION("ADI gpio2 pin control driver"); | |
1183 | +MODULE_LICENSE("GPL"); |
drivers/pinctrl/pinctrl-adi2.h
1 | +/* | |
2 | + * Pinctrl Driver for ADI GPIO2 controller | |
3 | + * | |
4 | + * Copyright 2007-2013 Analog Devices Inc. | |
5 | + * | |
6 | + * Licensed under the GPLv2 or later | |
7 | + */ | |
8 | + | |
9 | +#ifndef PINCTRL_PINCTRL_ADI2_H | |
10 | +#define PINCTRL_PINCTRL_ADI2_H | |
11 | + | |
12 | +#include <linux/pinctrl/pinctrl.h> | |
13 | + | |
14 | + /** | |
15 | + * struct adi_pin_group - describes a pin group | |
16 | + * @name: the name of this pin group | |
17 | + * @pins: an array of pins | |
18 | + * @num: the number of pins in this array | |
19 | + */ | |
20 | +struct adi_pin_group { | |
21 | + const char *name; | |
22 | + const unsigned *pins; | |
23 | + const unsigned num; | |
24 | +}; | |
25 | + | |
26 | +#define ADI_PIN_GROUP(n, p) \ | |
27 | + { \ | |
28 | + .name = n, \ | |
29 | + .pins = p, \ | |
30 | + .num = ARRAY_SIZE(p), \ | |
31 | + } | |
32 | + | |
33 | + /** | |
34 | + * struct adi_pmx_func - describes function mux setting of pin groups | |
35 | + * @name: the name of this function mux setting | |
36 | + * @groups: an array of pin groups | |
37 | + * @num_groups: the number of pin groups in this array | |
38 | + * @mux: the function mux setting array, end by zero | |
39 | + */ | |
40 | +struct adi_pmx_func { | |
41 | + const char *name; | |
42 | + const char * const *groups; | |
43 | + const unsigned num_groups; | |
44 | + const unsigned short *mux; | |
45 | +}; | |
46 | + | |
47 | +#define ADI_PMX_FUNCTION(n, g, m) \ | |
48 | + { \ | |
49 | + .name = n, \ | |
50 | + .groups = g, \ | |
51 | + .num_groups = ARRAY_SIZE(g), \ | |
52 | + .mux = m, \ | |
53 | + } | |
54 | + | |
55 | +/** | |
56 | + * struct adi_pinctrl_soc_data - ADI pin controller per-SoC configuration | |
57 | + * @functions: The functions supported on this SoC. | |
58 | + * @nfunction: The number of entries in @functions. | |
59 | + * @groups: An array describing all pin groups the pin SoC supports. | |
60 | + * @ngroups: The number of entries in @groups. | |
61 | + * @pins: An array describing all pins the pin controller affects. | |
62 | + * @npins: The number of entries in @pins. | |
63 | + */ | |
64 | +struct adi_pinctrl_soc_data { | |
65 | + const struct adi_pmx_func *functions; | |
66 | + int nfunctions; | |
67 | + const struct adi_pin_group *groups; | |
68 | + int ngroups; | |
69 | + const struct pinctrl_pin_desc *pins; | |
70 | + int npins; | |
71 | +}; | |
72 | + | |
73 | +void adi_pinctrl_soc_init(const struct adi_pinctrl_soc_data **soc); | |
74 | + | |
75 | +#endif /* PINCTRL_PINCTRL_ADI2_H */ |
include/linux/platform_data/pinctrl-adi2.h
1 | +/* | |
2 | + * Pinctrl Driver for ADI GPIO2 controller | |
3 | + * | |
4 | + * Copyright 2007-2013 Analog Devices Inc. | |
5 | + * | |
6 | + * Licensed under the GPLv2 or later | |
7 | + */ | |
8 | + | |
9 | + | |
10 | +#ifndef PINCTRL_ADI2_H | |
11 | +#define PINCTRL_ADI2_H | |
12 | + | |
13 | +#include <linux/io.h> | |
14 | +#include <linux/platform_device.h> | |
15 | + | |
16 | +/** | |
17 | + * struct adi_pinctrl_gpio_platform_data - Pinctrl gpio platform data | |
18 | + * for ADI GPIO2 device. | |
19 | + * | |
20 | + * @port_gpio_base: Optional global GPIO index of the GPIO bank. | |
21 | + * 0 means driver decides. | |
22 | + * @port_pin_base: Pin index of the pin controller device. | |
23 | + * @port_width: PIN number of the GPIO bank device | |
24 | + * @pint_id: GPIO PINT device id that this GPIO bank should map to. | |
25 | + * @pint_assign: The 32-bit GPIO PINT registers can be divided into 2 parts. A | |
26 | + * GPIO bank can be mapped into either low 16 bits[0] or high 16 | |
27 | + * bits[1] of each PINT register. | |
28 | + * @pint_map: GIOP bank mapping code in PINT device | |
29 | + */ | |
30 | +struct adi_pinctrl_gpio_platform_data { | |
31 | + unsigned int port_gpio_base; | |
32 | + unsigned int port_pin_base; | |
33 | + unsigned int port_width; | |
34 | + u8 pinctrl_id; | |
35 | + u8 pint_id; | |
36 | + bool pint_assign; | |
37 | + u8 pint_map; | |
38 | +}; | |
39 | + | |
40 | +#endif |