没想到一个小小的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];这个数组大家,应该还有印象。
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,
};
}
其他的和前一个函数都很类似,我们只看这部分
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))