Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pinmux.c
Go to the documentation of this file.
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) 2005-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 #include <hwregs/clkgen_defs.h>
19 
20 #undef DEBUG
21 
22 #define PINS 80
23 #define PORT_PINS 32
24 #define PORTS 3
25 
26 static char pins[PINS];
27 static DEFINE_SPINLOCK(pinmux_lock);
28 
29 static void crisv32_pinmux_set(int port);
30 
31 int
33 {
34  static int initialized;
35 
36  if (!initialized) {
37  initialized = 1;
38  REG_WR_INT(pinmux, regi_pinmux, rw_hwprot, 0);
42  }
43 
44  return 0;
45 }
46 
47 int
48 crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode)
49 {
50  int i;
51  unsigned long flags;
52 
54 
55  if (port >= PORTS)
56  return -EINVAL;
57 
58  spin_lock_irqsave(&pinmux_lock, flags);
59 
60  for (i = first_pin; i <= last_pin; i++) {
61  if ((pins[port * PORT_PINS + i] != pinmux_none) &&
62  (pins[port * PORT_PINS + i] != pinmux_gpio) &&
63  (pins[port * PORT_PINS + i] != mode)) {
64  spin_unlock_irqrestore(&pinmux_lock, flags);
65 #ifdef DEBUG
66  panic("Pinmux alloc failed!\n");
67 #endif
68  return -EPERM;
69  }
70  }
71 
72  for (i = first_pin; i <= last_pin; i++)
73  pins[port * PORT_PINS + i] = mode;
74 
75  crisv32_pinmux_set(port);
76 
77  spin_unlock_irqrestore(&pinmux_lock, flags);
78 
79  return 0;
80 }
81 
82 int
84 {
85  int ret = -EINVAL;
86  char saved[sizeof pins];
87  unsigned long flags;
88  reg_pinmux_rw_hwprot hwprot;
89  reg_clkgen_rw_clk_ctrl clk_ctrl;
90 
91  spin_lock_irqsave(&pinmux_lock, flags);
92 
93  /* Save internal data for recovery */
94  memcpy(saved, pins, sizeof pins);
95 
96  crisv32_pinmux_init(); /* must be done before we read rw_hwprot */
97 
98  hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
99  clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);
100 
101  switch (function) {
102  case pinmux_eth:
103  clk_ctrl.eth = regk_clkgen_yes;
104  clk_ctrl.dma0_1_eth = regk_clkgen_yes;
106  ret |= crisv32_pinmux_alloc(PORT_B, 24, 25, pinmux_fixed);
107  hwprot.eth = hwprot.eth_mdio = regk_pinmux_yes;
108  break;
109  case pinmux_geth:
111  hwprot.geth = regk_pinmux_yes;
112  break;
113  case pinmux_tg_cmos:
114  clk_ctrl.ccd_tg_100 = clk_ctrl.ccd_tg_200 = regk_clkgen_yes;
115  ret = crisv32_pinmux_alloc(PORT_B, 27, 29, pinmux_fixed);
116  hwprot.tg_clk = regk_pinmux_yes;
117  break;
118  case pinmux_tg_ccd:
119  clk_ctrl.ccd_tg_100 = clk_ctrl.ccd_tg_200 = regk_clkgen_yes;
120  ret = crisv32_pinmux_alloc(PORT_B, 27, 31, pinmux_fixed);
121  ret |= crisv32_pinmux_alloc(PORT_C, 0, 15, pinmux_fixed);
122  hwprot.tg = hwprot.tg_clk = regk_pinmux_yes;
123  break;
124  case pinmux_vout:
125  clk_ctrl.strdma0_2_video = regk_clkgen_yes;
127  hwprot.vout = hwprot.vout_sync = regk_pinmux_yes;
128  break;
129  case pinmux_ser1:
130  clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
131  ret = crisv32_pinmux_alloc(PORT_A, 24, 25, pinmux_fixed);
132  hwprot.ser1 = regk_pinmux_yes;
133  break;
134  case pinmux_ser2:
135  clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
136  ret = crisv32_pinmux_alloc(PORT_A, 26, 27, pinmux_fixed);
137  hwprot.ser2 = regk_pinmux_yes;
138  break;
139  case pinmux_ser3:
140  clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
141  ret = crisv32_pinmux_alloc(PORT_A, 28, 29, pinmux_fixed);
142  hwprot.ser3 = regk_pinmux_yes;
143  break;
144  case pinmux_ser4:
145  clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
146  ret = crisv32_pinmux_alloc(PORT_A, 30, 31, pinmux_fixed);
147  hwprot.ser4 = regk_pinmux_yes;
148  break;
149  case pinmux_sser:
150  clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
151  ret = crisv32_pinmux_alloc(PORT_A, 19, 23, pinmux_fixed);
152  hwprot.sser = regk_pinmux_yes;
153  break;
154  case pinmux_pio:
155  hwprot.pio = regk_pinmux_yes;
156  ret = 0;
157  break;
158  case pinmux_pwm0:
159  ret = crisv32_pinmux_alloc(PORT_A, 30, 30, pinmux_fixed);
160  hwprot.pwm0 = regk_pinmux_yes;
161  break;
162  case pinmux_pwm1:
163  ret = crisv32_pinmux_alloc(PORT_A, 31, 31, pinmux_fixed);
164  hwprot.pwm1 = regk_pinmux_yes;
165  break;
166  case pinmux_pwm2:
167  ret = crisv32_pinmux_alloc(PORT_B, 26, 26, pinmux_fixed);
168  hwprot.pwm2 = regk_pinmux_yes;
169  break;
170  case pinmux_i2c0:
172  hwprot.i2c0 = regk_pinmux_yes;
173  break;
174  case pinmux_i2c1:
176  hwprot.i2c1 = regk_pinmux_yes;
177  break;
178  case pinmux_i2c1_3wire:
181  hwprot.i2c1 = hwprot.i2c1_sen = regk_pinmux_yes;
182  break;
183  case pinmux_i2c1_sda1:
185  hwprot.i2c1 = hwprot.i2c1_sda1 = regk_pinmux_yes;
186  break;
187  case pinmux_i2c1_sda2:
190  hwprot.i2c1 = hwprot.i2c1_sda2 = regk_pinmux_yes;
191  break;
192  case pinmux_i2c1_sda3:
195  hwprot.i2c1 = hwprot.i2c1_sda3 = regk_pinmux_yes;
196  break;
197  default:
198  ret = -EINVAL;
199  break;
200  }
201 
202  if (!ret) {
203  REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
204  REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl);
205  } else
206  memcpy(pins, saved, sizeof pins);
207 
208  spin_unlock_irqrestore(&pinmux_lock, flags);
209 
210  return ret;
211 }
212 
213 void
214 crisv32_pinmux_set(int port)
215 {
216  int i;
217  int gpio_val = 0;
218  int iop_val = 0;
219  int pin = port * PORT_PINS;
220 
221  for (i = 0; (i < PORT_PINS) && (pin < PINS); i++, pin++) {
222  if (pins[pin] == pinmux_gpio)
223  gpio_val |= (1 << i);
224  else if (pins[pin] == pinmux_iop)
225  iop_val |= (1 << i);
226  }
227 
229  gpio_val);
231  iop_val);
232 
233 #ifdef DEBUG
235 #endif
236 }
237 
238 int
239 crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
240 {
241  int i;
242  unsigned long flags;
243 
245 
246  if (port > PORTS || port < 0)
247  return -EINVAL;
248 
249  spin_lock_irqsave(&pinmux_lock, flags);
250 
251  for (i = first_pin; i <= last_pin; i++)
252  pins[port * PORT_PINS + i] = pinmux_none;
253 
254  crisv32_pinmux_set(port);
255  spin_unlock_irqrestore(&pinmux_lock, flags);
256 
257  return 0;
258 }
259 
260 int
262 {
263  int ret = -EINVAL;
264  char saved[sizeof pins];
265  unsigned long flags;
266  reg_pinmux_rw_hwprot hwprot;
267 
268  spin_lock_irqsave(&pinmux_lock, flags);
269 
270  /* Save internal data for recovery */
271  memcpy(saved, pins, sizeof pins);
272 
273  crisv32_pinmux_init(); /* must be done before we read rw_hwprot */
274 
275  hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
276 
277  switch (function) {
278  case pinmux_eth:
279  ret = crisv32_pinmux_dealloc(PORT_B, 8, 23);
280  ret |= crisv32_pinmux_dealloc(PORT_B, 24, 25);
281  ret |= crisv32_pinmux_dealloc(PORT_B, 0, 7);
282  hwprot.eth = hwprot.eth_mdio = hwprot.geth = regk_pinmux_no;
283  break;
284  case pinmux_tg_cmos:
285  ret = crisv32_pinmux_dealloc(PORT_B, 27, 29);
286  hwprot.tg_clk = regk_pinmux_no;
287  break;
288  case pinmux_tg_ccd:
289  ret = crisv32_pinmux_dealloc(PORT_B, 27, 31);
290  ret |= crisv32_pinmux_dealloc(PORT_C, 0, 15);
291  hwprot.tg = hwprot.tg_clk = regk_pinmux_no;
292  break;
293  case pinmux_vout:
294  ret = crisv32_pinmux_dealloc(PORT_A, 8, 18);
295  hwprot.vout = hwprot.vout_sync = regk_pinmux_no;
296  break;
297  case pinmux_ser1:
298  ret = crisv32_pinmux_dealloc(PORT_A, 24, 25);
299  hwprot.ser1 = regk_pinmux_no;
300  break;
301  case pinmux_ser2:
302  ret = crisv32_pinmux_dealloc(PORT_A, 26, 27);
303  hwprot.ser2 = regk_pinmux_no;
304  break;
305  case pinmux_ser3:
306  ret = crisv32_pinmux_dealloc(PORT_A, 28, 29);
307  hwprot.ser3 = regk_pinmux_no;
308  break;
309  case pinmux_ser4:
310  ret = crisv32_pinmux_dealloc(PORT_A, 30, 31);
311  hwprot.ser4 = regk_pinmux_no;
312  break;
313  case pinmux_sser:
314  ret = crisv32_pinmux_dealloc(PORT_A, 19, 23);
315  hwprot.sser = regk_pinmux_no;
316  break;
317  case pinmux_pwm0:
318  ret = crisv32_pinmux_dealloc(PORT_A, 30, 30);
319  hwprot.pwm0 = regk_pinmux_no;
320  break;
321  case pinmux_pwm1:
322  ret = crisv32_pinmux_dealloc(PORT_A, 31, 31);
323  hwprot.pwm1 = regk_pinmux_no;
324  break;
325  case pinmux_pwm2:
326  ret = crisv32_pinmux_dealloc(PORT_B, 26, 26);
327  hwprot.pwm2 = regk_pinmux_no;
328  break;
329  case pinmux_i2c0:
330  ret = crisv32_pinmux_dealloc(PORT_A, 0, 1);
331  hwprot.i2c0 = regk_pinmux_no;
332  break;
333  case pinmux_i2c1:
334  ret = crisv32_pinmux_dealloc(PORT_A, 2, 3);
335  hwprot.i2c1 = regk_pinmux_no;
336  break;
337  case pinmux_i2c1_3wire:
338  ret = crisv32_pinmux_dealloc(PORT_A, 2, 3);
339  ret |= crisv32_pinmux_dealloc(PORT_A, 7, 7);
340  hwprot.i2c1 = hwprot.i2c1_sen = regk_pinmux_no;
341  break;
342  case pinmux_i2c1_sda1:
343  ret = crisv32_pinmux_dealloc(PORT_A, 2, 4);
344  hwprot.i2c1_sda1 = regk_pinmux_no;
345  break;
346  case pinmux_i2c1_sda2:
347  ret = crisv32_pinmux_dealloc(PORT_A, 2, 3);
348  ret |= crisv32_pinmux_dealloc(PORT_A, 5, 5);
349  hwprot.i2c1_sda2 = regk_pinmux_no;
350  break;
351  case pinmux_i2c1_sda3:
352  ret = crisv32_pinmux_dealloc(PORT_A, 2, 3);
353  ret |= crisv32_pinmux_dealloc(PORT_A, 6, 6);
354  hwprot.i2c1_sda3 = regk_pinmux_no;
355  break;
356  default:
357  ret = -EINVAL;
358  break;
359  }
360 
361  if (!ret)
362  REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
363  else
364  memcpy(pins, saved, sizeof pins);
365 
366  spin_unlock_irqrestore(&pinmux_lock, flags);
367 
368  return ret;
369 }
370 
371 void
373 {
374  int i, j;
375  int pin = 0;
376 
378 
379  for (i = 0; i < PORTS; i++) {
380  pin++;
381  printk(KERN_DEBUG "Port %c\n", 'A'+i);
382  for (j = 0; (j < PORT_PINS) && (pin < PINS); j++, pin++)
384  " Pin %d = %d\n", j, pins[i * PORT_PINS + j]);
385  }
386 }
387