• 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 	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;
105 		ret = crisv32_pinmux_alloc(PORT_B, 8, 23, pinmux_fixed);
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:
110 		ret = crisv32_pinmux_alloc(PORT_B, 0, 7, pinmux_fixed);
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;
126 		ret = crisv32_pinmux_alloc(PORT_A, 8, 18, pinmux_fixed);
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:
171 		ret = crisv32_pinmux_alloc(PORT_A, 0, 1, pinmux_fixed);
172 		hwprot.i2c0 = regk_pinmux_yes;
173 		break;
174 	case pinmux_i2c1:
175 		ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed);
176 		hwprot.i2c1 = regk_pinmux_yes;
177 		break;
178 	case pinmux_i2c1_3wire:
179 		ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed);
180 		ret |= crisv32_pinmux_alloc(PORT_A, 7, 7, pinmux_fixed);
181 		hwprot.i2c1 = hwprot.i2c1_sen = regk_pinmux_yes;
182 		break;
183 	case pinmux_i2c1_sda1:
184 		ret = crisv32_pinmux_alloc(PORT_A, 2, 4, pinmux_fixed);
185 		hwprot.i2c1 = hwprot.i2c1_sda1 = regk_pinmux_yes;
186 		break;
187 	case pinmux_i2c1_sda2:
188 		ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed);
189 		ret |= crisv32_pinmux_alloc(PORT_A, 5, 5, pinmux_fixed);
190 		hwprot.i2c1 = hwprot.i2c1_sda2 = regk_pinmux_yes;
191 		break;
192 	case pinmux_i2c1_sda3:
193 		ret = crisv32_pinmux_alloc(PORT_A, 2, 3, pinmux_fixed);
194 		ret |= crisv32_pinmux_alloc(PORT_A, 6, 6, pinmux_fixed);
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
crisv32_pinmux_set(int port)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 
228 	REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_gio_pa + 4 * port,
229 		gpio_val);
230 	REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_iop_pa + 4 * port,
231 		iop_val);
232 
233 #ifdef DEBUG
234        crisv32_pinmux_dump();
235 #endif
236 }
237 
238 int
crisv32_pinmux_dealloc(int port,int first_pin,int last_pin)239 crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
240 {
241 	int i;
242 	unsigned long flags;
243 
244 	crisv32_pinmux_init();
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
crisv32_pinmux_dealloc_fixed(enum fixed_function function)261 crisv32_pinmux_dealloc_fixed(enum fixed_function function)
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
crisv32_pinmux_dump(void)372 crisv32_pinmux_dump(void)
373 {
374 	int i, j;
375 	int pin = 0;
376 
377 	crisv32_pinmux_init();
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++)
383 			printk(KERN_DEBUG
384 				"  Pin %d = %d\n", j, pins[i * PORT_PINS + j]);
385 	}
386 }
387 
388 __initcall(crisv32_pinmux_init);
389