1 // SPDX-License-Identifier: GPL-2.0
3 * Allocator for I/O pins. All pins are allocated to GPIO at bootup.
4 * Unassigned pins and GPIO pins can be allocated to a fixed interface
5 * or the I/O processor instead.
7 * Copyright (c) 2004-2007 Axis Communications AB.
10 #include <linux/init.h>
11 #include <linux/errno.h>
12 #include <linux/kernel.h>
13 #include <linux/string.h>
14 #include <linux/spinlock.h>
15 #include <hwregs/reg_map.h>
16 #include <hwregs/reg_rdwr.h>
18 #include <hwregs/pinmux_defs.h>
25 static char pins
[PORTS
][PORT_PINS
];
26 static DEFINE_SPINLOCK(pinmux_lock
);
28 static void crisv32_pinmux_set(int port
);
30 static int __crisv32_pinmux_alloc(int port
, int first_pin
, int last_pin
,
35 for (i
= first_pin
; i
<= last_pin
; i
++) {
36 if ((pins
[port
][i
] != pinmux_none
)
37 && (pins
[port
][i
] != pinmux_gpio
)
38 && (pins
[port
][i
] != mode
)) {
40 panic("Pinmux alloc failed!\n");
46 for (i
= first_pin
; i
<= last_pin
; i
++)
49 crisv32_pinmux_set(port
);
54 static int crisv32_pinmux_init(void)
56 static int initialized
;
59 reg_pinmux_rw_pa pa
= REG_RD(pinmux
, regi_pinmux
, rw_pa
);
61 REG_WR_INT(pinmux
, regi_pinmux
, rw_hwprot
, 0);
62 pa
.pa0
= pa
.pa1
= pa
.pa2
= pa
.pa3
=
63 pa
.pa4
= pa
.pa5
= pa
.pa6
= pa
.pa7
= regk_pinmux_yes
;
64 REG_WR(pinmux
, regi_pinmux
, rw_pa
, pa
);
65 __crisv32_pinmux_alloc(PORT_B
, 0, PORT_PINS
- 1, pinmux_gpio
);
66 __crisv32_pinmux_alloc(PORT_C
, 0, PORT_PINS
- 1, pinmux_gpio
);
67 __crisv32_pinmux_alloc(PORT_D
, 0, PORT_PINS
- 1, pinmux_gpio
);
68 __crisv32_pinmux_alloc(PORT_E
, 0, PORT_PINS
- 1, pinmux_gpio
);
74 int crisv32_pinmux_alloc(int port
, int first_pin
, int last_pin
,
80 crisv32_pinmux_init();
82 if (port
> PORTS
|| port
< 0)
85 spin_lock_irqsave(&pinmux_lock
, flags
);
87 ret
= __crisv32_pinmux_alloc(port
, first_pin
, last_pin
, mode
);
89 spin_unlock_irqrestore(&pinmux_lock
, flags
);
94 int crisv32_pinmux_alloc_fixed(enum fixed_function function
)
97 char saved
[sizeof pins
];
99 reg_pinmux_rw_hwprot hwprot
;
101 spin_lock_irqsave(&pinmux_lock
, flags
);
103 /* Save internal data for recovery */
104 memcpy(saved
, pins
, sizeof pins
);
106 crisv32_pinmux_init(); /* Must be done before we read rw_hwprot */
108 hwprot
= REG_RD(pinmux
, regi_pinmux
, rw_hwprot
);
112 ret
= __crisv32_pinmux_alloc(PORT_C
, 4, 7, pinmux_fixed
);
113 hwprot
.ser1
= regk_pinmux_yes
;
116 ret
= __crisv32_pinmux_alloc(PORT_C
, 8, 11, pinmux_fixed
);
117 hwprot
.ser2
= regk_pinmux_yes
;
120 ret
= __crisv32_pinmux_alloc(PORT_C
, 12, 15, pinmux_fixed
);
121 hwprot
.ser3
= regk_pinmux_yes
;
124 ret
= __crisv32_pinmux_alloc(PORT_C
, 0, 3, pinmux_fixed
);
125 ret
|= __crisv32_pinmux_alloc(PORT_C
, 16, 16, pinmux_fixed
);
126 hwprot
.sser0
= regk_pinmux_yes
;
129 ret
= __crisv32_pinmux_alloc(PORT_D
, 0, 4, pinmux_fixed
);
130 hwprot
.sser1
= regk_pinmux_yes
;
133 ret
= __crisv32_pinmux_alloc(PORT_D
, 5, 7, pinmux_fixed
);
134 ret
|= __crisv32_pinmux_alloc(PORT_D
, 15, 17, pinmux_fixed
);
135 hwprot
.ata0
= regk_pinmux_yes
;
138 ret
= __crisv32_pinmux_alloc(PORT_D
, 0, 4, pinmux_fixed
);
139 ret
|= __crisv32_pinmux_alloc(PORT_E
, 17, 17, pinmux_fixed
);
140 hwprot
.ata1
= regk_pinmux_yes
;
143 ret
= __crisv32_pinmux_alloc(PORT_C
, 11, 15, pinmux_fixed
);
144 ret
|= __crisv32_pinmux_alloc(PORT_E
, 3, 3, pinmux_fixed
);
145 hwprot
.ata2
= regk_pinmux_yes
;
148 ret
= __crisv32_pinmux_alloc(PORT_C
, 8, 10, pinmux_fixed
);
149 ret
|= __crisv32_pinmux_alloc(PORT_C
, 0, 2, pinmux_fixed
);
150 hwprot
.ata2
= regk_pinmux_yes
;
153 ret
= __crisv32_pinmux_alloc(PORT_B
, 0, 15, pinmux_fixed
);
154 ret
|= __crisv32_pinmux_alloc(PORT_D
, 8, 15, pinmux_fixed
);
155 hwprot
.ata
= regk_pinmux_yes
;
158 ret
= __crisv32_pinmux_alloc(PORT_E
, 0, 17, pinmux_fixed
);
159 hwprot
.eth1
= regk_pinmux_yes
;
160 hwprot
.eth1_mgm
= regk_pinmux_yes
;
163 ret
= __crisv32_pinmux_alloc(PORT_C
, 16, 16, pinmux_fixed
);
164 hwprot
.timer
= regk_pinmux_yes
;
165 spin_unlock_irqrestore(&pinmux_lock
, flags
);
170 REG_WR(pinmux
, regi_pinmux
, rw_hwprot
, hwprot
);
172 memcpy(pins
, saved
, sizeof pins
);
174 spin_unlock_irqrestore(&pinmux_lock
, flags
);
179 void crisv32_pinmux_set(int port
)
185 for (i
= 0; i
< PORT_PINS
; i
++) {
186 if (pins
[port
][i
] == pinmux_gpio
)
187 gpio_val
|= (1 << i
);
188 else if (pins
[port
][i
] == pinmux_iop
)
192 REG_WRITE(int, regi_pinmux
+ REG_RD_ADDR_pinmux_rw_pb_gio
+ 8 * port
,
194 REG_WRITE(int, regi_pinmux
+ REG_RD_ADDR_pinmux_rw_pb_iop
+ 8 * port
,
198 crisv32_pinmux_dump();
202 static int __crisv32_pinmux_dealloc(int port
, int first_pin
, int last_pin
)
206 for (i
= first_pin
; i
<= last_pin
; i
++)
207 pins
[port
][i
] = pinmux_none
;
209 crisv32_pinmux_set(port
);
213 int crisv32_pinmux_dealloc(int port
, int first_pin
, int last_pin
)
217 crisv32_pinmux_init();
219 if (port
> PORTS
|| port
< 0)
222 spin_lock_irqsave(&pinmux_lock
, flags
);
223 __crisv32_pinmux_dealloc(port
, first_pin
, last_pin
);
224 spin_unlock_irqrestore(&pinmux_lock
, flags
);
229 int crisv32_pinmux_dealloc_fixed(enum fixed_function function
)
232 char saved
[sizeof pins
];
234 reg_pinmux_rw_hwprot hwprot
;
236 spin_lock_irqsave(&pinmux_lock
, flags
);
238 /* Save internal data for recovery */
239 memcpy(saved
, pins
, sizeof pins
);
241 crisv32_pinmux_init(); /* Must be done before we read rw_hwprot */
243 hwprot
= REG_RD(pinmux
, regi_pinmux
, rw_hwprot
);
247 ret
= __crisv32_pinmux_dealloc(PORT_C
, 4, 7);
248 hwprot
.ser1
= regk_pinmux_no
;
251 ret
= __crisv32_pinmux_dealloc(PORT_C
, 8, 11);
252 hwprot
.ser2
= regk_pinmux_no
;
255 ret
= __crisv32_pinmux_dealloc(PORT_C
, 12, 15);
256 hwprot
.ser3
= regk_pinmux_no
;
259 ret
= __crisv32_pinmux_dealloc(PORT_C
, 0, 3);
260 ret
|= __crisv32_pinmux_dealloc(PORT_C
, 16, 16);
261 hwprot
.sser0
= regk_pinmux_no
;
264 ret
= __crisv32_pinmux_dealloc(PORT_D
, 0, 4);
265 hwprot
.sser1
= regk_pinmux_no
;
268 ret
= __crisv32_pinmux_dealloc(PORT_D
, 5, 7);
269 ret
|= __crisv32_pinmux_dealloc(PORT_D
, 15, 17);
270 hwprot
.ata0
= regk_pinmux_no
;
273 ret
= __crisv32_pinmux_dealloc(PORT_D
, 0, 4);
274 ret
|= __crisv32_pinmux_dealloc(PORT_E
, 17, 17);
275 hwprot
.ata1
= regk_pinmux_no
;
278 ret
= __crisv32_pinmux_dealloc(PORT_C
, 11, 15);
279 ret
|= __crisv32_pinmux_dealloc(PORT_E
, 3, 3);
280 hwprot
.ata2
= regk_pinmux_no
;
283 ret
= __crisv32_pinmux_dealloc(PORT_C
, 8, 10);
284 ret
|= __crisv32_pinmux_dealloc(PORT_C
, 0, 2);
285 hwprot
.ata2
= regk_pinmux_no
;
288 ret
= __crisv32_pinmux_dealloc(PORT_B
, 0, 15);
289 ret
|= __crisv32_pinmux_dealloc(PORT_D
, 8, 15);
290 hwprot
.ata
= regk_pinmux_no
;
293 ret
= __crisv32_pinmux_dealloc(PORT_E
, 0, 17);
294 hwprot
.eth1
= regk_pinmux_no
;
295 hwprot
.eth1_mgm
= regk_pinmux_no
;
298 ret
= __crisv32_pinmux_dealloc(PORT_C
, 16, 16);
299 hwprot
.timer
= regk_pinmux_no
;
300 spin_unlock_irqrestore(&pinmux_lock
, flags
);
305 REG_WR(pinmux
, regi_pinmux
, rw_hwprot
, hwprot
);
307 memcpy(pins
, saved
, sizeof pins
);
309 spin_unlock_irqrestore(&pinmux_lock
, flags
);
315 static void crisv32_pinmux_dump(void)
319 crisv32_pinmux_init();
321 for (i
= 0; i
< PORTS
; i
++) {
322 printk(KERN_DEBUG
"Port %c\n", 'B' + i
);
323 for (j
= 0; j
< PORT_PINS
; j
++)
324 printk(KERN_DEBUG
" Pin %d = %d\n", j
, pins
[i
][j
]);
328 __initcall(crisv32_pinmux_init
);