Linux下s3c6410的GPIO操作(5)

1、我们曾经在前面看到这个函数,源码如下:

__init void s3c_gpiolib_add(struct s3c_gpio_chip *chip){struct gpio_chip *gc = &chip->chip;int ret;BUG_ON(!chip->base);BUG_ON(!gc->label);BUG_ON(!gc->ngpio);if (!gc->direction_input)gc->direction_input = s3c_gpiolib_input;if (!gc->direction_output)gc->direction_output = s3c_gpiolib_output;if (!gc->set)gc->set = s3c_gpiolib_set;if (!gc->get)gc->get = s3c_gpiolib_get;当初只是对这一部分,说明gc内部成员的赋值,而没具体分析这几个函数,我里的几个函数并不是对每个GPIO都实用,有些我们定义了新的函数,所以并不用这些默认值,希望你能分清,那些用的是默认值,哪些是我们新定义的。我们现在分析下。/* gpiochip_add() prints own failure message on error. */ret = gpiochip_add(gc);if (ret >= 0)s3c_gpiolib_track(chip);

}

2、这几个函数的源码都在linux/arch/arm/plat-s3c/gpio.c文件中:

/* Default routines for controlling GPIO, based on the original S3C24XX* GPIO functions which deal with the case where each gpio bank of the* chip is as following:** base + 0x00: Control register, 2 bits per gpio* gpio n: 2 bits starting at (2*n)*00 = input, 01 = output, others mean special-function

以前是4位,现在是2位,区别就在这里* base + 0x04: Data register, 1 bit per gpio*bit n: data bit n*/static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset){struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);void __iomem *base = ourchip->base; 这些都和前面一样unsigned long flags;unsigned long con;local_irq_save(flags);con = __raw_readl(base + 0x00);con &= ~(3 << (offset * 2));__raw_writel(con, base + 0x00);local_irq_restore(flags);return 0;}

static int s3c_gpiolib_output(struct gpio_chip *chip, unsigned offset, int value){struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);void __iomem *base = ourchip->base;unsigned long flags;unsigned long dat;unsigned long con;local_irq_save(flags);dat = __raw_readl(base + 0x04);dat &= ~(1 << offset);if (value)dat |= 1 << offset;__raw_writel(dat, base + 0x04);con = __raw_readl(base + 0x00);con &= ~(3 << (offset * 2));con |= 1 << (offset * 2);__raw_writel(con, base + 0x00);__raw_writel(dat, base + 0x04);

__raw_writel(dat, base + OFF_GPDAT);写数据寄存器__raw_writel(con, base + OFF_GPCON);写控制寄存器__raw_writel(dat, base + OFF_GPDAT);写数据寄存器

这里有个疑问,为何要写两次数据寄存器?

local_irq_restore(flags);return 0;}

这两个函数是针对数据寄存器的,所以对4位,2位的控制寄存器都实用,因为数据寄存器中1位表示一个IO口,大家都一样,所以没必要特殊化。当然,使用的场合就有所不同,我想一般在设置为输出的时候才需要对某一位设置成1或者0吧?在设置为输入的时候,才需要读取吧?函数很简单,就不分析了。static void s3c_gpiolib_set(struct gpio_chip *chip, unsigned offset, int value){struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);void __iomem *base = ourchip->base;unsigned long flags;unsigned long dat;local_irq_save(flags);dat = __raw_readl(base + 0x04);dat &= ~(1 << offset);if (value)dat |= 1 << offset;__raw_writel(dat, base + 0x04);local_irq_restore(flags);}

static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset){struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);unsigned long val;val = __raw_readl(ourchip->base + 0x04);val >>= offset;val &= 1;return val;}

别人失去了信心,他却下决心实现自己的目标。

Linux下s3c6410的GPIO操作(5)

相关文章:

你感兴趣的文章:

标签云: