Merge tag 'iwlwifi-next-for-kalle-2014-12-30' of https://git.kernel.org/pub/scm/linux...
[cascardo/linux.git] / arch / cris / arch-v32 / mach-fs / pinmux.c
1 /*
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.
5  *
6  * Copyright (c) 2004-2007 Axis Communications AB.
7  */
8
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>
16 #include <pinmux.h>
17 #include <hwregs/pinmux_defs.h>
18
19 #undef DEBUG
20
21 #define PORT_PINS 18
22 #define PORTS 4
23
24 static char pins[PORTS][PORT_PINS];
25 static DEFINE_SPINLOCK(pinmux_lock);
26
27 static void crisv32_pinmux_set(int port);
28
29 static int __crisv32_pinmux_alloc(int port, int first_pin, int last_pin,
30                                  enum pin_mode mode)
31 {
32         int i;
33
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)) {
38 #ifdef DEBUG
39                         panic("Pinmux alloc failed!\n");
40 #endif
41                         return -EPERM;
42                 }
43         }
44
45         for (i = first_pin; i <= last_pin; i++)
46                 pins[port][i] = mode;
47
48         crisv32_pinmux_set(port);
49 }
50
51 static int crisv32_pinmux_init(void)
52 {
53         static int initialized;
54
55         if (!initialized) {
56                 reg_pinmux_rw_pa pa = REG_RD(pinmux, regi_pinmux, rw_pa);
57                 initialized = 1;
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);
66         }
67
68         return 0;
69 }
70
71 int crisv32_pinmux_alloc(int port, int first_pin, int last_pin,
72                          enum pin_mode mode)
73 {
74         unsigned long flags;
75         int ret;
76
77         crisv32_pinmux_init();
78
79         if (port > PORTS || port < 0)
80                 return -EINVAL;
81
82         spin_lock_irqsave(&pinmux_lock, flags);
83
84         ret = __crisv32_pinmux_alloc(port, first_pin, last_pin, mode);
85
86         spin_unlock_irqrestore(&pinmux_lock, flags);
87
88         return ret;
89 }
90
91 int crisv32_pinmux_alloc_fixed(enum fixed_function function)
92 {
93         int ret = -EINVAL;
94         char saved[sizeof pins];
95         unsigned long flags;
96
97         spin_lock_irqsave(&pinmux_lock, flags);
98
99         /* Save internal data for recovery */
100         memcpy(saved, pins, sizeof pins);
101
102         crisv32_pinmux_init();  /* Must be done before we read rw_hwprot */
103
104         reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
105
106         switch (function) {
107         case pinmux_ser1:
108                 ret = __crisv32_pinmux_alloc(PORT_C, 4, 7, pinmux_fixed);
109                 hwprot.ser1 = regk_pinmux_yes;
110                 break;
111         case pinmux_ser2:
112                 ret = __crisv32_pinmux_alloc(PORT_C, 8, 11, pinmux_fixed);
113                 hwprot.ser2 = regk_pinmux_yes;
114                 break;
115         case pinmux_ser3:
116                 ret = __crisv32_pinmux_alloc(PORT_C, 12, 15, pinmux_fixed);
117                 hwprot.ser3 = regk_pinmux_yes;
118                 break;
119         case pinmux_sser0:
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;
123                 break;
124         case pinmux_sser1:
125                 ret = __crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
126                 hwprot.sser1 = regk_pinmux_yes;
127                 break;
128         case pinmux_ata0:
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;
132                 break;
133         case pinmux_ata1:
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;
137                 break;
138         case pinmux_ata2:
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;
142                 break;
143         case pinmux_ata3:
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;
147                 break;
148         case pinmux_ata:
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;
152                 break;
153         case pinmux_eth1:
154                 ret = __crisv32_pinmux_alloc(PORT_E, 0, 17, pinmux_fixed);
155                 hwprot.eth1 = regk_pinmux_yes;
156                 hwprot.eth1_mgm = regk_pinmux_yes;
157                 break;
158         case pinmux_timer:
159                 ret = __crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
160                 hwprot.timer = regk_pinmux_yes;
161                 spin_unlock_irqrestore(&pinmux_lock, flags);
162                 return ret;
163         }
164
165         if (!ret)
166                 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
167         else
168                 memcpy(pins, saved, sizeof pins);
169
170         spin_unlock_irqrestore(&pinmux_lock, flags);
171
172         return ret;
173 }
174
175 void crisv32_pinmux_set(int port)
176 {
177         int i;
178         int gpio_val = 0;
179         int iop_val = 0;
180
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)
185                         iop_val |= (1 << i);
186         }
187
188         REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_pb_gio + 8 * port,
189                   gpio_val);
190         REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_pb_iop + 8 * port,
191                   iop_val);
192
193 #ifdef DEBUG
194         crisv32_pinmux_dump();
195 #endif
196 }
197
198 static int __crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
199 {
200         int i;
201
202         for (i = first_pin; i <= last_pin; i++)
203                 pins[port][i] = pinmux_none;
204
205         crisv32_pinmux_set(port);
206         return 0;
207 }
208
209 int crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
210 {
211         unsigned long flags;
212
213         crisv32_pinmux_init();
214
215         if (port > PORTS || port < 0)
216                 return -EINVAL;
217
218         spin_lock_irqsave(&pinmux_lock, flags);
219         __crisv32_pinmux_dealloc(port, first_pin, last_pin);
220         spin_unlock_irqrestore(&pinmux_lock, flags);
221
222         return 0;
223 }
224
225 int crisv32_pinmux_dealloc_fixed(enum fixed_function function)
226 {
227         int ret = -EINVAL;
228         char saved[sizeof pins];
229         unsigned long flags;
230
231         spin_lock_irqsave(&pinmux_lock, flags);
232
233         /* Save internal data for recovery */
234         memcpy(saved, pins, sizeof pins);
235
236         crisv32_pinmux_init();  /* Must be done before we read rw_hwprot */
237
238         reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
239
240         switch (function) {
241         case pinmux_ser1:
242                 ret = __crisv32_pinmux_dealloc(PORT_C, 4, 7);
243                 hwprot.ser1 = regk_pinmux_no;
244                 break;
245         case pinmux_ser2:
246                 ret = __crisv32_pinmux_dealloc(PORT_C, 8, 11);
247                 hwprot.ser2 = regk_pinmux_no;
248                 break;
249         case pinmux_ser3:
250                 ret = __crisv32_pinmux_dealloc(PORT_C, 12, 15);
251                 hwprot.ser3 = regk_pinmux_no;
252                 break;
253         case pinmux_sser0:
254                 ret = __crisv32_pinmux_dealloc(PORT_C, 0, 3);
255                 ret |= __crisv32_pinmux_dealloc(PORT_C, 16, 16);
256                 hwprot.sser0 = regk_pinmux_no;
257                 break;
258         case pinmux_sser1:
259                 ret = __crisv32_pinmux_dealloc(PORT_D, 0, 4);
260                 hwprot.sser1 = regk_pinmux_no;
261                 break;
262         case pinmux_ata0:
263                 ret = __crisv32_pinmux_dealloc(PORT_D, 5, 7);
264                 ret |= __crisv32_pinmux_dealloc(PORT_D, 15, 17);
265                 hwprot.ata0 = regk_pinmux_no;
266                 break;
267         case pinmux_ata1:
268                 ret = __crisv32_pinmux_dealloc(PORT_D, 0, 4);
269                 ret |= __crisv32_pinmux_dealloc(PORT_E, 17, 17);
270                 hwprot.ata1 = regk_pinmux_no;
271                 break;
272         case pinmux_ata2:
273                 ret = __crisv32_pinmux_dealloc(PORT_C, 11, 15);
274                 ret |= __crisv32_pinmux_dealloc(PORT_E, 3, 3);
275                 hwprot.ata2 = regk_pinmux_no;
276                 break;
277         case pinmux_ata3:
278                 ret = __crisv32_pinmux_dealloc(PORT_C, 8, 10);
279                 ret |= __crisv32_pinmux_dealloc(PORT_C, 0, 2);
280                 hwprot.ata2 = regk_pinmux_no;
281                 break;
282         case pinmux_ata:
283                 ret = __crisv32_pinmux_dealloc(PORT_B, 0, 15);
284                 ret |= __crisv32_pinmux_dealloc(PORT_D, 8, 15);
285                 hwprot.ata = regk_pinmux_no;
286                 break;
287         case pinmux_eth1:
288                 ret = __crisv32_pinmux_dealloc(PORT_E, 0, 17);
289                 hwprot.eth1 = regk_pinmux_no;
290                 hwprot.eth1_mgm = regk_pinmux_no;
291                 break;
292         case pinmux_timer:
293                 ret = __crisv32_pinmux_dealloc(PORT_C, 16, 16);
294                 hwprot.timer = regk_pinmux_no;
295                 spin_unlock_irqrestore(&pinmux_lock, flags);
296                 return ret;
297         }
298
299         if (!ret)
300                 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
301         else
302                 memcpy(pins, saved, sizeof pins);
303
304         spin_unlock_irqrestore(&pinmux_lock, flags);
305
306         return ret;
307 }
308
309 #ifdef DEBUG
310 static void crisv32_pinmux_dump(void)
311 {
312         int i, j;
313
314         crisv32_pinmux_init();
315
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]);
320         }
321 }
322 #endif
323 __initcall(crisv32_pinmux_init);