Chinaunix首页 | 论坛 | 博客
  • 博客访问: 734318
  • 博文数量: 77
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1173
  • 用 户 组: 普通用户
  • 注册时间: 2014-05-16 11:20
个人简介

将技术做到极致...

文章分类

全部博文(77)

文章存档

2019年(3)

2015年(27)

2014年(47)

分类: LINUX

2019-04-17 15:33:43

原文地址:GPIO的驱动模型 作者:wangbaolin719


  1. 一、概述
  2. GPIO是嵌入式系统最简单、最常用的资源了,比如点亮LED,控制蜂鸣器,输出高低电平,检测按键,等等。GPIO分输入和输出,在davinci linux中,有关GPIO的最底层的寄存器驱动,\arch\arm\mach-davinci目录下的gpio.c,这个是寄存器级的驱动,搞过单片机MCU的朋友应该比较熟悉寄存器级的驱动。

  3. GPIO的驱动主要就是读取GPIO口的状态,或者设置GPIO口的状态。就是这么简单,但是为了能够写好的这个驱动,在LINUX上作了一些软件上的分层。为了让其它驱动可以方便的操作到GPIO,在LINUX里实现了对GPIO操作的统一接口,这个接口实则上就是GPIO驱动的框架,具体的实现文件为gpiolib.c在配置内核的时候,我们必须使用CONFIG_GENERIC_GPIO这个宏来支持GPIO驱动。

  4. GPIO是与硬件体系密切相关的,linux提供一个模型来让驱动统一处理GPIO,即各个板卡都有实现自己的gpio_chip控制模块:request, free, input,output, get,set,irq...然后把控制模块注册到内核中,这时会改变全局gpio数组:gpio_desc[]. 当用户请求gpio时,就会到这个数组中找到,并调用这个GPIO对应的gpio_chip的处理函数。gpio实现为一组可用的 gpio_chip, 由驱动传入对应 gpio的全局序号去 request, dataout ,datain, free. 这时会调用gpio_chip中具体的实现。
  5. gpio是一组可控件的脚,由多个寄存器同时控制。通过设置对应的寄存器可以达到设置GPIO口对应状态与功能。数据状态,输入输出方向,清零,中断(那个边沿触发), 一般是一组(bank)一组的。
  6. 寄存器读写函数: __raw_writel() __raw_writeb() __raw_readl() __raw_readb()

  7. 二、linux 中GPIO模型的结构
  8. //表示一个gpio口,含对应的gpio_chip.
  9. //对于每一个gpio,都有一个gpio描述符,这个描述符包含了这个gpio所属的控制器即chip和一些标志,label等
  10. struct gpio_desc {
  11.     struct gpio_chip    *chip;
  12.     unsigned long    flags;
  13.     /* flag symbols are bit numbers */
  14.     #define FLAG_REQUESTED 0
  15.     #define FLAG_IS_OUT 1
  16.     #define FLAG_RESERVED 2
  17.     #define FLAG_EXPORT 3 /* protected by sysfs_lock */
  18.     #define FLAG_SYSFS 4 /* exported via /sys/class/gpio/control */
  19.     #define FLAG_TRIG_FALL 5 /* trigger on falling edge */
  20.     #define FLAG_TRIG_RISE 6 /* trigger on rising edge */
  21.     #define FLAG_ACTIVE_LOW 7 /* sysfs value has active low */
  22.     #define FLAG_OPEN_DRAIN 8 /* Gpio is open drain type */
  23.     #define FLAG_OPEN_SOURCE 9 /* Gpio is open source type */
  24.     
  25.     #define ID_SHIFT 16 /* add new flags before this one */
  26.     #define GPIO_FLAGS_MASK ((1 << ID_SHIFT) - 1)
  27.     #define GPIO_TRIGGER_MASK (BIT(FLAG_TRIG_FALL) | BIT(FLAG_TRIG_RISE))
  28.  
  29. #ifdef CONFIG_DEBUG_FS
  30.     const char    *label;
  31. #endif
  32. };
  33. //采用了一个具有ARCH_NR_GPIOS大小的gpio描述符数组。这个描述符数组便代表了系统所有的gpio。
  34. static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];//ARCH_NR_GPIOS=144,即系统现在有144个GPIO口

  35. //static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];//将144个GPIO分成每32个一组
  36. //一组GPIO控制器结构,例如GPIO0和GPIO1是一组(共32个GPIO口),共用一组寄存器,所以GPIO0和GPIO1荷载一起用chips[0]来控制
  37. ///共有144个GPIO,分为4组(GPIO0~GPIO8),每组有2个banks(即GPIO0和GPIO1为1组),每组最多可以有32个GPIO,每组的控制寄存器空间有10个。
  38. struct davinci_gpio_controller {
  39.     struct gpio_chip    chip;//每组对应的gpio_chip
  40.     int            irq_base;//每组对应的中断
  41.     spinlock_t        lock;//自旋锁
  42.     void __iomem        *regs;//每组的寄存器地址
  43.     void __iomem        *set_data;//设置数据寄存器地址
  44.     void __iomem        *clr_data;//清除数据寄存器地址
  45.     void __iomem        *in_data;//输入数据寄存器地址
  46. };

  47. //每一个davinci_gpio_controller结构都对应于一个gpio_chip结构,gpio_chip既可看成是davinci_gpio_controller结构的补充
  48. //表示一个gpio controller.通过这个结构抽象化所有的GPIO源,而让板上其它的模块可以用相同的接口调用使用这些GPIO。
  49. struct gpio_chip {
  50.     const char    *label;
  51.     struct device    *dev;
  52.     struct module    *owner;
  53.     int    (*request)(struct gpio_chip *chip,unsigned offset);//请求gpio
  54.     void    *free)(struct gpio_chip *chip,unsigned offset);//释放gpio
  55.     int    (*get_direction)(struct gpio_chip *chip,unsigned offset);
  56.     int    (*direction_input)(struct gpio_chip *chip,unsigned offset);//配置gpio为输入,返回当前gpio状态
  57.     int    (*get)(struct gpio_chip *chip,unsigned offset);//获取gpio的状态
  58.     int    (*direction_output)(struct gpio_chip *chip,unsigned offset, int value);//配置gpio为输出,并设置为value
  59.     int    (*set_debounce)(struct gpio_chip *chip,unsigned offset, unsigned debounce);//设置消抖动时间,尤其是gpio按键时有用
  60.     void    (*set)(struct gpio_chip *chip,unsigned offset, int value);//设置gpio为value值
  61.     int    (*to_irq)(struct gpio_chip *chip,unsigned offset);//把gpio号转换为中断号
  62.     void    (*dbg_show)(struct seq_file *s,struct gpio_chip *chip);
  63.     int    base;// 这个gpio控制器的gpio开始编号
  64.     u16    ngpio;//这个gpio控制器说控制的gpio数
  65.     const char    *const *names;
  66.     unsigned    can_sleep:1;
  67.     unsigned    exported:1;
  68.  
  69. #if defined(CONFIG_OF_GPIO)
  70.     struct device_node *of_node;
  71.     int of_gpio_n_cells;
  72.     int (*of_xlate)(struct gpio_chip *gc,const struct of_phandle_args *gpiospec, u32 *flags);
  73. #endif
  74. #ifdef CONFIG_PINCTRL
  75.     struct list_head pin_ranges;
  76. #endif
  77. };

  78. //GPIO寄存器结构
  79. struct davinci_gpio_regs {
  80.     u32 dir; // gpio方向设置寄存器
  81.     u32 out_data; // gpio设置为输出时,表示输出状态(0或1)
  82.     u32 set_data; // gpio设置为输出时,用于输出高电平
  83.     u32 clr_data; // gpio设置为输出时,用于输出低电平
  84.     u32 in_data; // gpio设置为输入时,用于读取输入值
  85.     u32 set_rising; // gpio中断上升沿触发设置
  86.     u32 clr_rising; // gpio中断上升沿触发清除
  87.     u32 set_falling; // gpio中断下降沿触发设置
  88.     u32 clr_falling; // gpio中断下降沿触发清除
  89.     u32 intstat; // gpio中断状态位,由硬件设置,可读取,写1时清除。
  90. };

  91. struct gpio {
  92.     unsigned gpio;//gpio号
  93.     unsigned long flags;//gpio标志
  94.     const char *label;//gpio名
  95. };

  96. 三、GPIO的初始化
  97. 1.首先设置GPIO的管脚复用寄存器
  98. static __init void da850_evm_init(void)
  99. {
  100.     //.......
  101.     ret = davinci_cfg_reg_list(da850_gpio_test_pins);
  102.     if (ret)
  103.         pr_warning("da850_evm_init: gpio test ping mux setup failed: %d\n", ret);
  104.     //.......
  105. }

  106. 2.根据板级结构的资源初始化chips数组,此函数在系统初始化时自动调用
  107. static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];//将144个GPIO分成每32个一组
  108. static int __init davinci_gpio_setup(void)
  109. {
  110.     int i, base;
  111.     unsigned ngpio;
  112.     struct davinci_soc_info *soc_info = &davinci_soc_info;//板级资源结构
  113.     struct davinci_gpio_regs *regs;

  114.     if (soc_info->gpio_type != GPIO_TYPE_DAVINCI)//判断GPIO类型
  115.         return 0;

  116.     ngpio = soc_info->gpio_num;//GPIO数量144
  117.     if (ngpio == 0) {
  118.         pr_err("GPIO setup: how many GPIOs?\n");
  119.         return -EINVAL;
  120.     }

  121.     if (WARN_ON(DAVINCI_N_GPIO < ngpio))//DAVINCI_N_GPIO=144
  122.         ngpio = DAVINCI_N_GPIO;

  123.     gpio_base = ioremap(soc_info->gpio_base, SZ_4K);//将GPIO的寄存器物理基地址(#define DA8XX_GPIO_BASE        0x01e26000)映射到内存中
  124.     if (WARN_ON(!gpio_base))
  125.         return -ENOMEM;
  126.     
  127.     //共有144个GPIO,分为4组(GPIO0~GPIO8),每组有2个banks(即GPIO0和GPIO1为1组),每组最多可以有32个GPIO,每组的控制寄存器空间有10个。
  128.     //chips[0]--chips[4],base值为0,32,64,96,128,ngpio分别为:32,32,32,32,16
  129.     for (i = 0, base = 0; base < ngpio; i++, base += 32) {
  130.         chips[i].chip.label = "DaVinci";
  131.         //设置操作函数
  132.         chips[i].chip.direction_input = davinci_direction_in;
  133.         chips[i].chip.get = davinci_gpio_get;
  134.         chips[i].chip.direction_output = davinci_direction_out;
  135.         chips[i].chip.set = davinci_gpio_set;

  136.         chips[i].chip.base = base;//每一组开始的GPIO号
  137.         //每组控制的GPIO个数,一般为32个
  138.         chips[i].chip.ngpio = ngpio - base;
  139.         if (chips[i].chip.ngpio > 32)
  140.             chips[i].chip.ngpio = 32;

  141.         spin_lock_init(&chips[i].lock);
  142.         //找到这组GPIO的寄存器地址,初始化chips结构
  143.         regs = gpio2regs(base);
  144.         chips[i].regs = regs;//设置每组的寄存器
  145.         chips[i].set_data = ?s->set_data;
  146.         chips[i].clr_data = ?s->clr_data;
  147.         chips[i].in_data = ?s->in_data;
  148.         
  149.         gpiochip_add(&chips[i].chip);//注册gpio_chip
  150.     }
  151.     //chips数组添加到板级资源中
  152.     soc_info->gpio_ctlrs = chips;
  153.     soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32);

  154.     davinci_gpio_irq_setup();//设置GPIO中断
  155.     return 0;
  156. }
  157. pure_initcall(davinci_gpio_setup);//linux初始化时会自动调用

  158. static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio)
  159. {
  160.     void __iomem *ptr;
  161.     
  162.     //根据GPIO的基地址累加,其中基地址(gpio_base+0)是REVID(Revision ID Register)寄存器
  163.     //(gpio_base+8)是BINTEN (GPIO Interrupt Per-Bank Enable Register)寄存器
  164.     //所以第一组寄存器从基地址+0x10开始
  165.     if (gpio < 32 * 1)
  166.         ptr = gpio_base + 0x10;
  167.     else if (gpio < 32 * 2)
  168.         ptr = gpio_base + 0x38;
  169.     else if (gpio < 32 * 3)
  170.         ptr = gpio_base + 0x60;
  171.     else if (gpio < 32 * 4)
  172.         ptr = gpio_base + 0x88;
  173.     else if (gpio < 32 * 5)
  174.         ptr = gpio_base + 0xb0;
  175.     else
  176.         ptr = NULL;
  177.     return ptr;
  178. }

  179. int gpiochip_add(struct gpio_chip *chip)
  180. {
  181.     unsigned long    flags;
  182.     int        status = 0;
  183.     unsigned    id;
  184.     int        base = chip->base;
  185.     
  186.     //检测gpio的有效性,判断这组GPIO的起始号是否在有效范围内
  187.     if ((!gpio_is_valid(base) || !gpio_is_valid(base + chip->ngpio - 1))&& base >= 0) {
  188.         status = -EINVAL;
  189.         goto fail;
  190.     }

  191.     spin_lock_irqsave(&gpio_lock, flags);
  192.     
  193.     //如果这组GPIO的起始号小于0,则动态的分配gpio的开始索引。
  194.     if (base < 0) {
  195.         base = gpiochip_find_base(chip->ngpio);//这个函数在gpiolib.c中,在gpio_desc[]中分配chip->ngpio个空间(从最后往前分配),返回第一个index
  196.         if (base < 0) {
  197.             status = base;
  198.             goto unlock;
  199.         }
  200.         chip->base = base;
  201.     }

  202.     //确保这些分配的gpio号没有被其他chip占用
  203.     for (id = base; id < base + chip->ngpio; id++) {
  204.         if (gpio_desc[id].chip != NULL) {
  205.             status = -EBUSY;
  206.             break;
  207.         }
  208.     }
  209.     //填充gpio_desc,将该组内的每个GPIO口的gpio_desc结构和该组的控制结构chip联系起来
  210.     if (status == 0) {
  211.         for (id = base; id < base + chip->ngpio; id++) {
  212.             gpio_desc[id].chip = chip;
  213.             gpio_desc[id].flags = !chip->direction_input? (1 << FLAG_IS_OUT): 0;//设置GPIO口标志
  214.         }
  215.     }
  216.     of_gpiochip_add(chip);

  217. unlock:
  218.     spin_unlock_irqrestore(&gpio_lock, flags);

  219.     if (status)
  220.         goto fail;

  221.     status = gpiochip_export(chip);//与sysfs文件系统有关,这里不关心
  222.     if (status)
  223.         goto fail;

  224.     return 0;
  225. fail:
  226.     /* failures here can mean systems won't boot... */
  227.     pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n",chip->base, chip->base + chip->ngpio - 1,chip->label ? : "generic");
  228.     return status;
  229. }

  230. .gpio的申请
  231. //所谓申请就是检测GPIO描述符desc->flags的FLAG_REQUESTED标志,已申请的话该标志是1,否则是0
  232. //往往多个gpio作为一个数组来进行申请
  233. int gpio_request_array(struct gpio *array, size_t num)
  234. {
  235.     int i, err;

  236.     for (i = 0; i < num; i++, array++) {//遍历数组中的每一个GPIO,gpio是GPIO号,flags是输入输出标志等,label是其取一个名字
  237.         err = gpio_request_one(array->gpio, array->flags, array->label);
  238.         if (err)
  239.             goto err_free;
  240.     }
  241.     return 0;

  242. err_free:
  243.     while (i--)
  244.         gpio_free((--array)->gpio);
  245.     return err;
  246. }

  247. int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
  248. {
  249.     int err;
  250.     
  251.     //gpio则为你要申请的哪一个管脚,label则是为其取一个名字。
  252.     err = gpio_request(gpio, label);
  253.     if (err)
  254.         return err;

  255.     if (flags & GPIOF_DIR_IN)//GPIO标志是输入
  256.         err = gpio_direction_input(gpio);//设置管脚为输入
  257.     else//GPIO标志是输出
  258.         err = gpio_direction_output(gpio,(flags & GPIOF_INIT_HIGH) ? 1 : 0);//根据标志确定输出1还是0

  259.     if (err)
  260.         gpio_free(gpio);

  261.     return err;
  262. }

  263. int gpio_request(unsigned gpio, const char *label)
  264. {
  265.     struct gpio_desc    *desc;
  266.     struct gpio_chip    *chip;
  267.     int            status = -EINVAL;
  268.     unsigned long        flags;
  269.     //屏蔽中断
  270.     spin_lock_irqsave(&gpio_lock, flags);

  271.     if (!gpio_is_valid(gpio))//判断是否有效,也就是参数的取值范围判断
  272.         goto done;
  273.         
  274.     //根据GPIO号找到对应的GPIO描述符结构
  275.     desc = &gpio_desc[gpio];
  276.     chip = desc->chip;//找到该GPIO所在的组控制器
  277.     if (chip == NULL)
  278.         goto done;
  279.         
  280.     //计数加1
  281.     if (!try_module_get(chip->owner))
  282.         goto done;

  283.     //这里测试并设置flags的第FLAG_REQUESTED位,如果没有被申请就返回该位的原值0
  284.     if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
  285.         desc_set_label(desc, label ? : "?");//设置GPIO描述符结构desc的label字段
  286.         status = 0;
  287.     } else {
  288.         status = -EBUSY;
  289.         module_put(chip->owner);
  290.         goto done;
  291.     }

  292.     if (chip->request) {/* chip->request may sleep */
  293.         spin_unlock_irqrestore(&gpio_lock, flags);
  294.         status = chip->request(chip, gpio - chip->base);
  295.         spin_lock_irqsave(&gpio_lock, flags);

  296.         if (status < 0) {
  297.             desc_set_label(desc, NULL);
  298.             module_put(chip->owner);
  299.             clear_bit(FLAG_REQUESTED, &desc->flags);
  300.         }
  301.     }

  302. done:
  303.     if (status)
  304.         pr_debug("gpio_request: gpio-%d (%s) status %d\n",gpio, label ? : "?", status);
  305.     spin_unlock_irqrestore(&gpio_lock, flags);
  306.     return status;
  307. }

  308. .GPIO的操作
  309. 1.设置GPIO为输出或输入
  310. int gpio_direction_input(unsigned gpio)
  311. {
  312.     unsigned long        flags;
  313.     struct gpio_chip    *chip;
  314.     struct gpio_desc    *desc = &gpio_desc[gpio];
  315.     int            status = -EINVAL;

  316.     spin_lock_irqsave(&gpio_lock, flags);
  317.     
  318.     //判断GPIO号是否有效
  319.     if (!gpio_is_valid(gpio))
  320.         goto fail;
  321.     //找到GPIO对应的gpio_chip结构
  322.     chip = desc->chip;
  323.     if (!chip || !chip->get || !chip->direction_input)
  324.         goto fail;
  325.     
  326.     //确保此GPIO是在此组内,chip->base是此组GPIO的起始号,chip->ngpio是此组GPIO的个数
  327.     gpio -= chip->base;
  328.     if (gpio >= chip->ngpio)
  329.         goto fail;
  330.         
  331.     //确保GPIO已申请
  332.     status = gpio_ensure_requested(desc, gpio);
  333.     if (status < 0)
  334.         goto fail;

  335.     //到这里可以确保GPIO是有效的
  336.     spin_unlock_irqrestore(&gpio_lock, flags);

  337.     might_sleep_if(chip->can_sleep);
  338.     //status=0
  339.     if (status) {
  340.         status = chip->request(chip, gpio);
  341.         if (status < 0) {
  342.             pr_debug("GPIO-%d: chip request fail, %d\n",chip->base + gpio, status);
  343.             goto lose;
  344.         }
  345.     }
  346.     //调用底层的已经设置过的操作,这里即davinci_direction_in
  347.     status = chip->direction_input(chip, gpio);
  348.     if (status == 0)//返回成功
  349.         clear_bit(FLAG_IS_OUT, &desc->flags);//清除输出标志
  350. lose:
  351.     return status;
  352. fail:
  353.     spin_unlock_irqrestore(&gpio_lock, flags);
  354.     if (status)
  355.         pr_debug("%s: gpio-%d status %d\n",__func__, gpio, status);
  356.     return status;
  357. }

  358. int gpio_direction_output(unsigned gpio, int value)
  359. {
  360.     //.........GPIO的检查,同上函数
  361.     
  362.     //调用底层的已经设置过的操作,这里即davinci_direction_out
  363.     status = chip->direction_output(chip, gpio, value);
  364.     if (status == 0)//返回成功
  365.         set_bit(FLAG_IS_OUT, &desc->flags);//设置输出标志
  366. lose:
  367.     return status;
  368. fail:
  369.     spin_unlock_irqrestore(&gpio_lock, flags);
  370.     if (status)
  371.         pr_debug("%s: gpio-%d status %d\n",__func__, gpio, status);
  372.     return status;
  373. }

  374. //根据前边对gpio_chip结构的初始化,会调用\arch\arm\mach-davinci\gpio.c里的函数
  375. static int davinci_direction_in(struct gpio_chip *chip, unsigned offset)
  376. {
  377.     return __davinci_direction(chip, offset, false, 0);
  378. }

  379. static int davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value)
  380. {
  381.     return __davinci_direction(chip, offset, true, value);
  382. }

  383. static inline int __davinci_direction(struct gpio_chip *chip,unsigned offset, bool out, int value)
  384. {
  385.     struct davinci_gpio_controller *d = chip2controller(chip);
  386.     struct davinci_gpio_regs __iomem *g = d->regs;//找到此组GPIO的控制寄存器地址
  387.     unsigned long flags;
  388.     u32 temp;
  389.     u32 mask = 1 << offset;

  390.     spin_lock_irqsave(&d->lock, flags);
  391.     temp = __raw_readl(&g->dir);//读出当前寄存器的输入输出方向
  392.     
  393.     if (out) {//为1设置输出
  394.         temp &= ~mask;
  395.         __raw_writel(mask, value ? &g->set_data : &g->clr_data);//确定是用于输出高电平还是输出低电平
  396.     }
  397.     else {//为0设置为输入
  398.         temp |= mask;
  399.     }
  400.     __raw_writel(temp, &g->dir);//写入方向寄存器
  401.     spin_unlock_irqrestore(&d->lock, flags);

  402.     return 0;
  403. }

  404. 2.获取gpio的状态
  405. int __gpio_get_value(unsigned gpio)
  406. {
  407.     struct gpio_chip    *chip;

  408.     chip = gpio_to_chip(gpio);
  409.     WARN_ON(chip->can_sleep);
  410.     return chip->get ? chip->get(chip, gpio - chip->base) : 0;//调用davinci_gpio_get
  411. }

  412. static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset)
  413. {
  414.     struct davinci_gpio_controller *d = chip2controller(chip);
  415.     struct davinci_gpio_regs __iomem *g = d->regs;

  416.     return (1 << offset) & __raw_readl(&g->in_data);
  417. }

  418. 3.设置GPIO的值
  419. void __gpio_set_value(unsigned gpio, int value)
  420. {
  421.     struct gpio_chip    *chip;

  422.     chip = gpio_to_chip(gpio);
  423.     WARN_ON(chip->can_sleep);
  424.     chip->set(chip, gpio - chip->base, value);//调用davinci_gpio_set
  425. }

  426. static void davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
  427. {
  428.     struct davinci_gpio_controller *d = chip2controller(chip);
  429.     struct davinci_gpio_regs __iomem *g = d->regs;

  430.     __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data);
  431. }

  432. 六、GPIO驱动编写
  433. 1.首先要申请GPIO口
  434. 2.注册设备
  435. 3.创建GPIO的sysfs相关文件
  436. #define GPIO_MAJOR 199         // major device NO.
  437. #define GPIO_MINOR 0         // minor device NO.
  438. #define DEVICE_NAME "omapl138_gpios" /*定义设备驱动的名字,或设备节点名称*/

  439. #define SET_OUTPUT_LOW 0
  440. #define SET_OUTPUT_HIGH 1
  441. #define GET_VALUE 2
  442. #define SET_INPUT 3

  443. static struct class *gpio_class;
  444. static struct gpio gpio_array[] =
  445. {
  446.     /*{ GPIO_TO_PIN(0, 0), GPIOF_OUT_INIT_LOW,     "RTU_WDI_SIGNAL" },will request fail*/
  447.     { GPIO_TO_PIN(0, 1), GPIOF_OUT_INIT_HIGH, "RTU_PLC_BAK_IO1"},
  448.     { GPIO_TO_PIN(0, 2), GPIOF_OUT_INIT_LOW,     "RTU_CHG_EN" },
  449.     { GPIO_TO_PIN(0, 3), GPIOF_IN,         "RTU_CHG_PG" },
  450.     { GPIO_TO_PIN(0, 5), GPIOF_IN,         "RTU_USB_OC_OUT" },
  451.     { GPIO_TO_PIN(0, 6), GPIOF_OUT_INIT_LOW,     "RTU_RUN_IND_LED" },
  452.     { GPIO_TO_PIN(1, 10), GPIOF_IN,         "RTU_TSC_BUSY"},
  453.     { GPIO_TO_PIN(1, 11), GPIOF_IN,        "RTU_PENIRQn" },
  454.     { GPIO_TO_PIN(1, 12), GPIOF_OUT_INIT_LOW, "RTU_uP_Q26x_RESET" },
  455.     { GPIO_TO_PIN(1, 13), GPIOF_OUT_INIT_HIGH, "RTU_uP_GPRS_PWR_EN" },
  456.     { GPIO_TO_PIN(1, 14), GPIOF_OUT_INIT_HIGH, "RTU_uP_Q26x_ON/OFF" },
  457.     { GPIO_TO_PIN(2, 1), GPIOF_OUT_INIT_LOW, "RTU_PLC_Reset" },
  458.     { GPIO_TO_PIN(2, 2), GPIOF_OUT_INIT_LOW, "RTU_PLC_T_Reg" },
  459.     { GPIO_TO_PIN(2, 4), GPIOF_OUT_INIT_LOW, "RTU_PLC_BAK_IO2" },
  460.     { GPIO_TO_PIN(2, 5), GPIOF_OUT_INIT_LOW, "RTU_RS485_RE" },
  461.     { GPIO_TO_PIN(2, 15), GPIOF_OUT_INIT_HIGH, "RTU_CHPWR_CS" },
  462.     { GPIO_TO_PIN(3, 9), GPIOF_OUT_INIT_HIGH, "RTU_RS485_DE" },
  463.     { GPIO_TO_PIN(6, 1), GPIOF_OUT_INIT_HIGH, "RTU_uP_VPIF_CLKO3" },
  464.     { GPIO_TO_PIN(6, 9), GPIOF_IN,         "RTU_KEY_IN2" },
  465.     { GPIO_TO_PIN(6, 11), GPIOF_IN,        "RTU_ALARM_IN5" },
  466.     { GPIO_TO_PIN(6, 15), GPIOF_OUT_INIT_HIGH,"RTU_uP_RESETOUTn" },
  467. };

  468. static int gpio_open(struct inode *inode,struct file *file)
  469. {
  470.     printk(KERN_WARNING"gpio open success!\n");
  471.     return 0;
  472. }

  473. static int gpio_release(struct inode *inode, struct file *filp)
  474. {
  475.   printk (KERN_ALERT "Device gpio released\n");
  476.   return 0;
  477. }

  478. static int gpio_read(struct file*f,char *dst,size_t size,loff_t*offset)
  479. {
  480.     unsigned char num;
  481.     __copy_to_user(&num,dst,1);
  482. #ifdef DEBUG
  483.      printk("__copy_to_user:%d\n",num);
  484. #endif

  485.     return 0;
  486. }

  487. static int gpio_write(struct file*f,const char *src,size_t size,loff_t *offset)
  488. {
  489.      unsigned char num;
  490.      __copy_from_user(&num,src,1);
  491. #ifdef DEBUG
  492.      printk("__copy_from_user:%d\n",num);
  493. #endif
  494.      return 0;

  495. }

  496. static long gpio_ioctl(struct file *file,unsigned int cmd,unsigned long gpio)
  497. {
  498.     int i;
  499.     unsigned long gpio_num = (gpio/100)*16+gpio%100;
  500.     for (i = 0; i < ARRAY_SIZE(gpio_array); i++) {
  501.         if(gpio_array[i].gpio == gpio_num)
  502.             goto valid_gpio;
  503.     }
  504.     return -1;
  505.         
  506. valid_gpio:
  507.     switch(cmd)//cmd表示应用程序传入的 GPIO 动作
  508.     {
  509.         case SET_OUTPUT_LOW://0
  510.         {
  511.             gpio_direction_output(gpio_num, 0);
  512.             break;
  513.         }
  514.         case SET_OUTPUT_HIGH://1
  515.         {
  516.             gpio_direction_output(gpio_num, 1);
  517.             break;
  518.         }
  519.         case GET_VALUE://2
  520.         {
  521.             return gpio_get_value(gpio_num);    
  522.         }
  523.         case SET_INPUT://3
  524.         {
  525.             gpio_direction_input(gpio_num);
  526.             break;
  527.         }
  528.         default:
  529.         {
  530.             printk(KERN_EMERG "GPIO command mistake!!!\n");
  531.             break;
  532.         }
  533.     }
  534.     return 0;
  535. }
  536.         
  537. static const struct file_operations gpio_fops =
  538. {
  539.   .owner = THIS_MODULE,
  540.   .open = gpio_open,
  541.   .release = gpio_release,
  542.   .read = gpio_read,
  543.   .write = gpio_write,
  544.   .unlocked_ioctl = gpio_ioctl,
  545. };

  546. static int __init gpio_init(void) /*内核初始化会调用该函数*/
  547. {
  548.     int ret;
  549.     
  550.     ret = gpio_request_array(gpio_array, ARRAY_SIZE(gpio_array));
  551.     if (ret < 0)
  552.     {
  553.         printk(KERN_EMERG "GPIO request failed\n");
  554.         goto request_failed;
  555.     }
  556.     
  557.     dev_t my_dev_no;
  558.     struct cdev *gpio_cdev;
  559.     gpio_cdev = cdev_alloc();
  560.     if(gpio_cdev == NULL)
  561.     {
  562.         printk(KERN_EMERG "Cannot alloc cdev\n");
  563.         goto request_failed;
  564.     }
  565.     cdev_init(gpio_cdev,&gpio_fops);
  566.     gpio_cdev->owner=THIS_MODULE;
  567.     int result=alloc_chrdev_region(&my_dev_no,0,1,DEVICE_NAME);
  568.     if(result < 0)
  569.     {
  570.         printk(KERN_EMERG "alloc_chrdev_region failed\n");
  571.         goto request_failed;
  572.     }
  573.     ret=cdev_add(gpio_cdev,my_dev_no,1);
  574.     
  575.     
  576.   ret = register_chrdev(GPIO_MAJOR, DEVICE_NAME, &gpio_fops);//驱动字符设备
  577.      if(ret < 0)
  578.      {
  579.     printk(KERN_EMERG "GPIO register failed\n");
  580.     goto request_failed;
  581.      }
  582.     
  583.     //在sysfs文件系统下创建一个类
  584.   gpio_class = class_create(THIS_MODULE, DEVICE_NAME);
  585.   //device_create-->device_create_vargs-->device_register创建相应的sysfs文件(如dev文件),用于udev根据sysfs文件系统下的dev文件创建设备节点
  586.     device_create(gpio_class, NULL, MKDEV(GPIO_MAJOR, GPIO_MINOR), NULL, DEVICE_NAME);
  587.     return ret;
  588.     
  589. request_failed:
  590.     gpio_free_array(gpio_array, ARRAY_SIZE(gpio_array));
  591.     return ret;
  592. }

  593. static void __exit gpio_exit(void)
  594. {
  595.     device_destroy(gpio_class, MKDEV(GPIO_MAJOR, GPIO_MINOR));
  596.   class_unregister(gpio_class);
  597.   class_destroy(gpio_class);
  598.   unregister_chrdev(GPIO_MAJOR, DEVICE_NAME);
  599. }

  600. module_init(gpio_init);
  601. module_exit(gpio_exit);
  602. MODULE_LICENSE("GPL");
  603. MODULE_VERSION ("v2.0");
  604. MODULE_AUTHOR("wbl <>");
  605. MODULE_DESCRIPTION("OMAPL138 GPIO driver");


阅读(2879) | 评论(0) | 转发(0) |
0

上一篇:git从远程A项目的某一分支基础上创建B项目

下一篇:没有了

给主人留下些什么吧!~~