NXP imx6ull在uboot中控制gpio
函数
复用
arch/arm/mach-imx/iomux-v3.c
/* configures a list of pads within declared with IOMUX_PADS macro */
void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
unsigned count)
{
iomux_v3_cfg_t const *p = pad_list;
int stride;
int i;
#if defined(CONFIG_MX6QDL)
stride = 2;
if (!is_mx6dq() && !is_mx6dqp())
p += 1;
#else
stride = 1;
#endif
for (i = 0; i < count; i++) {
imx_iomux_v3_setup_pad(*p);
p += stride;
}
}
控制
drivers/gpio/mxc_gpio.c
常用函数:
static int mxc_gpio_direction(unsigned int gpio,
enum mxc_gpio_direction direction)
{
unsigned int port = GPIO_TO_PORT(gpio);
struct gpio_regs *regs;
u32 l;
if (port >= ARRAY_SIZE(gpio_ports))
return -1;
if (RDC_CHECK(port))
return -1;
RDC_SPINLOCK_UP(port);
gpio &= 0x1f;
regs = (struct gpio_regs *)gpio_ports[port];
l = readl(®s->gpio_dir);
switch (direction) {
case MXC_GPIO_DIRECTION_OUT:
l |= 1 << gpio;
break;
case MXC_GPIO_DIRECTION_IN:
l &= ~(1 << gpio);
}
writel(l, ®s->gpio_dir);
RDC_SPINLOCK_DOWN(port);
return 0;
}
int gpio_set_value(unsigned gpio, int value)
{
unsigned int port = GPIO_TO_PORT(gpio);
struct gpio_regs *regs;
u32 l;
if (port >= ARRAY_SIZE(gpio_ports))
return -1;
if (RDC_CHECK(port))
return -1;
RDC_SPINLOCK_UP(port);
gpio &= 0x1f;
regs = (struct gpio_regs *)gpio_ports[port];
l = readl(®s->gpio_dr);
if (value)
l |= 1 << gpio;
else
l &= ~(1 << gpio);
writel(l, ®s->gpio_dr);
RDC_SPINLOCK_DOWN(port);
return 0;
}
int gpio_get_value(unsigned gpio)
{
unsigned int port = GPIO_TO_PORT(gpio);
struct gpio_regs *regs;
u32 val;
if (port >= ARRAY_SIZE(gpio_ports))
return -1;
if (RDC_CHECK(port))
return -1;
RDC_SPINLOCK_UP(port);
gpio &= 0x1f;
regs = (struct gpio_regs *)gpio_ports[port];
val = (readl(®s->gpio_dr) >> gpio) & 0x01;
RDC_SPINLOCK_DOWN(port);
return val;
}
int gpio_request(unsigned gpio, const char *label)
{
unsigned int port = GPIO_TO_PORT(gpio);
if (port >= ARRAY_SIZE(gpio_ports))
return -1;
if (RDC_CHECK(port))
return -1;
return 0;
}
int gpio_free(unsigned gpio)
{
return 0;
}
int gpio_direction_input(unsigned gpio)
{
return mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_IN);
}
int gpio_direction_output(unsigned gpio, int value)
{
int ret = gpio_set_value(gpio, value);
if (ret < 0)
return ret;
return mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_OUT);
}
控制GPIO
在引脚复用定义文件,arch/arm/include/asm/arch-mx6/mx6ull_pins.h中找到需要控制的引脚。
在 board/freescale/mx6ullevk/mx6ullevk.c 中添加定义和控制代码。
static iomux_v3_cfg_t const mygpio_pads[] = {
MX6_PAD_SNVS_TAMPER0__GPIO5_IO000 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
//随便找个函数控制gpio
int power_init_board(void)
{
/*** 省略原有代码 ***/
imx_iomux_v3_setup_multiple_pads(mygpio_pads, ARRAY_SIZE(mygpio_pads));
/*IMX_GPIO_NR计算gpio号
#define IMX_GPIO_NR(port, index) ((((port)-1)*32)+((index)&31))
gpio5_0, (5-1)*32+0 = 128
*/
gpio_request(IMX_GPIO_NR(5, 0), "mygpio");
//设置为输出模式,输出低信号
gpio_direction_output(IMX_GPIO_NR(5, 0) , 0);
}