Commit 34b2b751 authored by Alexander Potashev's avatar Alexander Potashev
Browse files

RT73025. ea-lpc1788: GPIO driver; setup pins for UART

Configure GPIO pins for UART.

GPIO driver:
 * lpc178x_gpio_config_table()
 * lpc178x_gpio_config_direction()
 * lpc178x_gpout_set()
 * lpc178x_gpin_get()
parent 73ca0251
......@@ -25,14 +25,51 @@
#include <common.h>
DECLARE_GLOBAL_DATA_PTR;
#include <asm/arch/lpc178x_gpio.h>
/*
* GPIO pin configuration table for EA-LPC1788
*/
static const struct lpc178x_gpio_pin_config ea_lpc1788_gpio[] = {
#if CONFIG_LPC178X_UART_PORT == 0
/* P0.2 (D) = UART0 TXD */
{{0, 2}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 0, 0)},
/* P0.3 (D) = UART0 RXD */
{{0, 3}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 0, 0)},
#elif CONFIG_LPC178X_UART_PORT == 2
/* P0.10 (D) = U2_TXD */
{{0, 10}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 0, 0)},
/* P0.11 (D) = U2_RXD */
{{0, 11}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 0, 0)},
#else /* Neither UART0 nor UART2 */
#error This configuration of GPIO pins supports only UART0 or UART2
#endif
};
/*
* Configure all necessary GPIO pins
*/
static void gpio_init(void)
{
/*
* Enable power on GPIO. This is not really necessary, because power
* on GPIO is enabled on SoC reset.
*/
lpc178x_periph_enable(LPC178X_SCC_PCONP_PCGPIO_MSK, 1);
/*
* Configure GPIO pins
*/
lpc178x_gpio_config_table(ea_lpc1788_gpio, ARRAY_SIZE(ea_lpc1788_gpio));
}
/*
* Early hardware init.
*/
int board_init(void)
{
/* TBD */
gpio_init();
return 0;
}
......
......@@ -30,6 +30,7 @@ COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o
COBJS-$(CONFIG_MX31_GPIO) += mx31_gpio.o
COBJS-$(CONFIG_PCA953X) += pca953x.o
COBJS-$(CONFIG_STM32F2_GPIO) += stm32f2_gpio.o
COBJS-$(CONFIG_LPC178X_GPIO) += lpc178x_gpio.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
......
/*
* (C) Copyright 2011
*
* Alexander Potashev, Emcraft Systems, aspotashev@emcraft.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/errno.h>
#include <asm/arch/lpc178x_gpio.h>
DECLARE_GLOBAL_DATA_PTR;
/*
* List of available GPIO pins:
* P0[31:0]; P1[31:0]; P2[31:0]; P3[31:0]; P4[31:0]; P5[4:0]
*/
/* Number of GPIO ports */
#define LPC178X_GPIO_PORTS 6
/* Number of pins in all ports except the last one */
#define LPC178X_GPIO_NORMAL_PORT_PINS 32
/* Number of pins in the last port */
#define LPC178X_GPIO_LAST_PORT_PINS 5
/*
* IOCON (pin connect) registers base
*/
#define LPC178X_IOCON_BASE (LPC178X_APB0PERIPH_BASE + 0x0002C000)
/*
* Address of the IOCON register for the given pin
*/
#define LPC178X_IOCON_PIN_ADDR(port,pin) \
(LPC178X_IOCON_BASE + (port) * 0x80 + (pin) * 4)
/*
* Reference to the IOCON register for the given pin
*/
#define LPC178X_IOCON(port,pin) \
(*(volatile u32 *)LPC178X_IOCON_PIN_ADDR(port,pin))
/*
* GPIO register map
* Should be mapped at (0x20098000 + port * 0x20).
*/
struct lpc178x_gpio_regs {
u32 fiodir; /* Fast GPIO Port Direction control register */
u32 rsv0[3];
u32 fiomask; /* Fast Mask register for port */
u32 fiopin; /* Fast Port Pin value register using FIOMASK */
u32 fioset; /* Fast Port Output Set register using FIOMASK */
u32 fioclr; /* Fast Port Output Clear register using FIOMASK */
};
/*
* GPIO registers base
*/
#define LPC178X_GPIO_BASE (LPC178X_AHB_PERIPH_BASE + 0x00018000)
#define LPC178X_GPIO_PORT_ADDR(port) (LPC178X_GPIO_BASE + (port) * 0x20)
#define LPC178X_GPIO(port) \
((volatile struct lpc178x_gpio_regs *)LPC178X_GPIO_PORT_ADDR(port))
/*
* Check that the given (port, pin) pair is a valid LPC178x/7x GPIO pin.
* Returns 0 on success, -EINVAL otherwise.
*/
static inline int lpc178x_validate_gpio(const struct lpc178x_gpio_dsc *dsc)
{
int rv;
rv = 0;
/*
* P0[31:0]; P1[31:0]; P2[31:0]; P3[31:0]; P4[31:0]; P5[4:0]
*/
if (!dsc || dsc->port >= LPC178X_GPIO_PORTS ||
dsc->pin >= LPC178X_GPIO_NORMAL_PORT_PINS ||
(dsc->port == LPC178X_GPIO_PORTS - 1 &&
dsc->pin >= LPC178X_GPIO_LAST_PORT_PINS)) {
if (gd->have_console) {
printf("GPIO: incorrect params %d.%d.\n",
dsc ? dsc->port : -1,
dsc ? dsc->pin : -1);
}
rv = -EINVAL;
}
return rv;
}
/*
* Configure the specified GPIO pin.
* Returns 0 on success, -EINVAL otherwise.
*/
static int lpc178x_gpio_config(const struct lpc178x_gpio_dsc *dsc, u32 regval)
{
int rv;
rv = lpc178x_validate_gpio(dsc);
if (rv == 0)
LPC178X_IOCON(dsc->port, dsc->pin) = regval;
return rv;
}
/*
* Configure a set of GPIO pins using the given configuration table.
* Returns 0 on success.
*/
int lpc178x_gpio_config_table(
const struct lpc178x_gpio_pin_config *table, unsigned int len)
{
unsigned int i;
int rv;
for (i = 0; i < len; i ++) {
rv = lpc178x_gpio_config(&table[i].dsc, table[i].regval);
if (rv != 0)
goto out;
}
rv = 0;
out:
return rv;
}
/*
* output=0: Set a GPIO pin as an input.
* output=1: Set a GPIO pin as an output.
*
* Returns 0 on success, -EINVAL otherwise.
*/
int lpc178x_gpio_config_direction(const struct lpc178x_gpio_dsc *dsc, int output)
{
int rv;
rv = lpc178x_validate_gpio(dsc);
if (rv == 0) {
if (output)
LPC178X_GPIO(dsc->port)->fiodir |= (1 << dsc->pin);
else
LPC178X_GPIO(dsc->port)->fiodir &= ~(1 << dsc->pin);
}
return rv;
}
/*
* Set an output GPIO pin to the state specified (1, 0).
* Returns 0 on success, -EINVAL otherwise.
*/
int lpc178x_gpout_set(const struct lpc178x_gpio_dsc *dsc, int state)
{
int rv;
rv = lpc178x_validate_gpio(dsc);
if (rv == 0) {
if (state)
LPC178X_GPIO(dsc->port)->fioset = (1 << dsc->pin);
else
LPC178X_GPIO(dsc->port)->fioclr = (1 << dsc->pin);
}
return rv;
}
/*
* Return the state of an input GPIO.
* Returns 0 or 1 on success, -EINVAL otherwise.
*/
int lpc178x_gpin_get(const struct lpc178x_gpio_dsc *dsc)
{
int rv;
rv = lpc178x_validate_gpio(dsc);
if (rv == 0)
rv = (LPC178X_GPIO(dsc->port)->fiopin & (1 << dsc->pin)) ? 1 : 0;
return rv;
}
......@@ -46,6 +46,8 @@
#define LPC178X_APB0PERIPH_BASE (LPC178X_APB_PERIPH_BASE + 0x00000000)
#define LPC178X_APB1PERIPH_BASE (LPC178X_APB_PERIPH_BASE + 0x00080000)
#define LPC178X_AHB_PERIPH_BASE 0x20080000
/*
* 1-bit masks for PCONP (Power Control for Peripherals register) for different
* peripherals that enable power on them. One of these masks should be passed
......@@ -54,6 +56,7 @@
#define LPC178X_SCC_PCONP_PCUART0_MSK (1 << 3)
#define LPC178X_SCC_PCONP_PCUART1_MSK (1 << 4)
#define LPC178X_SCC_PCONP_PCUART4_MSK (1 << 8)
#define LPC178X_SCC_PCONP_PCGPIO_MSK (1 << 15)
#define LPC178X_SCC_PCONP_PCUART2_MSK (1 << 24)
#define LPC178X_SCC_PCONP_PCUART3_MSK (1 << 25)
......
/*
* (C) Copyright 2011
*
* Alexander Potashev, Emcraft Systems, aspotashev@emcraft.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef _LPC178X_GPIO_H_
#define _LPC178X_GPIO_H_
/*
* Bits and bit groups inside the IOCON registers
*/
/* Selects pin function */
#define LPC178X_GPIO_CONFIG_FUNC_BITS 0
/*
* Selects function mode (LPC178X_NO_PULLUP, LPC178X_PULLDOWN, LPC178X_PULLUP
* or LPC178X_REPEATER)
*/
#define LPC178X_GPIO_CONFIG_MODE_BITS 3
/* Hysteresis (1=enable, 0=disable) */
#define LPC178X_GPIO_CONFIG_HYS_BIT 5
/* Input polarity (1=input is inverted) */
#define LPC178X_GPIO_CONFIG_INV_BIT 6
/* Select Analog/Digital mode (0=analog, 1=digital) */
#define LPC178X_GPIO_CONFIG_ADMODE_BIT 7
#define LPC178X_GPIO_CONFIG_FILTER_BIT 8 /* Types A and W */
#define LPC178X_GPIO_CONFIG_HS_BIT 8 /* Type I */
#define LPC178X_GPIO_CONFIG_SLEW_BIT 9 /* Types D and W */
#define LPC178X_GPIO_CONFIG_HIDRIVE_BIT 9 /* Type I */
#define LPC178X_GPIO_CONFIG_OD_BITS 10
#define LPC178X_GPIO_CONFIG_DACEN_BIT 16
/*
* These macros should be used to compute the value for the second argument of
* `lpc178x_gpio_config()` (`regval`). This value will be copied into an IOCON
* register.
*/
/*
* Type D pins (digital pins)
*/
#define LPC178X_GPIO_CONFIG_D(func,mode,hys,inv,slew,od) \
((func << LPC178X_GPIO_CONFIG_FUNC_BITS) | \
(mode << LPC178X_GPIO_CONFIG_MODE_BITS) | \
(hys << LPC178X_GPIO_CONFIG_HYS_BIT ) | \
(inv << LPC178X_GPIO_CONFIG_INV_BIT ) | \
(slew << LPC178X_GPIO_CONFIG_SLEW_BIT ) | \
(od << LPC178X_GPIO_CONFIG_OD_BITS ))
/*
* TBD: similar macros for other pin types (A, U, I, W)
*/
/*
* Function mode for pins.
*
* One of these should be passed into LPC178X_GPIO_CONFIG_[DAUIW]() macros as
* the "mode" argument.
*/
#define LPC178X_NO_PULLUP 0
#define LPC178X_PULLDOWN 1
#define LPC178X_PULLUP 2
#define LPC178X_REPEATER 3
/*
* GPIO descriptor
*/
struct lpc178x_gpio_dsc {
unsigned int port; /* GPIO port */
unsigned int pin; /* GPIO pin */
};
struct lpc178x_gpio_pin_config {
struct lpc178x_gpio_dsc dsc;
u32 regval; /* Value for writing into the IOCON register */
};
/*
* Configure a set of GPIO pins using the given configuration table
*/
extern int lpc178x_gpio_config_table(
const struct lpc178x_gpio_pin_config *table, unsigned int len);
/*
* Set a GPIO pin as an input.
* Returns 0 on success, -EINVAL otherwise.
*/
int lpc178x_gpio_set_input(const struct lpc178x_gpio_dsc *dsc);
/*
* Set a GPIO pin as an output.
* Returns 0 on success, -EINVAL otherwise.
*/
int lpc178x_gpio_set_output(const struct lpc178x_gpio_dsc *dsc);
/*
* Set an output GPIO pin to the state specified (1, 0).
* Returns 0 on success, -EINVAL otherwise.
*/
int lpc178x_gpout_set(const struct lpc178x_gpio_dsc *gpio_dsc, int state);
/*
* Return the state of an input GPIO.
* Returns 0 or 1 on success, -EINVAL otherwise.
*/
int lpc178x_gpin_get(const struct lpc178x_gpio_dsc *gpio_dsc);
#endif /* _LPC178X_GPIO_H_ */
......@@ -44,7 +44,7 @@
/*
* Enable GPIO driver
*/
/* TBD */
#define CONFIG_LPC178X_GPIO
/*
* Display CPU and Board information
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment