• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/cris/arch-v32/mach-a3/
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
26static char pins[PINS];
27static DEFINE_SPINLOCK(pinmux_lock);
28
29static void crisv32_pinmux_set(int port);
30
31int
32crisv32_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
47int
48crisv32_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
82int
83crisv32_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
212void
213crisv32_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
237int
238crisv32_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 || port < 0)
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
259int
260crisv32_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
369void
370crisv32_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