aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/mach-at32ap/pio.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.osdl.org>2006-12-11 21:28:59 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-11 21:28:59 -0500
commitcd39301a68f9604854f3543117b01dc73cbe193f (patch)
tree0be77134407d73aece97050151d80ed4b07b23bc /arch/avr32/mach-at32ap/pio.c
parent13d7d84e078f49f08b657a3fba0d7a0b7b44ba65 (diff)
parent3fc0eb47aa96b1d9230ff85b722c45c3b9e83d14 (diff)
Merge branch 'for-linus' of git://www.atmel.no/~hskinnemoen/linux/kernel/avr32
* 'for-linus' of git://www.atmel.no/~hskinnemoen/linux/kernel/avr32: [AVR32] Add missing #include <linux/param.h> to delay.c [AVR32] Pass dev parameter to dma_cache_sync() [AVR32] Implement intc_get_pending() [AVR32] Don't include <asm/delay.h> [AVR32] Put the chip in "stop" mode when halting the system [AVR32] Set flow handler for external interrupts [AVR32] Remove unused file [AVR32] Remove mii_phy_addr and eth_addr from eth_platform_data [AVR32] Move ethernet tag parsing to board-specific code [AVR32] Add macb1 platform_device [AVR32] Portmux API update
Diffstat (limited to 'arch/avr32/mach-at32ap/pio.c')
-rw-r--r--arch/avr32/mach-at32ap/pio.c85
1 files changed, 78 insertions, 7 deletions
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c
index d3aabfca8598..f1280ed8ed6d 100644
--- a/arch/avr32/mach-at32ap/pio.c
+++ b/arch/avr32/mach-at32ap/pio.c
@@ -25,27 +25,98 @@ struct pio_device {
25 void __iomem *regs; 25 void __iomem *regs;
26 const struct platform_device *pdev; 26 const struct platform_device *pdev;
27 struct clk *clk; 27 struct clk *clk;
28 u32 alloc_mask; 28 u32 pinmux_mask;
29 char name[32]; 29 char name[32];
30}; 30};
31 31
32static struct pio_device pio_dev[MAX_NR_PIO_DEVICES]; 32static struct pio_device pio_dev[MAX_NR_PIO_DEVICES];
33 33
34void portmux_set_func(unsigned int portmux_id, unsigned int pin_id, 34static struct pio_device *gpio_to_pio(unsigned int gpio)
35 unsigned int function_id)
36{ 35{
37 struct pio_device *pio; 36 struct pio_device *pio;
38 u32 mask = 1 << pin_id; 37 unsigned int index;
39 38
40 BUG_ON(portmux_id >= MAX_NR_PIO_DEVICES); 39 index = gpio >> 5;
40 if (index >= MAX_NR_PIO_DEVICES)
41 return NULL;
42 pio = &pio_dev[index];
43 if (!pio->regs)
44 return NULL;
41 45
42 pio = &pio_dev[portmux_id]; 46 return pio;
47}
48
49/* Pin multiplexing API */
50
51void __init at32_select_periph(unsigned int pin, unsigned int periph,
52 unsigned long flags)
53{
54 struct pio_device *pio;
55 unsigned int pin_index = pin & 0x1f;
56 u32 mask = 1 << pin_index;
57
58 pio = gpio_to_pio(pin);
59 if (unlikely(!pio)) {
60 printk("pio: invalid pin %u\n", pin);
61 goto fail;
62 }
43 63
44 if (function_id) 64 if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) {
65 printk("%s: pin %u is busy\n", pio->name, pin_index);
66 goto fail;
67 }
68
69 pio_writel(pio, PUER, mask);
70 if (periph)
45 pio_writel(pio, BSR, mask); 71 pio_writel(pio, BSR, mask);
46 else 72 else
47 pio_writel(pio, ASR, mask); 73 pio_writel(pio, ASR, mask);
74
48 pio_writel(pio, PDR, mask); 75 pio_writel(pio, PDR, mask);
76 if (!(flags & AT32_GPIOF_PULLUP))
77 pio_writel(pio, PUDR, mask);
78
79 return;
80
81fail:
82 dump_stack();
83}
84
85void __init at32_select_gpio(unsigned int pin, unsigned long flags)
86{
87 struct pio_device *pio;
88 unsigned int pin_index = pin & 0x1f;
89 u32 mask = 1 << pin_index;
90
91 pio = gpio_to_pio(pin);
92 if (unlikely(!pio)) {
93 printk("pio: invalid pin %u\n", pin);
94 goto fail;
95 }
96
97 if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) {
98 printk("%s: pin %u is busy\n", pio->name, pin_index);
99 goto fail;
100 }
101
102 pio_writel(pio, PUER, mask);
103 if (flags & AT32_GPIOF_HIGH)
104 pio_writel(pio, SODR, mask);
105 else
106 pio_writel(pio, CODR, mask);
107 if (flags & AT32_GPIOF_OUTPUT)
108 pio_writel(pio, OER, mask);
109 else
110 pio_writel(pio, ODR, mask);
111
112 pio_writel(pio, PER, mask);
113 if (!(flags & AT32_GPIOF_PULLUP))
114 pio_writel(pio, PUDR, mask);
115
116 return;
117
118fail:
119 dump_stack();
49} 120}
50 121
51static int __init pio_probe(struct platform_device *pdev) 122static int __init pio_probe(struct platform_device *pdev)