2.在uboot里面找到gpio相关的代码,在路径uboot/drivers/gpio/nuc970_gpio.c这个文件里面,先来看一次这个文件:
#include <common.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <asm-generic/gpio.h>
#include "nuc970_gpio.h"
struct gpio_port {
volatile unsigned int * dir;
volatile unsigned int * out;
volatile unsigned int * in;
};
static const struct gpio_port port_class[] = {
{(volatile unsigned int *)REG_GPIOA_DIR, (volatile unsigned int *)REG_GPIOA_DATAOUT,
(volatile unsigned int *)REG_GPIOA_DATAIN},
{(volatile unsigned int *)REG_GPIOB_DIR, (volatile unsigned int *)REG_GPIOB_DATAOUT,
(volatile unsigned int *)REG_GPIOB_DATAIN},
{(volatile unsigned int *)REG_GPIOC_DIR, (volatile unsigned int *)REG_GPIOC_DATAOUT,
(volatile unsigned int *)REG_GPIOC_DATAIN},
{(volatile unsigned int *)REG_GPIOD_DIR, (volatile unsigned int *)REG_GPIOD_DATAOUT,
(volatile unsigned int *)REG_GPIOD_DATAIN},
{(volatile unsigned int *)REG_GPIOE_DIR, (volatile unsigned int *)REG_GPIOE_DATAOUT,
(volatile unsigned int *)REG_GPIOE_DATAIN},
{(volatile unsigned int *)REG_GPIOF_DIR, (volatile unsigned int *)REG_GPIOF_DATAOUT,
(volatile unsigned int *)REG_GPIOF_DATAIN},
{(volatile unsigned int *)REG_GPIOG_DIR, (volatile unsigned int *)REG_GPIOG_DATAOUT,
(volatile unsigned int *)REG_GPIOG_DATAIN},
{(volatile unsigned int *)REG_GPIOH_DIR, (volatile unsigned int *)REG_GPIOH_DATAOUT,
(volatile unsigned int *)REG_GPIOH_DATAIN},
{(volatile unsigned int *)REG_GPIOI_DIR, (volatile unsigned int *)REG_GPIOI_DATAOUT,
(volatile unsigned int *)REG_GPIOI_DATAIN},
{},
};
static const struct gpio_port *nuc970_gpio_cla_port(unsigned gpio,
int *num)
{
int group;
group = gpio / GPIO_OFFSET;
*num = gpio % GPIO_OFFSET;
return &port_class[group];
}
/**
* Set value of the specified gpio
*/
int gpio_set_value(unsigned gpio, int val)
{
int port_num, value;
const struct gpio_port *port =
nuc970_gpio_cla_port(gpio, &port_num);
if ((readl(port->dir) & (1 << port_num))) { //GPIO OUT
value = readl(port->out);
if (val)
value |= (1 << port_num);
else
value &= ~(1 << port_num);
writel(value, port->out);
} else { //GPIO IN
value = readl(port->in);
if (val)
value |= (1 << port_num);
else
value &= ~(1 << port_num);
writel(value, port->in);;
}
return 0;
}
/**
* Get value of the specified gpio
*/
int gpio_get_value(unsigned gpio)
{
int port_num, value;
const struct gpio_port *port;
port = nuc970_gpio_cla_port(gpio, &port_num);
value = 0;
if ((readl(port->dir) & (1 << port_num))) { //GPIO OUT
value = (readl(port->out) >> port_num) & 0x1;
} else { //GPIO IN
value = (readl(port->in) >> port_num) & 0x1;
writel(value, port->in);
}
return value;
}
/**
* Set gpio direction as input
*/
int gpio_direction_input(unsigned gpio)
{
int port_num;
unsigned long value;
const struct gpio_port *port =
nuc970_gpio_cla_port(gpio, &port_num);
value = readl(port->dir);
value &= ~(1 << port_num);
writel(value, port->dir);
return 0;
}
|