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	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
213void
214crisv32_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
238int
239crisv32_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
260int
261crisv32_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
371void
372crisv32_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