diff options
author | Haavard Skinnemoen <hskinnemoen@atmel.com> | 2006-12-04 07:46:52 -0500 |
---|---|---|
committer | Haavard Skinnemoen <hskinnemoen@atmel.com> | 2006-12-08 07:06:17 -0500 |
commit | c3e2a79c0bd3e12b67ce5f11cab10951ae8b7f37 (patch) | |
tree | 5d7290aaa6c92c781e3c2dafab44b946d9419af0 /arch/avr32 | |
parent | 68380b581383c028830f79ec2670f4a193854aa6 (diff) |
[AVR32] Portmux API update
Rename portmux_set_func to at32_select_periph, add at32_select_gpio
and add flags parameter to specify the initial state of the pins.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Diffstat (limited to 'arch/avr32')
-rw-r--r-- | arch/avr32/mach-at32ap/at32ap7000.c | 144 | ||||
-rw-r--r-- | arch/avr32/mach-at32ap/pio.c | 85 |
2 files changed, 146 insertions, 83 deletions
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c index 7ff6ad8bab5f..ada7930d5a4d 100644 --- a/arch/avr32/mach-at32ap/at32ap7000.c +++ b/arch/avr32/mach-at32ap/at32ap7000.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <asm/io.h> | 12 | #include <asm/io.h> |
13 | 13 | ||
14 | #include <asm/arch/at32ap7000.h> | ||
14 | #include <asm/arch/board.h> | 15 | #include <asm/arch/board.h> |
15 | #include <asm/arch/portmux.h> | 16 | #include <asm/arch/portmux.h> |
16 | #include <asm/arch/sm.h> | 17 | #include <asm/arch/sm.h> |
@@ -57,6 +58,9 @@ static struct platform_device _name##_id##_device = { \ | |||
57 | .num_resources = ARRAY_SIZE(_name##_id##_resource), \ | 58 | .num_resources = ARRAY_SIZE(_name##_id##_resource), \ |
58 | } | 59 | } |
59 | 60 | ||
61 | #define select_peripheral(pin, periph, flags) \ | ||
62 | at32_select_periph(GPIO_PIN_##pin, GPIO_##periph, flags) | ||
63 | |||
60 | #define DEV_CLK(_name, devname, bus, _index) \ | 64 | #define DEV_CLK(_name, devname, bus, _index) \ |
61 | static struct clk devname##_##_name = { \ | 65 | static struct clk devname##_##_name = { \ |
62 | .name = #_name, \ | 66 | .name = #_name, \ |
@@ -67,18 +71,6 @@ static struct clk devname##_##_name = { \ | |||
67 | .index = _index, \ | 71 | .index = _index, \ |
68 | } | 72 | } |
69 | 73 | ||
70 | enum { | ||
71 | PIOA, | ||
72 | PIOB, | ||
73 | PIOC, | ||
74 | PIOD, | ||
75 | }; | ||
76 | |||
77 | enum { | ||
78 | FUNC_A, | ||
79 | FUNC_B, | ||
80 | }; | ||
81 | |||
82 | unsigned long at32ap7000_osc_rates[3] = { | 74 | unsigned long at32ap7000_osc_rates[3] = { |
83 | [0] = 32768, | 75 | [0] = 32768, |
84 | /* FIXME: these are ATSTK1002-specific */ | 76 | /* FIXME: these are ATSTK1002-specific */ |
@@ -569,26 +561,26 @@ DEV_CLK(usart, atmel_usart3, pba, 6); | |||
569 | 561 | ||
570 | static inline void configure_usart0_pins(void) | 562 | static inline void configure_usart0_pins(void) |
571 | { | 563 | { |
572 | portmux_set_func(PIOA, 8, FUNC_B); /* RXD */ | 564 | select_peripheral(PA(8), PERIPH_B, 0); /* RXD */ |
573 | portmux_set_func(PIOA, 9, FUNC_B); /* TXD */ | 565 | select_peripheral(PA(9), PERIPH_B, 0); /* TXD */ |
574 | } | 566 | } |
575 | 567 | ||
576 | static inline void configure_usart1_pins(void) | 568 | static inline void configure_usart1_pins(void) |
577 | { | 569 | { |
578 | portmux_set_func(PIOA, 17, FUNC_A); /* RXD */ | 570 | select_peripheral(PA(17), PERIPH_A, 0); /* RXD */ |
579 | portmux_set_func(PIOA, 18, FUNC_A); /* TXD */ | 571 | select_peripheral(PA(18), PERIPH_A, 0); /* TXD */ |
580 | } | 572 | } |
581 | 573 | ||
582 | static inline void configure_usart2_pins(void) | 574 | static inline void configure_usart2_pins(void) |
583 | { | 575 | { |
584 | portmux_set_func(PIOB, 26, FUNC_B); /* RXD */ | 576 | select_peripheral(PB(26), PERIPH_B, 0); /* RXD */ |
585 | portmux_set_func(PIOB, 27, FUNC_B); /* TXD */ | 577 | select_peripheral(PB(27), PERIPH_B, 0); /* TXD */ |
586 | } | 578 | } |
587 | 579 | ||
588 | static inline void configure_usart3_pins(void) | 580 | static inline void configure_usart3_pins(void) |
589 | { | 581 | { |
590 | portmux_set_func(PIOB, 18, FUNC_B); /* RXD */ | 582 | select_peripheral(PB(18), PERIPH_B, 0); /* RXD */ |
591 | portmux_set_func(PIOB, 17, FUNC_B); /* TXD */ | 583 | select_peripheral(PB(17), PERIPH_B, 0); /* TXD */ |
592 | } | 584 | } |
593 | 585 | ||
594 | static struct platform_device *at32_usarts[4]; | 586 | static struct platform_device *at32_usarts[4]; |
@@ -663,27 +655,27 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data) | |||
663 | case 0: | 655 | case 0: |
664 | pdev = &macb0_device; | 656 | pdev = &macb0_device; |
665 | 657 | ||
666 | portmux_set_func(PIOC, 3, FUNC_A); /* TXD0 */ | 658 | select_peripheral(PC(3), PERIPH_A, 0); /* TXD0 */ |
667 | portmux_set_func(PIOC, 4, FUNC_A); /* TXD1 */ | 659 | select_peripheral(PC(4), PERIPH_A, 0); /* TXD1 */ |
668 | portmux_set_func(PIOC, 7, FUNC_A); /* TXEN */ | 660 | select_peripheral(PC(7), PERIPH_A, 0); /* TXEN */ |
669 | portmux_set_func(PIOC, 8, FUNC_A); /* TXCK */ | 661 | select_peripheral(PC(8), PERIPH_A, 0); /* TXCK */ |
670 | portmux_set_func(PIOC, 9, FUNC_A); /* RXD0 */ | 662 | select_peripheral(PC(9), PERIPH_A, 0); /* RXD0 */ |
671 | portmux_set_func(PIOC, 10, FUNC_A); /* RXD1 */ | 663 | select_peripheral(PC(10), PERIPH_A, 0); /* RXD1 */ |
672 | portmux_set_func(PIOC, 13, FUNC_A); /* RXER */ | 664 | select_peripheral(PC(13), PERIPH_A, 0); /* RXER */ |
673 | portmux_set_func(PIOC, 15, FUNC_A); /* RXDV */ | 665 | select_peripheral(PC(15), PERIPH_A, 0); /* RXDV */ |
674 | portmux_set_func(PIOC, 16, FUNC_A); /* MDC */ | 666 | select_peripheral(PC(16), PERIPH_A, 0); /* MDC */ |
675 | portmux_set_func(PIOC, 17, FUNC_A); /* MDIO */ | 667 | select_peripheral(PC(17), PERIPH_A, 0); /* MDIO */ |
676 | 668 | ||
677 | if (!data->is_rmii) { | 669 | if (!data->is_rmii) { |
678 | portmux_set_func(PIOC, 0, FUNC_A); /* COL */ | 670 | select_peripheral(PC(0), PERIPH_A, 0); /* COL */ |
679 | portmux_set_func(PIOC, 1, FUNC_A); /* CRS */ | 671 | select_peripheral(PC(1), PERIPH_A, 0); /* CRS */ |
680 | portmux_set_func(PIOC, 2, FUNC_A); /* TXER */ | 672 | select_peripheral(PC(2), PERIPH_A, 0); /* TXER */ |
681 | portmux_set_func(PIOC, 5, FUNC_A); /* TXD2 */ | 673 | select_peripheral(PC(5), PERIPH_A, 0); /* TXD2 */ |
682 | portmux_set_func(PIOC, 6, FUNC_A); /* TXD3 */ | 674 | select_peripheral(PC(6), PERIPH_A, 0); /* TXD3 */ |
683 | portmux_set_func(PIOC, 11, FUNC_A); /* RXD2 */ | 675 | select_peripheral(PC(11), PERIPH_A, 0); /* RXD2 */ |
684 | portmux_set_func(PIOC, 12, FUNC_A); /* RXD3 */ | 676 | select_peripheral(PC(12), PERIPH_A, 0); /* RXD3 */ |
685 | portmux_set_func(PIOC, 14, FUNC_A); /* RXCK */ | 677 | select_peripheral(PC(14), PERIPH_A, 0); /* RXCK */ |
686 | portmux_set_func(PIOC, 18, FUNC_A); /* SPD */ | 678 | select_peripheral(PC(18), PERIPH_A, 0); /* SPD */ |
687 | } | 679 | } |
688 | break; | 680 | break; |
689 | 681 | ||
@@ -714,12 +706,12 @@ struct platform_device *__init at32_add_device_spi(unsigned int id) | |||
714 | switch (id) { | 706 | switch (id) { |
715 | case 0: | 707 | case 0: |
716 | pdev = &spi0_device; | 708 | pdev = &spi0_device; |
717 | portmux_set_func(PIOA, 0, FUNC_A); /* MISO */ | 709 | select_peripheral(PA(0), PERIPH_A, 0); /* MISO */ |
718 | portmux_set_func(PIOA, 1, FUNC_A); /* MOSI */ | 710 | select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */ |
719 | portmux_set_func(PIOA, 2, FUNC_A); /* SCK */ | 711 | select_peripheral(PA(2), PERIPH_A, 0); /* SCK */ |
720 | portmux_set_func(PIOA, 3, FUNC_A); /* NPCS0 */ | 712 | select_peripheral(PA(3), PERIPH_A, 0); /* NPCS0 */ |
721 | portmux_set_func(PIOA, 4, FUNC_A); /* NPCS1 */ | 713 | select_peripheral(PA(4), PERIPH_A, 0); /* NPCS1 */ |
722 | portmux_set_func(PIOA, 5, FUNC_A); /* NPCS2 */ | 714 | select_peripheral(PA(5), PERIPH_A, 0); /* NPCS2 */ |
723 | break; | 715 | break; |
724 | 716 | ||
725 | default: | 717 | default: |
@@ -762,37 +754,37 @@ at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data) | |||
762 | switch (id) { | 754 | switch (id) { |
763 | case 0: | 755 | case 0: |
764 | pdev = &lcdc0_device; | 756 | pdev = &lcdc0_device; |
765 | portmux_set_func(PIOC, 19, FUNC_A); /* CC */ | 757 | select_peripheral(PC(19), PERIPH_A, 0); /* CC */ |
766 | portmux_set_func(PIOC, 20, FUNC_A); /* HSYNC */ | 758 | select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */ |
767 | portmux_set_func(PIOC, 21, FUNC_A); /* PCLK */ | 759 | select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */ |
768 | portmux_set_func(PIOC, 22, FUNC_A); /* VSYNC */ | 760 | select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC */ |
769 | portmux_set_func(PIOC, 23, FUNC_A); /* DVAL */ | 761 | select_peripheral(PC(23), PERIPH_A, 0); /* DVAL */ |
770 | portmux_set_func(PIOC, 24, FUNC_A); /* MODE */ | 762 | select_peripheral(PC(24), PERIPH_A, 0); /* MODE */ |
771 | portmux_set_func(PIOC, 25, FUNC_A); /* PWR */ | 763 | select_peripheral(PC(25), PERIPH_A, 0); /* PWR */ |
772 | portmux_set_func(PIOC, 26, FUNC_A); /* DATA0 */ | 764 | select_peripheral(PC(26), PERIPH_A, 0); /* DATA0 */ |
773 | portmux_set_func(PIOC, 27, FUNC_A); /* DATA1 */ | 765 | select_peripheral(PC(27), PERIPH_A, 0); /* DATA1 */ |
774 | portmux_set_func(PIOC, 28, FUNC_A); /* DATA2 */ | 766 | select_peripheral(PC(28), PERIPH_A, 0); /* DATA2 */ |
775 | portmux_set_func(PIOC, 29, FUNC_A); /* DATA3 */ | 767 | select_peripheral(PC(29), PERIPH_A, 0); /* DATA3 */ |
776 | portmux_set_func(PIOC, 30, FUNC_A); /* DATA4 */ | 768 | select_peripheral(PC(30), PERIPH_A, 0); /* DATA4 */ |
777 | portmux_set_func(PIOC, 31, FUNC_A); /* DATA5 */ | 769 | select_peripheral(PC(31), PERIPH_A, 0); /* DATA5 */ |
778 | portmux_set_func(PIOD, 0, FUNC_A); /* DATA6 */ | 770 | select_peripheral(PD(0), PERIPH_A, 0); /* DATA6 */ |
779 | portmux_set_func(PIOD, 1, FUNC_A); /* DATA7 */ | 771 | select_peripheral(PD(1), PERIPH_A, 0); /* DATA7 */ |
780 | portmux_set_func(PIOD, 2, FUNC_A); /* DATA8 */ | 772 | select_peripheral(PD(2), PERIPH_A, 0); /* DATA8 */ |
781 | portmux_set_func(PIOD, 3, FUNC_A); /* DATA9 */ | 773 | select_peripheral(PD(3), PERIPH_A, 0); /* DATA9 */ |
782 | portmux_set_func(PIOD, 4, FUNC_A); /* DATA10 */ | 774 | select_peripheral(PD(4), PERIPH_A, 0); /* DATA10 */ |
783 | portmux_set_func(PIOD, 5, FUNC_A); /* DATA11 */ | 775 | select_peripheral(PD(5), PERIPH_A, 0); /* DATA11 */ |
784 | portmux_set_func(PIOD, 6, FUNC_A); /* DATA12 */ | 776 | select_peripheral(PD(6), PERIPH_A, 0); /* DATA12 */ |
785 | portmux_set_func(PIOD, 7, FUNC_A); /* DATA13 */ | 777 | select_peripheral(PD(7), PERIPH_A, 0); /* DATA13 */ |
786 | portmux_set_func(PIOD, 8, FUNC_A); /* DATA14 */ | 778 | select_peripheral(PD(8), PERIPH_A, 0); /* DATA14 */ |
787 | portmux_set_func(PIOD, 9, FUNC_A); /* DATA15 */ | 779 | select_peripheral(PD(9), PERIPH_A, 0); /* DATA15 */ |
788 | portmux_set_func(PIOD, 10, FUNC_A); /* DATA16 */ | 780 | select_peripheral(PD(10), PERIPH_A, 0); /* DATA16 */ |
789 | portmux_set_func(PIOD, 11, FUNC_A); /* DATA17 */ | 781 | select_peripheral(PD(11), PERIPH_A, 0); /* DATA17 */ |
790 | portmux_set_func(PIOD, 12, FUNC_A); /* DATA18 */ | 782 | select_peripheral(PD(12), PERIPH_A, 0); /* DATA18 */ |
791 | portmux_set_func(PIOD, 13, FUNC_A); /* DATA19 */ | 783 | select_peripheral(PD(13), PERIPH_A, 0); /* DATA19 */ |
792 | portmux_set_func(PIOD, 14, FUNC_A); /* DATA20 */ | 784 | select_peripheral(PD(14), PERIPH_A, 0); /* DATA20 */ |
793 | portmux_set_func(PIOD, 15, FUNC_A); /* DATA21 */ | 785 | select_peripheral(PD(15), PERIPH_A, 0); /* DATA21 */ |
794 | portmux_set_func(PIOD, 16, FUNC_A); /* DATA22 */ | 786 | select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */ |
795 | portmux_set_func(PIOD, 17, FUNC_A); /* DATA23 */ | 787 | select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */ |
796 | 788 | ||
797 | clk_set_parent(&lcdc0_pixclk, &pll0); | 789 | clk_set_parent(&lcdc0_pixclk, &pll0); |
798 | clk_set_rate(&lcdc0_pixclk, clk_get_rate(&pll0)); | 790 | clk_set_rate(&lcdc0_pixclk, clk_get_rate(&pll0)); |
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 | ||
32 | static struct pio_device pio_dev[MAX_NR_PIO_DEVICES]; | 32 | static struct pio_device pio_dev[MAX_NR_PIO_DEVICES]; |
33 | 33 | ||
34 | void portmux_set_func(unsigned int portmux_id, unsigned int pin_id, | 34 | static 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 | |||
51 | void __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 | |||
81 | fail: | ||
82 | dump_stack(); | ||
83 | } | ||
84 | |||
85 | void __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 | |||
118 | fail: | ||
119 | dump_stack(); | ||
49 | } | 120 | } |
50 | 121 | ||
51 | static int __init pio_probe(struct platform_device *pdev) | 122 | static int __init pio_probe(struct platform_device *pdev) |