【Linux基础系列之】gpio系统

本文深入探讨Linux GPIO系统,包括GPIO初始化、GPIO API(新旧版本)的使用,以及GPIO如何作为中断控制器。重点讲解了gpiochip_add()函数的作用,GPIO descriptor-based API的操作,如gpiod_request()和gpiod_set_value(),并阐述了GPIO与中断的结合,以及中断控制器的注册。
摘要由CSDN通过智能技术生成

  上一章介绍了pinctrl系统管理所有的物理pin脚,gpio也是pin脚的一种,所以需要某个gpio的时候就需要通过pinctrl把某个pin脚设置为gpio功能就即可;在pinctrl系统提供了操作pin脚的统一API接口,同时也可以用gpio的API来操作,在request gpio表明该pin没有被挪为他用之后,就可以设置该GPIO的输入输出,驱动能力,或者debounce功能等;


(一) GPIO 初始化

  pinctrl有讲到一个pinctrl可以管理着个gpio range链表,每个node管理着一定范围内的gpio,可以叫作gpio bank,我们把它实例话成一个设备,用gpio_chip来表示,下面为各个结构关系图:

这里写图片描述

通过gpiochip_add()将gpio chip添加到gpio子系统中:

 299 int gpiochip_add(struct gpio_chip *chip)
 300 {
 301     unsigned long   flags;
 302     int     status = 0;
 303     unsigned    id;
 304     int     base = chip->base; //这个chip处理的第一个gpio number;
 305     struct gpio_desc *descs;
 306 
 307     descs = kcalloc(chip->ngpio, sizeof(descs[0]), GFP_KERNEL);
 308     if (!descs)
 309         return -ENOMEM;
 310 
 311     spin_lock_irqsave(&gpio_lock, flags);
 312 
 313     if (base < 0) { 
 //如果没有指定base,那么需要基于该chip的gpio数量在系统支持的gpio范围里找一段区间给该chip;
 //一般平台默认为512个gpio,通过扫描gpio_chips全局chip链表,分配一段free的gpio空间;
 314         base = gpiochip_find_base(chip->ngpio); //ngpio为该chip处理的gpio个数;
 315         if (base < 0) {
 316             status = base;
 317             spin_unlock_irqrestore(&gpio_lock, flags);
 318             goto err_free_descs;
 319         }
 320         chip->base = base;
 321     }
 322  //到这里的时候,说明一切正常,把它加入到全局的gpiochip链表中去,注意,加入的时候会基于base排序;
 323     status = gpiochip_add_to_list(chip);
 324     if (status) {
 325         spin_unlock_irqrestore(&gpio_lock, flags);
 326         goto err_free_descs;
 327     }
 328     //如果加入成功,最后一步就是初始化该chip对应的那些gpio了;
 329     for (id = 0; id < chip->ngpio; id++) {
 330         struct gpio_desc *desc = &descs[id]; //每个gpio分配一个gpio_desc来描述;
 331 
 332         desc->chip = chip;
 333         //默认指定为输入为好,考虑到大多数情况下推挽式输出,防止漏电;
 340         desc->flags = !chip->direction_input ? (1 << FLAG_IS_OUT) : 0;
 341     }
 342 
 343     chip->desc = descs;
 344 
 345     spin_unlock_irqrestore(&gpio_lock, flags);
 346 
 347 #ifdef CONFIG_PINCTRL
 348     INIT_LIST_HEAD(&chip->pin_ranges);
 349 #endif
 350 
 351     if (!chip->owner && chip->dev && chip->dev->driver)
 352         chip->owner = chip->dev->driver->owner;
 353 
 354     status = gpiochip_set_desc_names(chip);
 355     if (status)
 356         goto err_remove_from_list;
 357 
 358     status = of_gpiochip_add(chip); // 初始化设备树相关的信息;
 359     if (status)
 360         goto err_remove_chip;
 361     //添加chip到ACPI(Advanced Configuration & Power Interface.)
 362     acpi_gpiochip_add(chip);
 363 
 364     status = gpiochip_sysfs_register(chip);// 将该gpiochip导出到sys,用于调试和应用层直接操作;
 372     return 0;
 373 
 391 }
 392 EXPORT_SYMBOL_GPL(gpiochip_add);
422 int of_gpiochip_add(struct gpio_chip 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值