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 int crisv32_pinmux_init(void)
31 static int initialized
;
34 reg_pinmux_rw_pa pa
= REG_RD(pinmux
, regi_pinmux
, rw_pa
);
36 REG_WR_INT(pinmux
, regi_pinmux
, rw_hwprot
, 0);
37 pa
.pa0
= pa
.pa1
= pa
.pa2
= pa
.pa3
=
38 pa
.pa4
= pa
.pa5
= pa
.pa6
= pa
.pa7
= regk_pinmux_yes
;
39 REG_WR(pinmux
, regi_pinmux
, rw_pa
, pa
);
40 crisv32_pinmux_alloc(PORT_B
, 0, PORT_PINS
- 1, pinmux_gpio
);
41 crisv32_pinmux_alloc(PORT_C
, 0, PORT_PINS
- 1, pinmux_gpio
);
42 crisv32_pinmux_alloc(PORT_D
, 0, PORT_PINS
- 1, pinmux_gpio
);
43 crisv32_pinmux_alloc(PORT_E
, 0, PORT_PINS
- 1, pinmux_gpio
);
50 crisv32_pinmux_alloc(int port
, int first_pin
, int last_pin
, enum pin_mode mode
)
55 crisv32_pinmux_init();
57 if (port
> PORTS
|| port
< 0)
60 spin_lock_irqsave(&pinmux_lock
, flags
);
62 for (i
= first_pin
; i
<= last_pin
; i
++) {
63 if ((pins
[port
][i
] != pinmux_none
)
64 && (pins
[port
][i
] != pinmux_gpio
)
65 && (pins
[port
][i
] != mode
)) {
66 spin_unlock_irqrestore(&pinmux_lock
, flags
);
68 panic("Pinmux alloc failed!\n");
74 for (i
= first_pin
; i
<= last_pin
; i
++)
77 crisv32_pinmux_set(port
);
79 spin_unlock_irqrestore(&pinmux_lock
, flags
);
84 int crisv32_pinmux_alloc_fixed(enum fixed_function function
)
87 char saved
[sizeof pins
];
90 spin_lock_irqsave(&pinmux_lock
, flags
);
92 /* Save internal data for recovery */
93 memcpy(saved
, pins
, sizeof pins
);
95 crisv32_pinmux_init(); /* Must be done before we read rw_hwprot */
97 reg_pinmux_rw_hwprot hwprot
= REG_RD(pinmux
, regi_pinmux
, rw_hwprot
);
101 ret
= crisv32_pinmux_alloc(PORT_C
, 4, 7, pinmux_fixed
);
102 hwprot
.ser1
= regk_pinmux_yes
;
105 ret
= crisv32_pinmux_alloc(PORT_C
, 8, 11, pinmux_fixed
);
106 hwprot
.ser2
= regk_pinmux_yes
;
109 ret
= crisv32_pinmux_alloc(PORT_C
, 12, 15, pinmux_fixed
);
110 hwprot
.ser3
= regk_pinmux_yes
;
113 ret
= crisv32_pinmux_alloc(PORT_C
, 0, 3, pinmux_fixed
);
114 ret
|= crisv32_pinmux_alloc(PORT_C
, 16, 16, pinmux_fixed
);
115 hwprot
.sser0
= regk_pinmux_yes
;
118 ret
= crisv32_pinmux_alloc(PORT_D
, 0, 4, pinmux_fixed
);
119 hwprot
.sser1
= regk_pinmux_yes
;
122 ret
= crisv32_pinmux_alloc(PORT_D
, 5, 7, pinmux_fixed
);
123 ret
|= crisv32_pinmux_alloc(PORT_D
, 15, 17, pinmux_fixed
);
124 hwprot
.ata0
= regk_pinmux_yes
;
127 ret
= crisv32_pinmux_alloc(PORT_D
, 0, 4, pinmux_fixed
);
128 ret
|= crisv32_pinmux_alloc(PORT_E
, 17, 17, pinmux_fixed
);
129 hwprot
.ata1
= regk_pinmux_yes
;
132 ret
= crisv32_pinmux_alloc(PORT_C
, 11, 15, pinmux_fixed
);
133 ret
|= crisv32_pinmux_alloc(PORT_E
, 3, 3, pinmux_fixed
);
134 hwprot
.ata2
= regk_pinmux_yes
;
137 ret
= crisv32_pinmux_alloc(PORT_C
, 8, 10, pinmux_fixed
);
138 ret
|= crisv32_pinmux_alloc(PORT_C
, 0, 2, pinmux_fixed
);
139 hwprot
.ata2
= regk_pinmux_yes
;
142 ret
= crisv32_pinmux_alloc(PORT_B
, 0, 15, pinmux_fixed
);
143 ret
|= crisv32_pinmux_alloc(PORT_D
, 8, 15, pinmux_fixed
);
144 hwprot
.ata
= regk_pinmux_yes
;
147 ret
= crisv32_pinmux_alloc(PORT_E
, 0, 17, pinmux_fixed
);
148 hwprot
.eth1
= regk_pinmux_yes
;
149 hwprot
.eth1_mgm
= regk_pinmux_yes
;
152 ret
= crisv32_pinmux_alloc(PORT_C
, 16, 16, pinmux_fixed
);
153 hwprot
.timer
= regk_pinmux_yes
;
154 spin_unlock_irqrestore(&pinmux_lock
, flags
);
159 REG_WR(pinmux
, regi_pinmux
, rw_hwprot
, hwprot
);
161 memcpy(pins
, saved
, sizeof pins
);
163 spin_unlock_irqrestore(&pinmux_lock
, flags
);
168 void crisv32_pinmux_set(int port
)
174 for (i
= 0; i
< PORT_PINS
; i
++) {
175 if (pins
[port
][i
] == pinmux_gpio
)
176 gpio_val
|= (1 << i
);
177 else if (pins
[port
][i
] == pinmux_iop
)
181 REG_WRITE(int, regi_pinmux
+ REG_RD_ADDR_pinmux_rw_pb_gio
+ 8 * port
,
183 REG_WRITE(int, regi_pinmux
+ REG_RD_ADDR_pinmux_rw_pb_iop
+ 8 * port
,
187 crisv32_pinmux_dump();
191 int crisv32_pinmux_dealloc(int port
, int first_pin
, int last_pin
)
196 crisv32_pinmux_init();
198 if (port
> PORTS
|| port
< 0)
201 spin_lock_irqsave(&pinmux_lock
, flags
);
203 for (i
= first_pin
; i
<= last_pin
; i
++)
204 pins
[port
][i
] = pinmux_none
;
206 crisv32_pinmux_set(port
);
207 spin_unlock_irqrestore(&pinmux_lock
, flags
);
212 int crisv32_pinmux_dealloc_fixed(enum fixed_function function
)
215 char saved
[sizeof pins
];
218 spin_lock_irqsave(&pinmux_lock
, flags
);
220 /* Save internal data for recovery */
221 memcpy(saved
, pins
, sizeof pins
);
223 crisv32_pinmux_init(); /* Must be done before we read rw_hwprot */
225 reg_pinmux_rw_hwprot hwprot
= REG_RD(pinmux
, regi_pinmux
, rw_hwprot
);
229 ret
= crisv32_pinmux_dealloc(PORT_C
, 4, 7);
230 hwprot
.ser1
= regk_pinmux_no
;
233 ret
= crisv32_pinmux_dealloc(PORT_C
, 8, 11);
234 hwprot
.ser2
= regk_pinmux_no
;
237 ret
= crisv32_pinmux_dealloc(PORT_C
, 12, 15);
238 hwprot
.ser3
= regk_pinmux_no
;
241 ret
= crisv32_pinmux_dealloc(PORT_C
, 0, 3);
242 ret
|= crisv32_pinmux_dealloc(PORT_C
, 16, 16);
243 hwprot
.sser0
= regk_pinmux_no
;
246 ret
= crisv32_pinmux_dealloc(PORT_D
, 0, 4);
247 hwprot
.sser1
= regk_pinmux_no
;
250 ret
= crisv32_pinmux_dealloc(PORT_D
, 5, 7);
251 ret
|= crisv32_pinmux_dealloc(PORT_D
, 15, 17);
252 hwprot
.ata0
= regk_pinmux_no
;
255 ret
= crisv32_pinmux_dealloc(PORT_D
, 0, 4);
256 ret
|= crisv32_pinmux_dealloc(PORT_E
, 17, 17);
257 hwprot
.ata1
= regk_pinmux_no
;
260 ret
= crisv32_pinmux_dealloc(PORT_C
, 11, 15);
261 ret
|= crisv32_pinmux_dealloc(PORT_E
, 3, 3);
262 hwprot
.ata2
= regk_pinmux_no
;
265 ret
= crisv32_pinmux_dealloc(PORT_C
, 8, 10);
266 ret
|= crisv32_pinmux_dealloc(PORT_C
, 0, 2);
267 hwprot
.ata2
= regk_pinmux_no
;
270 ret
= crisv32_pinmux_dealloc(PORT_B
, 0, 15);
271 ret
|= crisv32_pinmux_dealloc(PORT_D
, 8, 15);
272 hwprot
.ata
= regk_pinmux_no
;
275 ret
= crisv32_pinmux_dealloc(PORT_E
, 0, 17);
276 hwprot
.eth1
= regk_pinmux_no
;
277 hwprot
.eth1_mgm
= regk_pinmux_no
;
280 ret
= crisv32_pinmux_dealloc(PORT_C
, 16, 16);
281 hwprot
.timer
= regk_pinmux_no
;
282 spin_unlock_irqrestore(&pinmux_lock
, flags
);
287 REG_WR(pinmux
, regi_pinmux
, rw_hwprot
, hwprot
);
289 memcpy(pins
, saved
, sizeof pins
);
291 spin_unlock_irqrestore(&pinmux_lock
, flags
);
296 void crisv32_pinmux_dump(void)
300 crisv32_pinmux_init();
302 for (i
= 0; i
< PORTS
; i
++) {
303 printk(KERN_DEBUG
"Port %c\n", 'B' + i
);
304 for (j
= 0; j
< PORT_PINS
; j
++)
305 printk(KERN_DEBUG
" Pin %d = %d\n", j
, pins
[i
][j
]);
309 __initcall(crisv32_pinmux_init
);