Skip to content

Commit

Permalink
[ARM] 4757/1: [AT91] UART initialization
Browse files Browse the repository at this point in the history
Modify the UART initialization to allow the board-initialization code
to specify which pins are connected, and which pins should therefore
be initialized.

The current at91_init_serial() will continue to work as-is, but is
marked as "deprecated" and will be removed once the board-specific
files has been updated to use the new interface.

As in the AVR32 code, we assume that the TX and RX pins will always be
initialized.

Signed-off-by: Andrew Victor <linux@maxim.org.za>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Andrew Victor authored and Russell King committed Jan 26, 2008
1 parent b7b272a commit c8f385a
Show file tree
Hide file tree
Showing 6 changed files with 420 additions and 76 deletions.
114 changes: 92 additions & 22 deletions arch/arm/mach-at91/at91rm9200_devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -884,17 +884,21 @@ static struct platform_device at91rm9200_uart0_device = {
.num_resources = ARRAY_SIZE(uart0_resources),
};

static inline void configure_usart0_pins(void)
static inline void configure_usart0_pins(unsigned pins)
{
at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */
at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */
at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */

/*
* AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21.
* We need to drive the pin manually. Default is off (RTS is active low).
*/
at91_set_gpio_output(AT91_PIN_PA21, 1);
if (pins & ATMEL_UART_CTS)
at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */

if (pins & ATMEL_UART_RTS) {
/*
* AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21.
* We need to drive the pin manually. Default is off (RTS is active low).
*/
at91_set_gpio_output(AT91_PIN_PA21, 1);
}
}

static struct resource uart1_resources[] = {
Expand Down Expand Up @@ -929,16 +933,23 @@ static struct platform_device at91rm9200_uart1_device = {
.num_resources = ARRAY_SIZE(uart1_resources),
};

static inline void configure_usart1_pins(void)
static inline void configure_usart1_pins(unsigned pins)
{
at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */
at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */
at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */
at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */
at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */
at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */
at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */
at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */

if (pins & ATMEL_UART_RI)
at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */
if (pins & ATMEL_UART_DTR)
at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */
if (pins & ATMEL_UART_DCD)
at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */
if (pins & ATMEL_UART_CTS)
at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */
if (pins & ATMEL_UART_DSR)
at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */
if (pins & ATMEL_UART_RTS)
at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */
}

static struct resource uart2_resources[] = {
Expand Down Expand Up @@ -973,10 +984,15 @@ static struct platform_device at91rm9200_uart2_device = {
.num_resources = ARRAY_SIZE(uart2_resources),
};

static inline void configure_usart2_pins(void)
static inline void configure_usart2_pins(unsigned pins)
{
at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */
at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */

if (pins & ATMEL_UART_CTS)
at91_set_B_periph(AT91_PIN_PA30, 0); /* CTS2 */
if (pins & ATMEL_UART_RTS)
at91_set_B_periph(AT91_PIN_PA31, 0); /* RTS2 */
}

static struct resource uart3_resources[] = {
Expand Down Expand Up @@ -1011,39 +1027,44 @@ static struct platform_device at91rm9200_uart3_device = {
.num_resources = ARRAY_SIZE(uart3_resources),
};

static inline void configure_usart3_pins(void)
static inline void configure_usart3_pins(unsigned pins)
{
at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */
at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */

if (pins & ATMEL_UART_CTS)
at91_set_B_periph(AT91_PIN_PB1, 0); /* CTS3 */
if (pins & ATMEL_UART_RTS)
at91_set_B_periph(AT91_PIN_PB0, 0); /* RTS3 */
}

static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
struct platform_device *atmel_default_console_device; /* the serial console device */

void __init at91_init_serial(struct at91_uart_config *config)
void __init __deprecated at91_init_serial(struct at91_uart_config *config)
{
int i;

/* Fill in list of supported UARTs */
for (i = 0; i < config->nr_tty; i++) {
switch (config->tty_map[i]) {
case 0:
configure_usart0_pins();
configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
at91_uarts[i] = &at91rm9200_uart0_device;
at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart");
break;
case 1:
configure_usart1_pins();
configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS | ATMEL_UART_DSR | ATMEL_UART_DTR | ATMEL_UART_DCD | ATMEL_UART_RI);
at91_uarts[i] = &at91rm9200_uart1_device;
at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart");
break;
case 2:
configure_usart2_pins();
configure_usart2_pins(0);
at91_uarts[i] = &at91rm9200_uart2_device;
at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart");
break;
case 3:
configure_usart3_pins();
configure_usart3_pins(0);
at91_uarts[i] = &at91rm9200_uart3_device;
at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart");
break;
Expand All @@ -1065,6 +1086,53 @@ void __init at91_init_serial(struct at91_uart_config *config)
printk(KERN_INFO "AT91: No default serial console defined.\n");
}

void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
{
struct platform_device *pdev;

switch (id) {
case 0: /* DBGU */
pdev = &at91rm9200_dbgu_device;
configure_dbgu_pins();
at91_clock_associate("mck", &pdev->dev, "usart");
break;
case AT91RM9200_ID_US0:
pdev = &at91rm9200_uart0_device;
configure_usart0_pins(pins);
at91_clock_associate("usart0_clk", &pdev->dev, "usart");
break;
case AT91RM9200_ID_US1:
pdev = &at91rm9200_uart1_device;
configure_usart1_pins(pins);
at91_clock_associate("usart1_clk", &pdev->dev, "usart");
break;
case AT91RM9200_ID_US2:
pdev = &at91rm9200_uart2_device;
configure_usart2_pins(pins);
at91_clock_associate("usart2_clk", &pdev->dev, "usart");
break;
case AT91RM9200_ID_US3:
pdev = &at91rm9200_uart3_device;
configure_usart3_pins(pins);
at91_clock_associate("usart3_clk", &pdev->dev, "usart");
break;
default:
return;
}
pdev->id = portnr; /* update to mapped ID */

if (portnr < ATMEL_MAX_UART)
at91_uarts[portnr] = pdev;
}

void __init at91_set_serial_console(unsigned portnr)
{
if (portnr < ATMEL_MAX_UART)
atmel_default_console_device = at91_uarts[portnr];
if (!atmel_default_console_device)
printk(KERN_INFO "AT91: No default serial console defined.\n");
}

void __init at91_add_device_serial(void)
{
int i;
Expand All @@ -1075,7 +1143,9 @@ void __init at91_add_device_serial(void)
}
}
#else
void __init at91_init_serial(struct at91_uart_config *config) {}
void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
void __init at91_set_serial_console(unsigned portnr) {}
void __init at91_add_device_serial(void) {}
#endif

Expand Down
115 changes: 97 additions & 18 deletions arch/arm/mach-at91/at91sam9260_devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -760,16 +760,23 @@ static struct platform_device at91sam9260_uart0_device = {
.num_resources = ARRAY_SIZE(uart0_resources),
};

static inline void configure_usart0_pins(void)
static inline void configure_usart0_pins(unsigned pins)
{
at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */
at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */
at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */
at91_set_A_periph(AT91_PIN_PB27, 0); /* CTS0 */
at91_set_A_periph(AT91_PIN_PB24, 0); /* DTR0 */
at91_set_A_periph(AT91_PIN_PB22, 0); /* DSR0 */
at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD0 */
at91_set_A_periph(AT91_PIN_PB25, 0); /* RI0 */

if (pins & ATMEL_UART_RTS)
at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */
if (pins & ATMEL_UART_CTS)
at91_set_A_periph(AT91_PIN_PB27, 0); /* CTS0 */
if (pins & ATMEL_UART_DTR)
at91_set_A_periph(AT91_PIN_PB24, 0); /* DTR0 */
if (pins & ATMEL_UART_DSR)
at91_set_A_periph(AT91_PIN_PB22, 0); /* DSR0 */
if (pins & ATMEL_UART_DCD)
at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD0 */
if (pins & ATMEL_UART_RI)
at91_set_A_periph(AT91_PIN_PB25, 0); /* RI0 */
}

static struct resource uart1_resources[] = {
Expand Down Expand Up @@ -804,12 +811,15 @@ static struct platform_device at91sam9260_uart1_device = {
.num_resources = ARRAY_SIZE(uart1_resources),
};

static inline void configure_usart1_pins(void)
static inline void configure_usart1_pins(unsigned pins)
{
at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */
at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */
at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */
at91_set_A_periph(AT91_PIN_PB29, 0); /* CTS1 */

if (pins & ATMEL_UART_RTS)
at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */
if (pins & ATMEL_UART_CTS)
at91_set_A_periph(AT91_PIN_PB29, 0); /* CTS1 */
}

static struct resource uart2_resources[] = {
Expand Down Expand Up @@ -844,10 +854,15 @@ static struct platform_device at91sam9260_uart2_device = {
.num_resources = ARRAY_SIZE(uart2_resources),
};

static inline void configure_usart2_pins(void)
static inline void configure_usart2_pins(unsigned pins)
{
at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */
at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */

if (pins & ATMEL_UART_RTS)
at91_set_A_periph(AT91_PIN_PA4, 0); /* RTS2 */
if (pins & ATMEL_UART_CTS)
at91_set_A_periph(AT91_PIN_PA5, 0); /* CTS2 */
}

static struct resource uart3_resources[] = {
Expand Down Expand Up @@ -882,10 +897,15 @@ static struct platform_device at91sam9260_uart3_device = {
.num_resources = ARRAY_SIZE(uart3_resources),
};

static inline void configure_usart3_pins(void)
static inline void configure_usart3_pins(unsigned pins)
{
at91_set_A_periph(AT91_PIN_PB10, 1); /* TXD3 */
at91_set_A_periph(AT91_PIN_PB11, 0); /* RXD3 */

if (pins & ATMEL_UART_RTS)
at91_set_B_periph(AT91_PIN_PC8, 0); /* RTS3 */
if (pins & ATMEL_UART_CTS)
at91_set_B_periph(AT91_PIN_PC10, 0); /* CTS3 */
}

static struct resource uart4_resources[] = {
Expand Down Expand Up @@ -967,30 +987,30 @@ static inline void configure_usart5_pins(void)
static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
struct platform_device *atmel_default_console_device; /* the serial console device */

void __init at91_init_serial(struct at91_uart_config *config)
void __init __deprecated at91_init_serial(struct at91_uart_config *config)
{
int i;

/* Fill in list of supported UARTs */
for (i = 0; i < config->nr_tty; i++) {
switch (config->tty_map[i]) {
case 0:
configure_usart0_pins();
configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS | ATMEL_UART_DSR | ATMEL_UART_DTR | ATMEL_UART_DCD | ATMEL_UART_RI);
at91_uarts[i] = &at91sam9260_uart0_device;
at91_clock_associate("usart0_clk", &at91sam9260_uart0_device.dev, "usart");
break;
case 1:
configure_usart1_pins();
configure_usart1_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
at91_uarts[i] = &at91sam9260_uart1_device;
at91_clock_associate("usart1_clk", &at91sam9260_uart1_device.dev, "usart");
break;
case 2:
configure_usart2_pins();
configure_usart2_pins(0);
at91_uarts[i] = &at91sam9260_uart2_device;
at91_clock_associate("usart2_clk", &at91sam9260_uart2_device.dev, "usart");
break;
case 3:
configure_usart3_pins();
configure_usart3_pins(0);
at91_uarts[i] = &at91sam9260_uart3_device;
at91_clock_associate("usart3_clk", &at91sam9260_uart3_device.dev, "usart");
break;
Expand Down Expand Up @@ -1022,6 +1042,63 @@ void __init at91_init_serial(struct at91_uart_config *config)
printk(KERN_INFO "AT91: No default serial console defined.\n");
}

void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
{
struct platform_device *pdev;

switch (id) {
case 0: /* DBGU */
pdev = &at91sam9260_dbgu_device;
configure_dbgu_pins();
at91_clock_associate("mck", &pdev->dev, "usart");
break;
case AT91SAM9260_ID_US0:
pdev = &at91sam9260_uart0_device;
configure_usart0_pins(pins);
at91_clock_associate("usart0_clk", &pdev->dev, "usart");
break;
case AT91SAM9260_ID_US1:
pdev = &at91sam9260_uart1_device;
configure_usart1_pins(pins);
at91_clock_associate("usart1_clk", &pdev->dev, "usart");
break;
case AT91SAM9260_ID_US2:
pdev = &at91sam9260_uart2_device;
configure_usart2_pins(pins);
at91_clock_associate("usart2_clk", &pdev->dev, "usart");
break;
case AT91SAM9260_ID_US3:
pdev = &at91sam9260_uart3_device;
configure_usart3_pins(pins);
at91_clock_associate("usart3_clk", &pdev->dev, "usart");
break;
case AT91SAM9260_ID_US4:
pdev = &at91sam9260_uart4_device;
configure_usart4_pins();
at91_clock_associate("usart4_clk", &pdev->dev, "usart");
break;
case AT91SAM9260_ID_US5:
pdev = &at91sam9260_uart5_device;
configure_usart5_pins();
at91_clock_associate("usart5_clk", &pdev->dev, "usart");
break;
default:
return;
}
pdev->id = portnr; /* update to mapped ID */

if (portnr < ATMEL_MAX_UART)
at91_uarts[portnr] = pdev;
}

void __init at91_set_serial_console(unsigned portnr)
{
if (portnr < ATMEL_MAX_UART)
atmel_default_console_device = at91_uarts[portnr];
if (!atmel_default_console_device)
printk(KERN_INFO "AT91: No default serial console defined.\n");
}

void __init at91_add_device_serial(void)
{
int i;
Expand All @@ -1032,7 +1109,9 @@ void __init at91_add_device_serial(void)
}
}
#else
void __init at91_init_serial(struct at91_uart_config *config) {}
void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
void __init at91_set_serial_console(unsigned portnr) {}
void __init at91_add_device_serial(void) {}
#endif

Expand Down
Loading

0 comments on commit c8f385a

Please sign in to comment.