首先来看s3c_gpio_cfgpin();

int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
{
struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);//得到对应GPIO结构体首指针,里面包含了该GPIO的各种参数
    unsigned long flags;
int offset;
int ret; if (!chip)
return -EINVAL; offset = pin - chip->chip.base; s3c_gpio_lock(chip, flags);
ret = s3c_gpio_do_setcfg(chip, offset, config);//设置该GPIO状态寄存器的数值为config
    s3c_gpio_unlock(chip, flags);

    return ret;
}
static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip)
{
return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
}
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_cfg = {
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg)
{
void __iomem *reg = chip->base;
unsigned int shift = (off & ) * ;
u32 con; if (off < && chip->chip.ngpio > )
reg -= ; if (s3c_gpio_is_cfg_special(cfg)) {
cfg &= 0xf;
cfg <<= shift;
} con = __raw_readl(reg);//读GPXCON的值
con &= ~(0xf << shift);//清零
con |= cfg;//设置config
__raw_writel(con, reg);//写值 return ;
}

其中结构体s3c_gpio_chip如下:

Linux下GPIO驱动(二) ----s3c_gpio_cfgpin();gpio_set_value();-LMLPHP

/**
* struct s3c_gpio_chip - wrapper for specific implementation of gpio
* @chip: The chip structure to be exported via gpiolib.
* @base: The base pointer to the gpio configuration registers.
* @config: special function and pull-resistor control information.
* @lock: Lock for exclusive access to this gpio bank.
* @pm_save: Save information for suspend/resume support.
*
* This wrapper provides the necessary information for the Samsung
* specific gpios being registered with gpiolib.
*
* The lock protects each gpio bank from multiple access of the shared
* configuration registers, or from reading of data whilst another thread
* is writing to the register set.
*
* Each chip has its own lock to avoid any contention between different
* CPU cores trying to get one lock for different GPIO banks, where each
* bank of GPIO has its own register space and configuration registers.
*/
struct s3c_gpio_chip {
struct gpio_chip chip;
struct s3c_gpio_cfg *config;
struct s3c_gpio_pm *pm;
void __iomem *base;
int eint_offset;
spinlock_t lock;
#ifdef CONFIG_PM
u32 pm_save[];
#endif
};
static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {//描述了芯片中所有的GPIO端口
{
.chip = {
.base = S5PV210_GPA0(),
.ngpio = S5PV210_GPIO_A0_NR,
.label = "GPA0",
.to_irq = s5p_gpiolib_gpioint_to_irq,
},
},{
。。。。
}
。。。。
};

接下来看gpio_set_value();

void __gpio_set_value(unsigned gpio, int value)
{
struct gpio_chip *chip; chip = gpio_to_chip(gpio);//返回对应于pin的gpio_desc[pin].chip指针
WARN_ON(extra_checks && chip->can_sleep);
chip->set(chip, gpio - chip->base, value);//调用chip->set
}

那么chip的成员函数set是怎么实现的呢?请看下篇

05-11 11:29