一、设备树

设备树文件arch\arm\boot\dts\imx6ull.dtsi,如果不知道这个文件。可以从板子上反汇编设备树,通过一些特定的节点找源码文件。

/ {aliases {can0 = &flexcan1;can1 = &flexcan2;ethernet0 = &fec1;ethernet1 = &fec2;gpio0 = &gpio1;gpio1 = &gpio2;gpio2 = &gpio3;gpio3 = &gpio4;gpio4 = &gpio5;//...}gpio1: gpio@0209c000 {compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";reg = <0x0209c000 0x4000>;interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;//两个必须的节点gpio-controller;                  //表明这是一个gpio controller#gpio-cells = <2>;                //表明多少个cell来描述一个引脚interrupt-controller;#interrupt-cells = <2>;};

当解析设备节点中的GPIO信息时,需要用到上面的属性:
比如下面的led-gpios,在#gpio-cells = <2>的情况下,它表示的引脚数量时1.

 myled {compatible = "100ask,leddrv";led-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;};

二、驱动程序

驱动源码在driver/gpio/gpio-mxc.c

2.1 分配gpio_chip

支持的设备列表:

static const struct of_device_id mxc_gpio_dt_ids[] = {{ .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], },{ .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], },{ .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], },{ .compatible = "fsl,imx35-gpio", .data = &mxc_gpio_devtype[IMX35_GPIO], },{ /* sentinel */ }
};

匹配到设备树后,probe函数就被调用:

static int mxc_gpio_probe(struct platform_device *pdev)
{struct device_node *np = pdev->dev.of_node;struct mxc_gpio_port *port;struct resource *iores;int irq_base = 0;int err;mxc_gpio_get_hw(pdev);port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);       //分配了一个mxc_gpio_port结构体//....iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);       //从设备节点中获得寄存器的地址port->base = devm_ioremap_resource(&pdev->dev, iores);           //把物理地址重映射//....port->irq_high = platform_get_irq(pdev, 1);         //获取irq的高位地址port->irq = platform_get_irq(pdev, 0);                      //获得irq的地位地址//....port->clk = devm_clk_get(&pdev->dev, NULL);            //获取gpio的时钟//....err = clk_prepare_enable(port->clk);                           //是能时钟//....err = bgpio_init(&port->gc, &pdev->dev, 4,               //初始化设置,给gpio_chip一些初始化函数port->base + GPIO_PSR,                      //pad status寄存器,得到引脚当前电平port->base + GPIO_DR, NULL,              //数据寄存器port->base + GPIO_GDIR, NULL,            //方向寄存器BGPIOF_READ_OUTPUT_REG_SET);//...port->gc.request = mxc_gpio_request;port->gc.free = mxc_gpio_free;port->gc.parent = &pdev->dev;port->gc.to_irq = mxc_gpio_to_irq;port->gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 :pdev->id * 32;//....err = devm_gpiochip_add_data(&pdev->dev, &port->gc, port);     //注册}

mxc_gpio_port结构体

struct mxc_gpio_port {struct list_head node;struct clk *clk;void __iomem *base;int irq;int irq_high;struct irq_domain *domain;struct gpio_chip gc;               //gpio_chip结构体u32 both_edges;int saved_reg[6];bool gpio_ranges;
};

2.2 设置gpio_chip

int bgpio_init(struct gpio_chip *gc, struct device *dev,unsigned long sz, void __iomem *dat, void __iomem *set,void __iomem *clr, void __iomem *dirout, void __iomem *dirin,unsigned long flags)
{//...ret = bgpio_setup_io(gc, dat, set, clr, flags);          //设置函数写入gpio_chip中的接口//....ret = bgpio_setup_accessors(dev, gc, flags & BGPIOF_BIG_ENDIAN,flags & BGPIOF_BIG_ENDIAN_BYTE_ORDER);           //设置函数//....ret = bgpio_setup_direction(gc, dirout, dirin, flags);     //设置函数//....
}

2.3 注册gpio_chip

int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *chip,void *data)
{ptr = devres_alloc(devm_gpio_chip_release, sizeof(*ptr),GFP_KERNEL);//...ret = gpiochip_add_data(chip, data);//...*ptr = chip;devres_add(dev, ptr);//...
}int gpiochip_add_data(struct gpio_chip *chip, void *data)
{//...gdev = kzalloc(sizeof(*gdev), GFP_KERNEL);       //分配一个gpio_device,用来表示一个gpio device//...设置gdevgdev->dev.bus = &gpio_bus_type;gdev->chip = chip;          //传入的参数chip分配给gpio_device的gpio_chipchip->gpiodev = gdev;if (chip->parent) {gdev->dev.parent = chip->parent;gdev->dev.of_node = chip->parent->of_node;}//....依然时一些设置函数dev_set_name(&gdev->dev, "gpiochip%d", gdev->id);device_initialize(&gdev->dev);dev_set_drvdata(&gdev->dev, gdev);//....gdev->descs = kcalloc(chip->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL); //分配一个gpio_desc数组//....gdev->ngpio = chip->ngpio;gdev->data = data;//....status = gpiodev_add_to_list(gdev);        //把分配好的gpio_device加进系统列表//....
}

IMX6ULL的GPIO驱动源码分析相关推荐

  1. 我的内核学习笔记10:Intel GPIO驱动源码分析

    本文对Intel e3800的GPIO驱动源码进行分析. 一.概述 1.1 内核配置 Intel e3800的GPIO在Linux内核中使用的驱动名为gpio_ich(为了行文方便,将对应的设备称为& ...

  2. LCD驱动源码分析(s3cfb.c)

    1.驱动源码分析大致思路 (1)分析LCD驱动首先需要分析内核的帧缓冲子系统,因为LCD驱动就是按照帧缓冲子系统提供的注册接口来注册的: (2)内核帧缓冲子系统参考博客:<Linux 帧缓冲子系 ...

  3. (转)Linux设备驱动之HID驱动 源码分析

    //Linux设备驱动之HID驱动 源码分析 http://blog.chinaunix.net/uid-20543183-id-1930836.html HID是Human Interface De ...

  4. 通用USB设备驱动源码分析

    通用USB设备驱动源码分析 Author:aaron 前段时间写了篇<qualcomm usb modem驱动小结>的文章, 描述了自己如何为高通的一个usb modem设备写驱动的过程, ...

  5. linux网卡驱动源码分析(一)

    linux网卡驱动源码分析(一) linux struct linux内核 网络 descriptor resources 转自http://blog.csdn.net/ustc_dylan/arti ...

  6. linux打印源码,Linux打印机驱动源码分析.pdf

    您所在位置:网站首页 > 海量文档 &nbsp>&nbsp计算机&nbsp>&nbsplinux/Unix相关 Linux打印机驱动源码分析.pdf1 ...

  7. hisi3516dv300芯片基于hwmon驱动框架的温度获取驱动源码分析

    1.内核hwmon驱动框架 参考博客:<内核hwmon驱动框架详解以及海思芯片温度驱动分析>: 2.驱动实现的效果 /sys/devices/virtual/hwmon/hwmon0 # ...

  8. Davinci DM6446开发攻略——LINUX GPIO驱动源码移植

    一.             DM6446 GPIO的介绍 说到LINUX 驱动移植,没有移植过的朋友,或刚刚进入LINUX领域的朋友,最好去看看<LINUX 设备驱动程序>第三版,有个理 ...

  9. 【分析笔记】Linux gpio_wdt.c 看门狗设备驱动源码分析

    基本原理 该看门狗的设备驱动实现原理很简单,比较主要的有两点: 一.定时器喂狗 通过定时器根据配置文件配置的喂狗方式(如脉冲切换.电平切换),对指定的 gpio 进行脉冲切换或电平切换实现喂狗. 脉冲 ...

最新文章

  1. Linux下的Shell工作原理
  2. 数据结构 — 双向链表
  3. TypeError: sequence item 0: expected str instance, int found
  4. multinorm r语言_与心理学数据分析相关的R工具包
  5. 提升效率的Vue组件开发和实战技巧
  6. jQuery插件素材网站
  7. python with as有什么好处?
  8. Git过程中遇到Enter passphrase for key '/c/Users/XXX/.ssh/id_rsa':
  9. 互联网请回答2020
  10. www.gvlib video.php,求大佬帮忙
  11. 实现金钱数字格式化:一行代码解决(三位分隔)
  12. 超级计算机 人脑,世界第4超级计算机竟被人脑秒成渣,人类的大脑究竟多厉害?...
  13. 100个世界上鲜为人知的奇闻怪事小知识(转)
  14. 打乱魔方软件_一种智能魔方打乱装置的制作方法
  15. 计算机总评等级怎么弄,excel总评等级怎么做?
  16. android多线程下载程序卡死,android 多线程下载与断点续传
  17. 《Python编程 从入门到实践》 一、基础知识 第六章 字典
  18. Linux 下 网卡重启
  19. Spring Cloud Netfilx Ribbon(负载均衡工具)
  20. 《英语语法新思维初级教程》学习笔记(三)冠词

热门文章

  1. imx6ull Linux spi + frambuffer 实现st7789运行显示QT程序 且可实现大小屏双屏同显
  2. HDClone 磁盘克隆软件,让磁盘复制飞起来
  3. c++语言简易自动售货机,C++自动售货机源代码 课程设计
  4. 阿里云 SAE 携手云效助力「石家庄掌讯」持续交付、降本提效
  5. 这是一篇关于HaaS 506的小Tips
  6. WebBrowser的Cookie操作之流量刷新机
  7. 在计算机网络的工作模式中,在计算机网络的工作模式中,网络中计算机角色既是客户机又是服务器,及提供服务又使用服务,这种模式成为( )...
  8. LAH 笔记 cron
  9. Windows 10 Manager 2.3.2 中文版(绿色版)【系统管家】
  10. pos机 一直连接服务器,pos机刷卡一直在连接中是怎么回事