mirror of
https://github.com/adulau/aha.git
synced 2025-01-01 05:36:24 +00:00
[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>
This commit is contained in:
parent
68380b5813
commit
c3e2a79c0b
4 changed files with 194 additions and 88 deletions
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <asm/arch/at32ap7000.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/portmux.h>
|
||||
#include <asm/arch/sm.h>
|
||||
|
@ -57,6 +58,9 @@ static struct platform_device _name##_id##_device = { \
|
|||
.num_resources = ARRAY_SIZE(_name##_id##_resource), \
|
||||
}
|
||||
|
||||
#define select_peripheral(pin, periph, flags) \
|
||||
at32_select_periph(GPIO_PIN_##pin, GPIO_##periph, flags)
|
||||
|
||||
#define DEV_CLK(_name, devname, bus, _index) \
|
||||
static struct clk devname##_##_name = { \
|
||||
.name = #_name, \
|
||||
|
@ -67,18 +71,6 @@ static struct clk devname##_##_name = { \
|
|||
.index = _index, \
|
||||
}
|
||||
|
||||
enum {
|
||||
PIOA,
|
||||
PIOB,
|
||||
PIOC,
|
||||
PIOD,
|
||||
};
|
||||
|
||||
enum {
|
||||
FUNC_A,
|
||||
FUNC_B,
|
||||
};
|
||||
|
||||
unsigned long at32ap7000_osc_rates[3] = {
|
||||
[0] = 32768,
|
||||
/* FIXME: these are ATSTK1002-specific */
|
||||
|
@ -569,26 +561,26 @@ DEV_CLK(usart, atmel_usart3, pba, 6);
|
|||
|
||||
static inline void configure_usart0_pins(void)
|
||||
{
|
||||
portmux_set_func(PIOA, 8, FUNC_B); /* RXD */
|
||||
portmux_set_func(PIOA, 9, FUNC_B); /* TXD */
|
||||
select_peripheral(PA(8), PERIPH_B, 0); /* RXD */
|
||||
select_peripheral(PA(9), PERIPH_B, 0); /* TXD */
|
||||
}
|
||||
|
||||
static inline void configure_usart1_pins(void)
|
||||
{
|
||||
portmux_set_func(PIOA, 17, FUNC_A); /* RXD */
|
||||
portmux_set_func(PIOA, 18, FUNC_A); /* TXD */
|
||||
select_peripheral(PA(17), PERIPH_A, 0); /* RXD */
|
||||
select_peripheral(PA(18), PERIPH_A, 0); /* TXD */
|
||||
}
|
||||
|
||||
static inline void configure_usart2_pins(void)
|
||||
{
|
||||
portmux_set_func(PIOB, 26, FUNC_B); /* RXD */
|
||||
portmux_set_func(PIOB, 27, FUNC_B); /* TXD */
|
||||
select_peripheral(PB(26), PERIPH_B, 0); /* RXD */
|
||||
select_peripheral(PB(27), PERIPH_B, 0); /* TXD */
|
||||
}
|
||||
|
||||
static inline void configure_usart3_pins(void)
|
||||
{
|
||||
portmux_set_func(PIOB, 18, FUNC_B); /* RXD */
|
||||
portmux_set_func(PIOB, 17, FUNC_B); /* TXD */
|
||||
select_peripheral(PB(18), PERIPH_B, 0); /* RXD */
|
||||
select_peripheral(PB(17), PERIPH_B, 0); /* TXD */
|
||||
}
|
||||
|
||||
static struct platform_device *at32_usarts[4];
|
||||
|
@ -663,27 +655,27 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data)
|
|||
case 0:
|
||||
pdev = &macb0_device;
|
||||
|
||||
portmux_set_func(PIOC, 3, FUNC_A); /* TXD0 */
|
||||
portmux_set_func(PIOC, 4, FUNC_A); /* TXD1 */
|
||||
portmux_set_func(PIOC, 7, FUNC_A); /* TXEN */
|
||||
portmux_set_func(PIOC, 8, FUNC_A); /* TXCK */
|
||||
portmux_set_func(PIOC, 9, FUNC_A); /* RXD0 */
|
||||
portmux_set_func(PIOC, 10, FUNC_A); /* RXD1 */
|
||||
portmux_set_func(PIOC, 13, FUNC_A); /* RXER */
|
||||
portmux_set_func(PIOC, 15, FUNC_A); /* RXDV */
|
||||
portmux_set_func(PIOC, 16, FUNC_A); /* MDC */
|
||||
portmux_set_func(PIOC, 17, FUNC_A); /* MDIO */
|
||||
select_peripheral(PC(3), PERIPH_A, 0); /* TXD0 */
|
||||
select_peripheral(PC(4), PERIPH_A, 0); /* TXD1 */
|
||||
select_peripheral(PC(7), PERIPH_A, 0); /* TXEN */
|
||||
select_peripheral(PC(8), PERIPH_A, 0); /* TXCK */
|
||||
select_peripheral(PC(9), PERIPH_A, 0); /* RXD0 */
|
||||
select_peripheral(PC(10), PERIPH_A, 0); /* RXD1 */
|
||||
select_peripheral(PC(13), PERIPH_A, 0); /* RXER */
|
||||
select_peripheral(PC(15), PERIPH_A, 0); /* RXDV */
|
||||
select_peripheral(PC(16), PERIPH_A, 0); /* MDC */
|
||||
select_peripheral(PC(17), PERIPH_A, 0); /* MDIO */
|
||||
|
||||
if (!data->is_rmii) {
|
||||
portmux_set_func(PIOC, 0, FUNC_A); /* COL */
|
||||
portmux_set_func(PIOC, 1, FUNC_A); /* CRS */
|
||||
portmux_set_func(PIOC, 2, FUNC_A); /* TXER */
|
||||
portmux_set_func(PIOC, 5, FUNC_A); /* TXD2 */
|
||||
portmux_set_func(PIOC, 6, FUNC_A); /* TXD3 */
|
||||
portmux_set_func(PIOC, 11, FUNC_A); /* RXD2 */
|
||||
portmux_set_func(PIOC, 12, FUNC_A); /* RXD3 */
|
||||
portmux_set_func(PIOC, 14, FUNC_A); /* RXCK */
|
||||
portmux_set_func(PIOC, 18, FUNC_A); /* SPD */
|
||||
select_peripheral(PC(0), PERIPH_A, 0); /* COL */
|
||||
select_peripheral(PC(1), PERIPH_A, 0); /* CRS */
|
||||
select_peripheral(PC(2), PERIPH_A, 0); /* TXER */
|
||||
select_peripheral(PC(5), PERIPH_A, 0); /* TXD2 */
|
||||
select_peripheral(PC(6), PERIPH_A, 0); /* TXD3 */
|
||||
select_peripheral(PC(11), PERIPH_A, 0); /* RXD2 */
|
||||
select_peripheral(PC(12), PERIPH_A, 0); /* RXD3 */
|
||||
select_peripheral(PC(14), PERIPH_A, 0); /* RXCK */
|
||||
select_peripheral(PC(18), PERIPH_A, 0); /* SPD */
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -714,12 +706,12 @@ struct platform_device *__init at32_add_device_spi(unsigned int id)
|
|||
switch (id) {
|
||||
case 0:
|
||||
pdev = &spi0_device;
|
||||
portmux_set_func(PIOA, 0, FUNC_A); /* MISO */
|
||||
portmux_set_func(PIOA, 1, FUNC_A); /* MOSI */
|
||||
portmux_set_func(PIOA, 2, FUNC_A); /* SCK */
|
||||
portmux_set_func(PIOA, 3, FUNC_A); /* NPCS0 */
|
||||
portmux_set_func(PIOA, 4, FUNC_A); /* NPCS1 */
|
||||
portmux_set_func(PIOA, 5, FUNC_A); /* NPCS2 */
|
||||
select_peripheral(PA(0), PERIPH_A, 0); /* MISO */
|
||||
select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */
|
||||
select_peripheral(PA(2), PERIPH_A, 0); /* SCK */
|
||||
select_peripheral(PA(3), PERIPH_A, 0); /* NPCS0 */
|
||||
select_peripheral(PA(4), PERIPH_A, 0); /* NPCS1 */
|
||||
select_peripheral(PA(5), PERIPH_A, 0); /* NPCS2 */
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -762,37 +754,37 @@ at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data)
|
|||
switch (id) {
|
||||
case 0:
|
||||
pdev = &lcdc0_device;
|
||||
portmux_set_func(PIOC, 19, FUNC_A); /* CC */
|
||||
portmux_set_func(PIOC, 20, FUNC_A); /* HSYNC */
|
||||
portmux_set_func(PIOC, 21, FUNC_A); /* PCLK */
|
||||
portmux_set_func(PIOC, 22, FUNC_A); /* VSYNC */
|
||||
portmux_set_func(PIOC, 23, FUNC_A); /* DVAL */
|
||||
portmux_set_func(PIOC, 24, FUNC_A); /* MODE */
|
||||
portmux_set_func(PIOC, 25, FUNC_A); /* PWR */
|
||||
portmux_set_func(PIOC, 26, FUNC_A); /* DATA0 */
|
||||
portmux_set_func(PIOC, 27, FUNC_A); /* DATA1 */
|
||||
portmux_set_func(PIOC, 28, FUNC_A); /* DATA2 */
|
||||
portmux_set_func(PIOC, 29, FUNC_A); /* DATA3 */
|
||||
portmux_set_func(PIOC, 30, FUNC_A); /* DATA4 */
|
||||
portmux_set_func(PIOC, 31, FUNC_A); /* DATA5 */
|
||||
portmux_set_func(PIOD, 0, FUNC_A); /* DATA6 */
|
||||
portmux_set_func(PIOD, 1, FUNC_A); /* DATA7 */
|
||||
portmux_set_func(PIOD, 2, FUNC_A); /* DATA8 */
|
||||
portmux_set_func(PIOD, 3, FUNC_A); /* DATA9 */
|
||||
portmux_set_func(PIOD, 4, FUNC_A); /* DATA10 */
|
||||
portmux_set_func(PIOD, 5, FUNC_A); /* DATA11 */
|
||||
portmux_set_func(PIOD, 6, FUNC_A); /* DATA12 */
|
||||
portmux_set_func(PIOD, 7, FUNC_A); /* DATA13 */
|
||||
portmux_set_func(PIOD, 8, FUNC_A); /* DATA14 */
|
||||
portmux_set_func(PIOD, 9, FUNC_A); /* DATA15 */
|
||||
portmux_set_func(PIOD, 10, FUNC_A); /* DATA16 */
|
||||
portmux_set_func(PIOD, 11, FUNC_A); /* DATA17 */
|
||||
portmux_set_func(PIOD, 12, FUNC_A); /* DATA18 */
|
||||
portmux_set_func(PIOD, 13, FUNC_A); /* DATA19 */
|
||||
portmux_set_func(PIOD, 14, FUNC_A); /* DATA20 */
|
||||
portmux_set_func(PIOD, 15, FUNC_A); /* DATA21 */
|
||||
portmux_set_func(PIOD, 16, FUNC_A); /* DATA22 */
|
||||
portmux_set_func(PIOD, 17, FUNC_A); /* DATA23 */
|
||||
select_peripheral(PC(19), PERIPH_A, 0); /* CC */
|
||||
select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */
|
||||
select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */
|
||||
select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC */
|
||||
select_peripheral(PC(23), PERIPH_A, 0); /* DVAL */
|
||||
select_peripheral(PC(24), PERIPH_A, 0); /* MODE */
|
||||
select_peripheral(PC(25), PERIPH_A, 0); /* PWR */
|
||||
select_peripheral(PC(26), PERIPH_A, 0); /* DATA0 */
|
||||
select_peripheral(PC(27), PERIPH_A, 0); /* DATA1 */
|
||||
select_peripheral(PC(28), PERIPH_A, 0); /* DATA2 */
|
||||
select_peripheral(PC(29), PERIPH_A, 0); /* DATA3 */
|
||||
select_peripheral(PC(30), PERIPH_A, 0); /* DATA4 */
|
||||
select_peripheral(PC(31), PERIPH_A, 0); /* DATA5 */
|
||||
select_peripheral(PD(0), PERIPH_A, 0); /* DATA6 */
|
||||
select_peripheral(PD(1), PERIPH_A, 0); /* DATA7 */
|
||||
select_peripheral(PD(2), PERIPH_A, 0); /* DATA8 */
|
||||
select_peripheral(PD(3), PERIPH_A, 0); /* DATA9 */
|
||||
select_peripheral(PD(4), PERIPH_A, 0); /* DATA10 */
|
||||
select_peripheral(PD(5), PERIPH_A, 0); /* DATA11 */
|
||||
select_peripheral(PD(6), PERIPH_A, 0); /* DATA12 */
|
||||
select_peripheral(PD(7), PERIPH_A, 0); /* DATA13 */
|
||||
select_peripheral(PD(8), PERIPH_A, 0); /* DATA14 */
|
||||
select_peripheral(PD(9), PERIPH_A, 0); /* DATA15 */
|
||||
select_peripheral(PD(10), PERIPH_A, 0); /* DATA16 */
|
||||
select_peripheral(PD(11), PERIPH_A, 0); /* DATA17 */
|
||||
select_peripheral(PD(12), PERIPH_A, 0); /* DATA18 */
|
||||
select_peripheral(PD(13), PERIPH_A, 0); /* DATA19 */
|
||||
select_peripheral(PD(14), PERIPH_A, 0); /* DATA20 */
|
||||
select_peripheral(PD(15), PERIPH_A, 0); /* DATA21 */
|
||||
select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */
|
||||
select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */
|
||||
|
||||
clk_set_parent(&lcdc0_pixclk, &pll0);
|
||||
clk_set_rate(&lcdc0_pixclk, clk_get_rate(&pll0));
|
||||
|
|
|
@ -25,27 +25,98 @@ struct pio_device {
|
|||
void __iomem *regs;
|
||||
const struct platform_device *pdev;
|
||||
struct clk *clk;
|
||||
u32 alloc_mask;
|
||||
u32 pinmux_mask;
|
||||
char name[32];
|
||||
};
|
||||
|
||||
static struct pio_device pio_dev[MAX_NR_PIO_DEVICES];
|
||||
|
||||
void portmux_set_func(unsigned int portmux_id, unsigned int pin_id,
|
||||
unsigned int function_id)
|
||||
static struct pio_device *gpio_to_pio(unsigned int gpio)
|
||||
{
|
||||
struct pio_device *pio;
|
||||
u32 mask = 1 << pin_id;
|
||||
unsigned int index;
|
||||
|
||||
BUG_ON(portmux_id >= MAX_NR_PIO_DEVICES);
|
||||
index = gpio >> 5;
|
||||
if (index >= MAX_NR_PIO_DEVICES)
|
||||
return NULL;
|
||||
pio = &pio_dev[index];
|
||||
if (!pio->regs)
|
||||
return NULL;
|
||||
|
||||
pio = &pio_dev[portmux_id];
|
||||
return pio;
|
||||
}
|
||||
|
||||
if (function_id)
|
||||
/* Pin multiplexing API */
|
||||
|
||||
void __init at32_select_periph(unsigned int pin, unsigned int periph,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct pio_device *pio;
|
||||
unsigned int pin_index = pin & 0x1f;
|
||||
u32 mask = 1 << pin_index;
|
||||
|
||||
pio = gpio_to_pio(pin);
|
||||
if (unlikely(!pio)) {
|
||||
printk("pio: invalid pin %u\n", pin);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) {
|
||||
printk("%s: pin %u is busy\n", pio->name, pin_index);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pio_writel(pio, PUER, mask);
|
||||
if (periph)
|
||||
pio_writel(pio, BSR, mask);
|
||||
else
|
||||
pio_writel(pio, ASR, mask);
|
||||
|
||||
pio_writel(pio, PDR, mask);
|
||||
if (!(flags & AT32_GPIOF_PULLUP))
|
||||
pio_writel(pio, PUDR, mask);
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
dump_stack();
|
||||
}
|
||||
|
||||
void __init at32_select_gpio(unsigned int pin, unsigned long flags)
|
||||
{
|
||||
struct pio_device *pio;
|
||||
unsigned int pin_index = pin & 0x1f;
|
||||
u32 mask = 1 << pin_index;
|
||||
|
||||
pio = gpio_to_pio(pin);
|
||||
if (unlikely(!pio)) {
|
||||
printk("pio: invalid pin %u\n", pin);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) {
|
||||
printk("%s: pin %u is busy\n", pio->name, pin_index);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pio_writel(pio, PUER, mask);
|
||||
if (flags & AT32_GPIOF_HIGH)
|
||||
pio_writel(pio, SODR, mask);
|
||||
else
|
||||
pio_writel(pio, CODR, mask);
|
||||
if (flags & AT32_GPIOF_OUTPUT)
|
||||
pio_writel(pio, OER, mask);
|
||||
else
|
||||
pio_writel(pio, ODR, mask);
|
||||
|
||||
pio_writel(pio, PER, mask);
|
||||
if (!(flags & AT32_GPIOF_PULLUP))
|
||||
pio_writel(pio, PUDR, mask);
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
dump_stack();
|
||||
}
|
||||
|
||||
static int __init pio_probe(struct platform_device *pdev)
|
||||
|
|
33
include/asm-avr32/arch-at32ap/at32ap7000.h
Normal file
33
include/asm-avr32/arch-at32ap/at32ap7000.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Pin definitions for AT32AP7000.
|
||||
*
|
||||
* Copyright (C) 2006 Atmel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef __ASM_ARCH_AT32AP7000_H__
|
||||
#define __ASM_ARCH_AT32AP7000_H__
|
||||
|
||||
#define GPIO_PERIPH_A 0
|
||||
#define GPIO_PERIPH_B 1
|
||||
|
||||
#define NR_GPIO_CONTROLLERS 4
|
||||
|
||||
/*
|
||||
* Pin numbers identifying specific GPIO pins on the chip. They can
|
||||
* also be converted to IRQ numbers by passing them through
|
||||
* gpio_to_irq().
|
||||
*/
|
||||
#define GPIO_PIOA_BASE (0)
|
||||
#define GPIO_PIOB_BASE (GPIO_PIOA_BASE + 32)
|
||||
#define GPIO_PIOC_BASE (GPIO_PIOB_BASE + 32)
|
||||
#define GPIO_PIOD_BASE (GPIO_PIOC_BASE + 32)
|
||||
|
||||
#define GPIO_PIN_PA(N) (GPIO_PIOA_BASE + (N))
|
||||
#define GPIO_PIN_PB(N) (GPIO_PIOB_BASE + (N))
|
||||
#define GPIO_PIN_PC(N) (GPIO_PIOC_BASE + (N))
|
||||
#define GPIO_PIN_PD(N) (GPIO_PIOD_BASE + (N))
|
||||
|
||||
#endif /* __ASM_ARCH_AT32AP7000_H__ */
|
|
@ -7,10 +7,20 @@
|
|||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef __ASM_AVR32_AT32_PORTMUX_H__
|
||||
#define __ASM_AVR32_AT32_PORTMUX_H__
|
||||
#ifndef __ASM_ARCH_PORTMUX_H__
|
||||
#define __ASM_ARCH_PORTMUX_H__
|
||||
|
||||
void portmux_set_func(unsigned int portmux_id, unsigned int pin_id,
|
||||
unsigned int function_id);
|
||||
/*
|
||||
* Set up pin multiplexing, called from board init only.
|
||||
*
|
||||
* The following flags determine the initial state of the pin.
|
||||
*/
|
||||
#define AT32_GPIOF_PULLUP 0x00000001 /* Enable pull-up */
|
||||
#define AT32_GPIOF_OUTPUT 0x00000002 /* Enable output driver */
|
||||
#define AT32_GPIOF_HIGH 0x00000004 /* Set output high */
|
||||
|
||||
#endif /* __ASM_AVR32_AT32_PORTMUX_H__ */
|
||||
void at32_select_periph(unsigned int pin, unsigned int periph,
|
||||
unsigned long flags);
|
||||
void at32_select_gpio(unsigned int pin, unsigned long flags);
|
||||
|
||||
#endif /* __ASM_ARCH_PORTMUX_H__ */
|
||||
|
|
Loading…
Reference in a new issue