Linux下s3c6410的GPIO操作(7)

没想到一个小小的GPIO操作函数,竟然写了七篇博客,这应该算是最后一篇了。

1、s3c6410的GPIO操作函数主要涉及到三个文件,如下所示:

arch/arm/plat-s3c64xx/gpiolib.c

linux/arch/arm/plat-s3c/gpio.c

linux/arch/arm/plat-s3c/gpio-config.c

这三个文件中的很多函数都已经讲到了,可以说基本上都讲了,当然,下面这两个函数没讲:

int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)

{

struct s3c_gpio_chip *chip =s3c_gpiolib_getchip(pin);

这个函数根据pin的引脚编号,得到对应的struct s3c_gpio_chip结构体,源码如下:

static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip)
{
return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
}

struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];这个数组大家,应该还有印象。


unsigned long flags;
int offset;
int ret;


if (!chip)
return -EINVAL;


offset = pin - chip->chip.base;得到偏移量


local_irq_save(flags);

ret = s3c_gpio_do_setcfg(chip, offset, config);

这函数源码如下:
/* As a note, all gpio configuration functions are entered exclusively, either
 * with the relevant lock held or the system prevented from doing anything else
 * by disabling interrupts.
*/
static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip,
    unsigned int off, unsigned int config)
{
return (chip->config->set_config)(chip, off, config);
}

通过这调用具体的函数。例如:

static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
.set_config= s3c_gpio_setcfg_s3c64xx_4bit,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};

local_irq_restore(flags);


return ret;
}

2、看另外一个函数,源码如下:
int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
{
struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
unsigned long flags;
int offset, ret;


if (!chip)
return -EINVAL;


offset = pin - chip->chip.base;


local_irq_save(flags);
ret = s3c_gpio_do_setpull(chip, offset, pull);
local_irq_restore(flags);


return ret;

}

其他的和前一个函数都很类似,我们只看这部分

static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
     unsigned int off, s3c_gpio_pull_t pull)
{
return (chip->config->set_pull)(chip, off, pull);
}

也是调用具体的函数,如下

static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
.set_pull= s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
}

EXPORT_SYMBOL(s3c_gpio_cfgpin);
EXPORT_SYMBOL(s3c_gpio_setpull);

终于可以松口气了,GPIO操作函数以及所涉及的文件都已分析完了,可是要告诉大家一个不幸的消息,其实我们费那么多事,其实在实际运用中,也可不用这些函数,只需要下面这些就可以了,究竟是什么呢?其实,大家想一下,不就是对IO寄存器的操作吗?直接对其直接进行不也是一样的吗,何必费那么多事。包装真可怕!

#define __raw_writeb(v,a)(__chk_io_ptr(a), *(volatile unsigned char __force  *)(a) = (v))
#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))
#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force   *)(a) = (v))


#define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force  *)(a))
#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force   *)(a))




你可能感兴趣的:(c,linux,struct,IO,null,System)