|
相关源码路径如下:
- kernel/drivers/gpio/gpiolib.c
- kernel/arch/arm/plat-samsung/gpio.c
- kernel/arch/arm/plat-samsung/gpio-config.c
- kernel/arch/arm/mach-exynos/include/mach/gpio-exynos4.h
复制代码
内核中已经将GPIO的相关操作都封装成了函数库,我们只需要调用即可。这里只给出几种常用的操作函数的使用方法,具体实现过程可以琢磨源码。
设置GPIO上下拉属性的函数清单如下:
- 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;
- s3c_gpio_lock(chip, flags);
- ret = s3c_gpio_do_setpull(chip, offset, pull);
- s3c_gpio_unlock(chip, flags);
- return ret;
- }
- EXPORT_SYMBOL(s3c_gpio_setpull);
复制代码
第一个传入参数表示需要设置的管脚编号,第二个传入参数表示上下拉的属性。每一个GPIO的管脚编号都可以通过宏来指定,这些宏都在gpio-exynos4.h中定义。按照4412芯片手册的寄存器介绍,GPIO可以配置成禁止上下拉,上拉或下拉三种状态,对应宏定义如下:
- #define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00)
- #define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01)
- #define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x02)
复制代码
以设置GPD0(1)为例,如我们需要将它设置为带上拉功能,执行如下程序即可:
s3c_gpio_setpull(EXYNOS4_GPD0(1), S3C_GPIO_PULL_UP);
设置GPIO功能属性的函数清单如下:
- int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
- {
- struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
- 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);
- s3c_gpio_unlock(chip, flags);
- return ret;
- }
- EXPORT_SYMBOL(s3c_gpio_cfgpin);
复制代码
同样,第一个传入参数表示管脚编号,第二个传入参数表示配置信息,如下宏可以表述管脚的配置状态:
- #define S3C_GPIO_SPECIAL_MARK (0xfffffff0)
- #define S3C_GPIO_SPECIAL(x) (S3C_GPIO_SPECIAL_MARK | (x))
- #define S3C_GPIO_INPUT (S3C_GPIO_SPECIAL(0))
- #define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1))
- #define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x))
复制代码
S3C_GPIO_SFN(0)或S3C_GPIO_INPUT表示将管脚设置为输入,S3C_GPIO_SFN(1)或S3C_GPIO_OUTPUT表示将管脚设置为输出,将管脚设置为其他复合的功能时,需参考4412芯片用户手册的寄存器参数表,结合S3C_GPIO_SFN宏使用。
以下程序表示将GPD0(1)管脚设置为输出:
s3c_gpio_cfgpin(EXYNOS4_GPD0(1), S3C_GPIO_SFN(1));
当GPIO被设置为输出时,设置其电平状态属性的函数清单如下:
- #define gpio_set_value __gpio_set_value
- void __gpio_set_value(unsigned gpio, int value)//设置GPIO电平
- {
- struct gpio_chip *chip;
- chip = gpio_to_chip(gpio);
- WARN_ON(chip->can_sleep);
- trace_gpio_value(gpio, 0, value);
- chip->set(chip, gpio - chip->base, value);
- }
- EXPORT_SYMBOL_GPL(__gpio_set_value);
复制代码
gpio表示管脚编号,value表示电平状态,0表示低电平,1表示高电平。如下程序表示将GPD0(1)管脚设置为低电平:
- gpio_set_value(EXYNOS4_GPD0(1), 0);
复制代码
gpio_request和gpio_free函数分别用于申请GPIO和释放GPIO,强烈建议在使用GPIO时,首先申请GPIO,用完后释放,避免IO口冲突。申请GPD0(1)作为GPIO口的程序清单如下:
gpio_request(EXYNOS4_GPD0(1), "GPD0(1)");
这里第一个传入参数为IO口的管脚编号,第二个为IO口的名称,可自定义。释放GPD0(1)的程序清单如下:
- gpio_free(EXYNOS4_GPD0(1));
复制代码
通常在配置一个GPIO口时,首先通过gpio_request函数申请GPIO口,再通过s3c_gpio_setpull、s3c_gpio_cfgpin、gpio_set_value函数配置GPIO口,在不用时通过gpio_free
函数释放GPIO口。
|
|