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