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

 首先来看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 & 7) * 4;
    u32 con;

    if (off < 8 && chip->chip.ngpio > 8)
        reg -= 4;

    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 0;
}

 其中结构体s3c_gpio_chip如下:

/**
 * 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[7];
#endif
};

 

static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {//描述了芯片中所有的GPIO端口
    {
        .chip    = {
            .base    = S5PV210_GPA0(0),
            .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是怎么实现的呢?请看下篇

posted on 2013-08-24 14:55  熊猫酒仙是也  阅读(6848)  评论(0编辑  收藏  举报

导航