linux驱动之gpio2

转载 2012年03月23日 10:34:48

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 */

33 全志GPIO口的脚本配置及超声波测距模块的linux驱动

linux内核有gpiolib标准的gpio操作接口. 但这套接口只能配置输入,输出,获取或设置IO口的电平. 但GPIO口是多功能, 还有上/下拉功能. 全志的GPIO额外的配置在script.b...
  • jklinux
  • jklinux
  • 2017年06月19日 10:50
  • 759

Android下led控制(下)--Linux驱动部分--script与gpio(全志)

前面写了三篇关于全志CQA83T下Android控制led的博文,但是还是有很多东西可以学习,可以写写作为学习记录。如果看源码,绕不过script这个东西,这个不是像其他系统脚本一样,这里的scrip...

迅为4412开发板Linux驱动教程之GPIO的初始化

迅为4412开发板Linux驱动教程之GPIO的初始化

linux驱动:TI+DM8127+GPIO(五)之plarform

五、【GPIO驱动框架》平台platform】 (一)设备找驱动 1、drivers/base/platform.c中 int platform_device_register(structpl...

Linux驱动子系统之输入子系统(6)-gpio-keys

6.Gpio-keys 6.1 概述 l  Gpio-keys是基于input子系统实现的一个通用的GPIO按键驱动。工程中我们常常会利用它来写按键驱动。   l  gpio-...

我的第一个linux驱动-s3c6410 gpio

前段时间学着写了第一个linux下的驱动,很简单,基于友善之臂的tiny6410,通过控制GPIOK4-7输入输出来控制板上的4个led。led的驱动友善已经提供,不过我自己写的有些不一样,是按照标准...
  • cokewei
  • cokewei
  • 2011年03月28日 11:40
  • 3775

【龙印】龙芯1c的gpio作为输入时的linux驱动

本文为在用龙芯1c做3D打印机过程中的笔记。龙芯1c做的3d打印机简称“龙印”,交流论坛地址是“http://www.openloongson.org/” 和GPIO作为输出一样,作为输入也经常用到。...
  • caogos
  • caogos
  • 2016年09月01日 16:26
  • 551

linux驱动:TI+DM8127+GPIO(四)之设备

四、【GPIO驱动框架》设备device】 arch/arm/mach-omap2/gpio.c中 1、static int __init omap2_gpio_init(void) {   ...

开发板上使用GPIO向电磁继电器发送高低电平控制台灯亮灭(我的第一个linux驱动程序开发)

开发板:tiny6410 虚拟机:Fedora 9 本驱动程序是根据tiny6410 开发文档中LED灯驱动程序改写,由于第一次接触驱动程序开发,第一次这么直接的操作硬件, 所以难免会有不...

linux驱动:设备-总线-驱动(以TI+DM8127中GPIO为例)

一:说明:这次学习设备-总线-驱动是以TI+DM8127的GPIO为例 1、GPIO资源注册到omap_hwmod链表中 2、初始化GPIO 3、将GPIO注册到plarform层 4、将GPIO注册...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux驱动之gpio2
举报原因:
原因补充:

(最多只允许输入30个字)