2 * Allocator for I/O pins. All pins are allocated to GPIO at bootup.
3 * Unassigned pins and GPIO pins can be allocated to a fixed interface
4 * or the I/O processor instead.
6 * Copyright (c) 2004-2007 Axis Communications AB.
9 #include <linux/init.h>
10 #include <linux/errno.h>
11 #include <linux/kernel.h>
12 #include <linux/string.h>
13 #include <linux/spinlock.h>
14 #include <hwregs/reg_map.h>
15 #include <hwregs/reg_rdwr.h>
17 #include <hwregs/pinmux_defs.h>
24 static char pins
[PORTS
][PORT_PINS
];
25 static DEFINE_SPINLOCK(pinmux_lock
);
27 static void crisv32_pinmux_set(int port
);
29 static int __crisv32_pinmux_alloc(int port
, int first_pin
, int last_pin
,
34 for (i
= first_pin
; i
<= last_pin
; i
++) {
35 if ((pins
[port
][i
] != pinmux_none
)
36 && (pins
[port
][i
] != pinmux_gpio
)
37 && (pins
[port
][i
] != mode
)) {
39 panic("Pinmux alloc failed!\n");
45 for (i
= first_pin
; i
<= last_pin
; i
++)
48 crisv32_pinmux_set(port
);
51 static int crisv32_pinmux_init(void)
53 static int initialized
;
56 reg_pinmux_rw_pa pa
= REG_RD(pinmux
, regi_pinmux
, rw_pa
);
58 REG_WR_INT(pinmux
, regi_pinmux
, rw_hwprot
, 0);
59 pa
.pa0
= pa
.pa1
= pa
.pa2
= pa
.pa3
=
60 pa
.pa4
= pa
.pa5
= pa
.pa6
= pa
.pa7
= regk_pinmux_yes
;
61 REG_WR(pinmux
, regi_pinmux
, rw_pa
, pa
);
62 __crisv32_pinmux_alloc(PORT_B
, 0, PORT_PINS
- 1, pinmux_gpio
);
63 __crisv32_pinmux_alloc(PORT_C
, 0, PORT_PINS
- 1, pinmux_gpio
);
64 __crisv32_pinmux_alloc(PORT_D
, 0, PORT_PINS
- 1, pinmux_gpio
);
65 __crisv32_pinmux_alloc(PORT_E
, 0, PORT_PINS
- 1, pinmux_gpio
);
71 int crisv32_pinmux_alloc(int port
, int first_pin
, int last_pin
,
77 crisv32_pinmux_init();
79 if (port
> PORTS
|| port
< 0)
82 spin_lock_irqsave(&pinmux_lock
, flags
);
84 ret
= __crisv32_pinmux_alloc(port
, first_pin
, last_pin
, mode
);
86 spin_unlock_irqrestore(&pinmux_lock
, flags
);
91 int crisv32_pinmux_alloc_fixed(enum fixed_function function
)
94 char saved
[sizeof pins
];
97 spin_lock_irqsave(&pinmux_lock
, flags
);
99 /* Save internal data for recovery */
100 memcpy(saved
, pins
, sizeof pins
);
102 crisv32_pinmux_init(); /* Must be done before we read rw_hwprot */
104 reg_pinmux_rw_hwprot hwprot
= REG_RD(pinmux
, regi_pinmux
, rw_hwprot
);
108 ret
= __crisv32_pinmux_alloc(PORT_C
, 4, 7, pinmux_fixed
);
109 hwprot
.ser1
= regk_pinmux_yes
;
112 ret
= __crisv32_pinmux_alloc(PORT_C
, 8, 11, pinmux_fixed
);
113 hwprot
.ser2
= regk_pinmux_yes
;
116 ret
= __crisv32_pinmux_alloc(PORT_C
, 12, 15, pinmux_fixed
);
117 hwprot
.ser3
= regk_pinmux_yes
;
120 ret
= __crisv32_pinmux_alloc(PORT_C
, 0, 3, pinmux_fixed
);
121 ret
|= __crisv32_pinmux_alloc(PORT_C
, 16, 16, pinmux_fixed
);
122 hwprot
.sser0
= regk_pinmux_yes
;
125 ret
= __crisv32_pinmux_alloc(PORT_D
, 0, 4, pinmux_fixed
);
126 hwprot
.sser1
= regk_pinmux_yes
;
129 ret
= __crisv32_pinmux_alloc(PORT_D
, 5, 7, pinmux_fixed
);
130 ret
|= __crisv32_pinmux_alloc(PORT_D
, 15, 17, pinmux_fixed
);
131 hwprot
.ata0
= regk_pinmux_yes
;
134 ret
= __crisv32_pinmux_alloc(PORT_D
, 0, 4, pinmux_fixed
);
135 ret
|= __crisv32_pinmux_alloc(PORT_E
, 17, 17, pinmux_fixed
);
136 hwprot
.ata1
= regk_pinmux_yes
;
139 ret
= __crisv32_pinmux_alloc(PORT_C
, 11, 15, pinmux_fixed
);
140 ret
|= __crisv32_pinmux_alloc(PORT_E
, 3, 3, pinmux_fixed
);
141 hwprot
.ata2
= regk_pinmux_yes
;
144 ret
= __crisv32_pinmux_alloc(PORT_C
, 8, 10, pinmux_fixed
);
145 ret
|= __crisv32_pinmux_alloc(PORT_C
, 0, 2, pinmux_fixed
);
146 hwprot
.ata2
= regk_pinmux_yes
;
149 ret
= __crisv32_pinmux_alloc(PORT_B
, 0, 15, pinmux_fixed
);
150 ret
|= __crisv32_pinmux_alloc(PORT_D
, 8, 15, pinmux_fixed
);
151 hwprot
.ata
= regk_pinmux_yes
;
154 ret
= __crisv32_pinmux_alloc(PORT_E
, 0, 17, pinmux_fixed
);
155 hwprot
.eth1
= regk_pinmux_yes
;
156 hwprot
.eth1_mgm
= regk_pinmux_yes
;
159 ret
= __crisv32_pinmux_alloc(PORT_C
, 16, 16, pinmux_fixed
);
160 hwprot
.timer
= regk_pinmux_yes
;
161 spin_unlock_irqrestore(&pinmux_lock
, flags
);
166 REG_WR(pinmux
, regi_pinmux
, rw_hwprot
, hwprot
);
168 memcpy(pins
, saved
, sizeof pins
);
170 spin_unlock_irqrestore(&pinmux_lock
, flags
);
175 void crisv32_pinmux_set(int port
)
181 for (i
= 0; i
< PORT_PINS
; i
++) {
182 if (pins
[port
][i
] == pinmux_gpio
)
183 gpio_val
|= (1 << i
);
184 else if (pins
[port
][i
] == pinmux_iop
)
188 REG_WRITE(int, regi_pinmux
+ REG_RD_ADDR_pinmux_rw_pb_gio
+ 8 * port
,
190 REG_WRITE(int, regi_pinmux
+ REG_RD_ADDR_pinmux_rw_pb_iop
+ 8 * port
,
194 crisv32_pinmux_dump();
198 static int __crisv32_pinmux_dealloc(int port
, int first_pin
, int last_pin
)
202 for (i
= first_pin
; i
<= last_pin
; i
++)
203 pins
[port
][i
] = pinmux_none
;
205 crisv32_pinmux_set(port
);
209 int crisv32_pinmux_dealloc(int port
, int first_pin
, int last_pin
)
213 crisv32_pinmux_init();
215 if (port
> PORTS
|| port
< 0)
218 spin_lock_irqsave(&pinmux_lock
, flags
);
219 __crisv32_pinmux_dealloc(port
, first_pin
, last_pin
);
220 spin_unlock_irqrestore(&pinmux_lock
, flags
);
225 int crisv32_pinmux_dealloc_fixed(enum fixed_function function
)
228 char saved
[sizeof pins
];
231 spin_lock_irqsave(&pinmux_lock
, flags
);
233 /* Save internal data for recovery */
234 memcpy(saved
, pins
, sizeof pins
);
236 crisv32_pinmux_init(); /* Must be done before we read rw_hwprot */
238 reg_pinmux_rw_hwprot hwprot
= REG_RD(pinmux
, regi_pinmux
, rw_hwprot
);
242 ret
= __crisv32_pinmux_dealloc(PORT_C
, 4, 7);
243 hwprot
.ser1
= regk_pinmux_no
;
246 ret
= __crisv32_pinmux_dealloc(PORT_C
, 8, 11);
247 hwprot
.ser2
= regk_pinmux_no
;
250 ret
= __crisv32_pinmux_dealloc(PORT_C
, 12, 15);
251 hwprot
.ser3
= regk_pinmux_no
;
254 ret
= __crisv32_pinmux_dealloc(PORT_C
, 0, 3);
255 ret
|= __crisv32_pinmux_dealloc(PORT_C
, 16, 16);
256 hwprot
.sser0
= regk_pinmux_no
;
259 ret
= __crisv32_pinmux_dealloc(PORT_D
, 0, 4);
260 hwprot
.sser1
= regk_pinmux_no
;
263 ret
= __crisv32_pinmux_dealloc(PORT_D
, 5, 7);
264 ret
|= __crisv32_pinmux_dealloc(PORT_D
, 15, 17);
265 hwprot
.ata0
= regk_pinmux_no
;
268 ret
= __crisv32_pinmux_dealloc(PORT_D
, 0, 4);
269 ret
|= __crisv32_pinmux_dealloc(PORT_E
, 17, 17);
270 hwprot
.ata1
= regk_pinmux_no
;
273 ret
= __crisv32_pinmux_dealloc(PORT_C
, 11, 15);
274 ret
|= __crisv32_pinmux_dealloc(PORT_E
, 3, 3);
275 hwprot
.ata2
= regk_pinmux_no
;
278 ret
= __crisv32_pinmux_dealloc(PORT_C
, 8, 10);
279 ret
|= __crisv32_pinmux_dealloc(PORT_C
, 0, 2);
280 hwprot
.ata2
= regk_pinmux_no
;
283 ret
= __crisv32_pinmux_dealloc(PORT_B
, 0, 15);
284 ret
|= __crisv32_pinmux_dealloc(PORT_D
, 8, 15);
285 hwprot
.ata
= regk_pinmux_no
;
288 ret
= __crisv32_pinmux_dealloc(PORT_E
, 0, 17);
289 hwprot
.eth1
= regk_pinmux_no
;
290 hwprot
.eth1_mgm
= regk_pinmux_no
;
293 ret
= __crisv32_pinmux_dealloc(PORT_C
, 16, 16);
294 hwprot
.timer
= regk_pinmux_no
;
295 spin_unlock_irqrestore(&pinmux_lock
, flags
);
300 REG_WR(pinmux
, regi_pinmux
, rw_hwprot
, hwprot
);
302 memcpy(pins
, saved
, sizeof pins
);
304 spin_unlock_irqrestore(&pinmux_lock
, flags
);
310 static void crisv32_pinmux_dump(void)
314 crisv32_pinmux_init();
316 for (i
= 0; i
< PORTS
; i
++) {
317 printk(KERN_DEBUG
"Port %c\n", 'B' + i
);
318 for (j
= 0; j
< PORT_PINS
; j
++)
319 printk(KERN_DEBUG
" Pin %d = %d\n", j
, pins
[i
][j
]);
323 __initcall(crisv32_pinmux_init
);