关闭

linux驱动之gpio2

标签: linuxnumbersreturningoutputlinux内核input
407人阅读 评论(0) 收藏 举报
分类:

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>文件。 

标签:  arm  linux  gpio  分类: 驱动笔记
1)说明
为了使得gpio的相关函数,具有更好的可移植性。Linux定义了一套通用的gpio结构和接口函数。如果在linux内核配置选项中,选择GENERIC_GPIO选项,就说明该平台支持通用的GPIO接口。
在Documentation/gpio.txt详细解释gpio的通用结构和相关函数。
2)头文件
在arm架构下,在以下4个地方包含了gpio.h文件。
include/linux/gpio.h
include/asm-generic/gpio.h
arch/arm/include/asm/gpio.h
arch/arm/mach-s3c2410/include/mach/gpio.h
 
这四个头文件的关系如下:
include/linux/gpio.h,包含了arch/arm/include/asm/gpio.h(需要定义CONFIG_GENERIC_GPIO)
  1. #ifndef __LINUX_GPIO_H
  2. #define __LINUX_GPIO_H

  3. /* see Documentation/gpio.txt */

  4. #ifdef CONFIG_GENERIC_GPIO
  5. #include <asm/gpio.h>

  6. #else

  7. #include <linux/kernel.h>
  8. #include <linux/types.h>
  9. #include <linux/errno.h>

  10. struct device;

  11. .......
  12. 实现了一些与GENERIC_GPIO类型的gpio接口函数同样声明的空函数。
  13. .......

  14. #endif

  15. #endif /* __LINUX_GPIO_H */
 
arch/arm/include/asm/gpio.h包含特定平台的gpio.h,例如包含了arch/arm/mach-realview/include/mach/gpio.h。
  1. #ifndef _ARCH_ARM_GPIO_H
  2. #define _ARCH_ARM_GPIO_H

  3. /* not all ARM platforms necessarily support this API ... */
  4. #include <mach/gpio.h>

  5. #endif /* _ARCH_ARM_GPIO_H */
 
 
arch/arm/mach-realview/include/mach/gpio.h,通常又会包含了include/asm-generic/gpio.h。在这个文件中,需要定义一个很重要的宏:ARCH_NR_GPIOS---该平台有多少个GPIO。
  1. /* arch/arm/mach-s3c2410/include/mach/gpio.h
  2.  *
  3.  * Copyright (c) 2008 Simtec Electronics
  4.  *    http://armlinux.simtec.co.uk/
  5.  *    Ben Dooks <ben@simtec.co.uk>
  6.  *
  7.  * S3C2410 - GPIO lib support
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License version 2 as
  11.  * published by the Free Software Foundation.
  12. */

  13. #define gpio_get_value    __gpio_get_value
  14. #define gpio_set_value    __gpio_set_value
  15. #define gpio_cansleep    __gpio_cansleep
  16. #define gpio_to_irq    __gpio_to_irq

  17. /* some boards require extra gpio capacity to support external
  18.  * devices that need GPIO.
  19.  */

  20. #ifdef CONFIG_CPU_S3C244X
  21. #define ARCH_NR_GPIOS    (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)   
  22. #else
  23. #define ARCH_NR_GPIOS    (256 + CONFIG_S3C24XX_GPIO_EXTRA)
  24. #endif

  25. #include <asm-generic/gpio.h>
  26. #include <mach/gpio-nrs.h>
  27. #include <mach/gpio-fns.h>

  28. #ifdef CONFIG_CPU_S3C24XX
  29. #define S3C_GPIO_END    (S3C2410_GPIO_BANKJ + 32)
  30. #else
  31. #define S3C_GPIO_END    (S3C2410_GPIO_BANKH + 32)
  32. #endif

 

include/asm-generic/gpio.h,这个文件的内容不完全列出来。该文件涉及到了一个宏:CONFIG_GPIOLIB。会对GPIO接口函数的实现产生影响。

  1. #include <linux/kernel.h>

  2. #include <linux/types.h>

  3. #include <linux/errno.h>

  4. #ifdef CONFIG_GPIOLIB
  5. #include <linux/compiler.h>
  6. /* Platforms may implement their GPIO interface with library code,
  7.  * at a small performance cost for non-inlined operations and some
  8.  * extra memory (for code and for per-GPIO table entries).
  9.  *
  10.  * While the GPIO programming interface defines valid GPIO numbers

  11.  * to be in the range 0..MAX_INT, this library restricts them to the

  12.  * smaller range 0..ARCH_NR_GPIOS-1.

  13.  */


  14. #ifndef ARCH_NR_GPIOS
  15. #define ARCH_NR_GPIOS 256
  16. #endif

  17. static inline int gpio_is_valid(int number) ----用于判断GPIO号是否可用。
  18. {
  19.     /* only some non-negative numbers are valid */
  20.     return ((unsigned)number) < ARCH_NR_GPIOS;
  21. }

  22. struct device;
  23. struct seq_file;
  24. struct module;
  25. .......
  26. 一些函数声明,宏定义。
  27. .......
  28. #else /* !CONFIG_HAVE_GPIO_LIB */
  29. static inline int gpio_is_valid(int number)
  30. {
  31.  /* only non-negative numbers are valid */
  32.  return number >= 0;
  33. }
  34. /* platforms that don't directly support access to GPIOs through I2C, SPI,
  35.  * or other blocking infrastructure can use these wrappers.
  36.  */
  37. static inline int gpio_cansleep(unsigned gpio)
  38. {
  39.  return 0;
  40. }
  41. static inline int gpio_get_value_cansleep(unsigned gpio)
  42. {
  43.  might_sleep();
  44.  return gpio_get_value(gpio);
  45. }
  46. static inline void gpio_set_value_cansleep(unsigned gpio, int value)
  47. {
  48.  might_sleep();
  49.  gpio_set_value(gpio, value);
  50. }
  51. #endif /* !CONFIG_HAVE_GPIO_LIB */

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:188940次
    • 积分:2492
    • 等级:
    • 排名:第14763名
    • 原创:49篇
    • 转载:53篇
    • 译文:2篇
    • 评论:8条
    最新评论