Linux中的IO使用方法
应该是新版本内核才有的方法。
请参考:./Documentation/gpio.txt文件
提供的API:
驱动需要包含 #include <linux/gpio.h>
判断一个IO是否合法:int gpio_is_valid(int number);
设置GPIO的方向,如果是输出同时设置电平:
/* set as input or output, returning 0 or negative errno */
int gpio_direction_input(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);
获取输入引脚的电平:
/* GPIO INPUT: return zero or nonzero */
int gpio_get_value(unsigned gpio);
/* GPIO OUTPUT */
void gpio_set_value(unsigned gpio, int value);
int gpio_cansleep(unsigned gpio);
To access such GPIOs, a different set of accessors is defined:
/* GPIO INPUT: return zero or nonzero, might sleep */
int gpio_get_value_cansleep(unsigned gpio);
/* GPIO OUTPUT, might sleep */
void gpio_set_value_cansleep(unsigned gpio, int value);
获取一个GPIO并声明标签:
/* request GPIO, returning 0 or negative errno.
* non-null labels may be useful for diagnostics.
*/
int gpio_request(unsigned gpio, const char *label);
/* release previously-claimed GPIO */
void gpio_free(unsigned gpio);
将GPIO映射为IRQ中断:
/* map GPIO numbers to IRQ numbers */
int gpio_to_irq(unsigned gpio);
/* map IRQ numbers to GPIO numbers (avoid using this) */
int irq_to_gpio(unsigned irq);
设置GPIO IRQ中断类型:
if (!sw->both_edges) {
if (gpio_get_value(sw->gpio))
set_irq_type(gpio_to_irq(sw->gpio), IRQ_TYPE_EDGE_FALLING);
else
set_irq_type(gpio_to_irq(sw->gpio), IRQ_TYPE_EDGE_RISING);
在驱动中使用延时函数mdelay,需要包含<linux/delay.h>文件。
- #ifndef __LINUX_GPIO_H
- #define __LINUX_GPIO_H
-
- /* see Documentation/gpio.txt */
-
- #ifdef CONFIG_GENERIC_GPIO
- #include <asm/gpio.h>
-
- #else
-
- #include <linux/kernel.h>
- #include <linux/types.h>
- #include <linux/errno.h>
-
- struct device;
-
- .......
- 实现了一些与GENERIC_GPIO类型的gpio接口函数同样声明的空函数。
- .......
-
- #endif
-
- #endif /* __LINUX_GPIO_H */
- #ifndef _ARCH_ARM_GPIO_H
- #define _ARCH_ARM_GPIO_H
-
- /* not all ARM platforms necessarily support this API ... */
- #include <mach/gpio.h>
-
- #endif /* _ARCH_ARM_GPIO_H */
- /* arch/arm/mach-s3c2410/include/mach/gpio.h
- *
- * Copyright (c) 2008 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - GPIO lib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
- #define gpio_get_value __gpio_get_value
- #define gpio_set_value __gpio_set_value
- #define gpio_cansleep __gpio_cansleep
- #define gpio_to_irq __gpio_to_irq
-
- /* some boards require extra gpio capacity to support external
- * devices that need GPIO.
- */
-
- #ifdef CONFIG_CPU_S3C244X
- #define ARCH_NR_GPIOS (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)
- #else
- #define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA)
- #endif
-
- #include <asm-generic/gpio.h>
- #include <mach/gpio-nrs.h>
- #include <mach/gpio-fns.h>
-
- #ifdef CONFIG_CPU_S3C24XX
- #define S3C_GPIO_END (S3C2410_GPIO_BANKJ + 32)
- #else
- #define S3C_GPIO_END (S3C2410_GPIO_BANKH + 32)
- #endif
include/asm-generic/gpio.h,这个文件的内容不完全列出来。该文件涉及到了一个宏:CONFIG_GPIOLIB。会对GPIO接口函数的实现产生影响。
- #include <linux/kernel.h>
-
- #include <linux/types.h>
-
- #include <linux/errno.h>
-
- #ifdef CONFIG_GPIOLIB
- #include <linux/compiler.h>
- /* Platforms may implement their GPIO interface with library code,
- * at a small performance cost for non-inlined operations and some
- * extra memory (for code and for per-GPIO table entries).
- *
- * While the GPIO programming interface defines valid GPIO numbers
-
- * to be in the range 0..MAX_INT, this library restricts them to the
-
- * smaller range 0..ARCH_NR_GPIOS-1.
-
- */
-
-
- #ifndef ARCH_NR_GPIOS
- #define ARCH_NR_GPIOS 256
- #endif
-
- static inline int gpio_is_valid(int number) ----用于判断GPIO号是否可用。
- {
- /* only some non-negative numbers are valid */
- return ((unsigned)number) < ARCH_NR_GPIOS;
- }
-
- struct device;
- struct seq_file;
- struct module;
- .......
- 一些函数声明,宏定义。
- .......
- #else /* !CONFIG_HAVE_GPIO_LIB */
- static inline int gpio_is_valid(int number)
- {
- /* only non-negative numbers are valid */
- return number >= 0;
- }
- /* platforms that don't directly support access to GPIOs through I2C, SPI,
- * or other blocking infrastructure can use these wrappers.
- */
- static inline int gpio_cansleep(unsigned gpio)
- {
- return 0;
- }
- static inline int gpio_get_value_cansleep(unsigned gpio)
- {
- might_sleep();
- return gpio_get_value(gpio);
- }
- static inline void gpio_set_value_cansleep(unsigned gpio, int value)
- {
- might_sleep();
- gpio_set_value(gpio, value);
- }
- #endif /* !CONFIG_HAVE_GPIO_LIB */