主题 : 使用gpio-cfg.h中提供的函数来操作gpio 复制链接 | 浏览器收藏 | 打印
级别: 侠客
UID: 6350
精华: 2
发帖: 110
金钱: 895 两
威望: 486 点
贡献值: 2 点
综合积分: 260 分
注册时间: 2009-05-29
最后登录: 2016-10-11
楼主  发表于: 2011-08-03 11:02

 使用gpio-cfg.h中提供的函数来操作gpio

使用gpio-cfg.h中提供的函数来操作gpio
在使用之前先得搞清楚gpio如何初始化的


参阅 arch/arm/mach-s3c64xx/gpiolib.c
gpio的信息分别保存在  gpio_4bit, gpio_4bit2, gpio_2bit三个结构体数组中
gpio_4bit是指gpio的每个端口在con中占4bit
gpio_4bit2是指gpio的每个端口在con中占4bit,如果gpio端口多的花,一个con寄存器不够用,得有两个
gpio_2bit是指gpio的每个端口在con中占2bit

gpio_4bit, gpio_4bit2, gpio_2bit三个结构体如下
struct s3c_gpio_chip {
    struct gpio_chip    chip;
    struct s3c_gpio_cfg    *config;
    struct s3c_gpio_pm    *pm;
    void __iomem        *base;
    int            irq_base;
    int            group;
    spinlock_t         lock;
#ifdef CONFIG_PM
    u32            pm_save[4];
#endif
};

gpio_4bit 包含 GPA GPB GPC GPD GPE GPG GPM
gpio_4bit2 包含 GPH GPK GPL
gpio_2bit 包含 GPF GPI GPJ GPN GPO GPP GPQ



内核调用s3c64xx_gpiolib_init函数来初始化gpio信息
在s3c64xx_gpiolib_init函数中,又调用了三次s3c64xx_gpiolib_add函数,将三组gpio加入信息表


函数s3c64xx_gpiolib_add循环遍历数组,调用s3c_gpiolib_add函数添加每个gpio端口

s3c_gpiolib_add函数定义在arch/arm/plat-samsung/gpio.c中
该函数对gpio数据进行检验,之后调用s3c_gpiolib_track将gpio信息保存在数组s3c_gpios中

s3c_gpios数组是一个关键数据,

使用前包含如下头文件
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>

可以使用的函数

int s3c_gpio_cfgpin(unsigned int pin, unsigned int to); //设置单一io
unsigned s3c_gpio_getcfg(unsigned int pin);//获取io口的配置
int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr, unsigned int cfg); //设置一组io
int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull); //设置单一io的上拉电阻
s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);//获取io口的上拉电阻配置
int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr, unsigned int cfg, s3c_gpio_pull_t pull);//设置一组io(包括上拉电阻)

这里有个问题,我们可以发现它并没有提供setpin函数,这就需要我们自己添加了
我这里抛砖引玉,加个
附个patch

diff --git a/arch/arm/mach-s3c64xx/gpiolib.c b/arch/arm/mach-s3c64xx/gpiolib.c
index 92b0908..2aed1f1 100644
--- a/arch/arm/mach-s3c64xx/gpiolib.c
+++ b/arch/arm/mach-s3c64xx/gpiolib.c
@@ -54,6 +54,7 @@ static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
     .get_config    = s3c_gpio_getcfg_s3c64xx_4bit,
     .set_pull    = s3c_gpio_setpull_updown,
     .get_pull    = s3c_gpio_getpull_updown,
+    .set_pin    = s3c_gpio_setpin_s3c64xx,
};

static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
@@ -62,6 +63,7 @@ static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
     .get_config    = s3c_gpio_getcfg_s3c64xx_4bit,
     .set_pull    = s3c_gpio_setpull_updown,
     .get_pull    = s3c_gpio_getpull_updown,
+    .set_pin    = s3c_gpio_setpin_s3c64xx,
};

static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
@@ -70,6 +72,7 @@ static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
     .set_config    = s3c_gpio_setcfg_s3c64xx_4bit,
     .set_pull    = s3c_gpio_setpull_updown,
     .get_pull    = s3c_gpio_getpull_updown,
+    .set_pin    = s3c_gpio_setpin_s3c64xx,
};

static int s3c64xx_gpio2int_gpm(struct gpio_chip *chip, unsigned pin)
@@ -177,6 +180,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
     .get_config    = s3c_gpio_getcfg_s3c24xx,
     .set_pull    = s3c_gpio_setpull_updown,
     .get_pull    = s3c_gpio_getpull_updown,
+    .set_pin    = s3c_gpio_setpin_s3c64xx,
};

static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
@@ -185,6 +189,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
     .get_config    = s3c_gpio_getcfg_s3c24xx,
     .set_pull    = s3c_gpio_setpull_updown,
     .get_pull    = s3c_gpio_getpull_updown,
+    .set_pin    = s3c_gpio_setpin_s3c64xx,
};

static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
@@ -193,6 +198,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
     .get_config    = s3c_gpio_getcfg_s3c24xx,
     .set_pull    = s3c_gpio_setpull_updown,
     .get_pull    = s3c_gpio_getpull_updown,
+    .set_pin    = s3c_gpio_setpin_s3c64xx,
};

static struct s3c_gpio_chip gpio_2bit[] = {
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index 1c0b040..6cce8bb 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -130,6 +130,24 @@ s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
}
EXPORT_SYMBOL(s3c_gpio_getpull);

+int s3c_gpio_setpin(unsigned int pin, int value)
+{
+    struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+    unsigned long flags;
+    int offset, ret;
+
+    if (chip) {
+        offset = pin - chip->chip.base;
+        s3c_gpio_lock(chip, flags);
+        ret = s3c_gpio_do_setpin(chip, offset, value);
+        s3c_gpio_unlock(chip, flags);
+        return ret;
+    }
+
+    return -EINVAL;
+}
+EXPORT_SYMBOL(s3c_gpio_setpin);
+
#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
                   unsigned int off, unsigned int cfg)
@@ -249,6 +267,18 @@ unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
     return S3C_GPIO_SPECIAL(con);
}

+int s3c_gpio_setpin_s3c64xx(struct s3c_gpio_chip *chip,
+                 unsigned int off, int val)
+{
+    void __iomem *reg = chip->base + 4;
+    u32 data;
+
+    data = __raw_readl(reg);
+    data &= ~(0x1 << off);
+    data |= (val & 0x1) << off;
+    __raw_writel(data, reg);
+    return 0;
+}
#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */

#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
index 5603db0..776b762 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -48,6 +48,11 @@ static inline s3c_gpio_pull_t s3c_gpio_do_getpull(struct s3c_gpio_chip *chip,
     return chip->config->get_pull(chip, off);
}

+static inline int s3c_gpio_do_setpin(struct s3c_gpio_chip *chip,
+                      unsigned int off, int val)
+{
+    return (chip->config->set_pin)(chip, off, val);      
+}
/**
  * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
  * @chip: The gpio chip that is being configured.
@@ -138,6 +143,9 @@ extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
                          unsigned int off);

+extern int s3c_gpio_setpin_s3c64xx(struct s3c_gpio_chip *chip,
+                 unsigned int off, int val);
+
/* Pull-{up,down} resistor controls.
  *
  * S3C2410,S3C2440,S3C24A0 = Pull-UP,
@@ -158,6 +166,7 @@ extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
                 unsigned int off, s3c_gpio_pull_t pull);

+
/**
  * s3c_gpio_setpull_1down() - Pull configuration for choice of down or none
  * @chip: The gpio chip that is being configured
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index e4b5cf1..6feef63 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -59,6 +59,8 @@ struct s3c_gpio_cfg {
     unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs);
     int     (*set_config)(struct s3c_gpio_chip *chip, unsigned offs,
                    unsigned config);
+    int     (*set_pin)(struct s3c_gpio_chip *chip, unsigned offs,
+                    int value);
};

#define S3C_GPIO_SPECIAL_MARK    (0xfffffff0)
@@ -172,6 +174,15 @@ extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
extern int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
                  unsigned int cfg, s3c_gpio_pull_t pull);

+/**
+ * s3c_gpio_setpin() - set output value.
+ * @pin: The gpio number.
+ * @value: The value.
+ *
+ */
+extern int s3c_gpio_setpin(unsigned int pin,  int value);
+
+
static inline int s3c_gpio_cfgrange_nopull(unsigned int pin, unsigned int size,
                        unsigned int cfg)
{
diff --git a/drivers/char/mini6410_leds.c b/drivers/char/mini6410_leds.c
index d3ab414..7132857 100644
--- a/drivers/char/mini6410_leds.c
+++ b/drivers/char/mini6410_leds.c
@@ -35,21 +35,16 @@
static long sbc2440_leds_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
     switch(cmd) {
-        unsigned tmp;
-    case 0:
-    case 1:
-        if (arg > 4) {
+        case 0:
+        case 1:
+            break;
+        default:
             return -EINVAL;
-        }
-        tmp = readl(S3C64XX_GPKDAT);
-        tmp &= ~(1 << (4 + arg));
-        tmp |= ( (!cmd) << (4 + arg) );
-        writel(tmp, S3C64XX_GPKDAT);
-        //printk (DEVICE_NAME": %d %d\n", arg, cmd);
-        return 0;
-    default:
+    }
+    if (arg > 4) {
         return -EINVAL;
     }
+    return s3c_gpio_setpin(S3C64XX_GPK(4 + arg), !cmd);
}

static struct file_operations dev_fops = {
@@ -67,17 +62,16 @@ static int __init dev_init(void)
{
     int ret;

-    ret = s3c_gpio_cfgall_range(S3C64XX_GPK(4), 4, S3C_GPIO_OUTPUT, S3C_GPIO_PULL_UP);
+    ret = s3c_gpio_cfgpin_range(S3C64XX_GPK(4), 4, S3C_GPIO_OUTPUT);

     if (ret) {
         printk (DEVICE_NAME"\t failed\n");
         return ret;
     }

-
     ret = misc_register(&misc);

-    printk (DEVICE_NAME"\tinitialized\n");
+    printk (DEVICE_NAME"\t loaded \n");

     return ret;
}

御·铃白
级别: 新手上路
UID: 61257
精华: 0
发帖: 7
金钱: 40 两
威望: 8 点
贡献值: 0 点
综合积分: 14 分
注册时间: 2011-12-26
最后登录: 2012-05-20
1楼  发表于: 2012-05-12 19:06
级别: 新手上路
UID: 68151
精华: 0
发帖: 4
金钱: 20 两
威望: 4 点
贡献值: 0 点
综合积分: 8 分
注册时间: 2012-04-19
最后登录: 2012-05-29
2楼  发表于: 2012-05-29 18:04
表示看不懂···