linux的gpio设备,Linux 4.x之Gpio分析(一)Gpiolib库1

下面的内容均在imx6平台上举例,这一次分析希望将整个GPIO子系统的所有细节整理清晰。

第一篇从gpiolib入手,后面的边分析边写.

开始之前给自己提几个问题

驱动开发中的GPIO API 究竟是怎么实现的?

GPIO的中断又是怎么实现的?

GPIO号和IRQ的号码怎么映射的?

1.芯片定义

我们在驱动程序中会用到gpio_request(x),这里的x便是gpio的编号,而GPIO通常会分组,在原理图经常会看见GPIO2_5类似的标识,通常我们先会翻阅一下datesheet来了解一下这块芯片的定义是如何。

在imx6芯片中的将GPIO分成了若干组,每组为32个管脚。

我们简单的阅读一下芯片手册:

IMX6的gpio控制结构:

473407fd023f

iomux_block.jpg

我们的芯片会引出一堆引脚,而在芯片的内部会集成很多control,(我们称这些control为block)其中的引脚可以功能复用,比如说A1 A2脚支持I2C功能也支持GPIO功能,我可以将I2C1_control的管脚连接过来,或者将GPIO1_1的管脚连接上来,这个就是IOMUX的作用:提供PIN不同的功能切换。

所以我们在使用芯片之前会先根据主板的配置先将各个管脚配置为正确的功能的Pin.

寄存器:

Data register (GPIO_DR)

GPIO direction register (GPIO_GDIR)

Pad sample register (GPIO_PSR)

Interrupt control registers (GPIO_ICR1, GPIO_ICR2)

Interrupt mask register (GPIO_IMR)

Interrupt status register (GPIO_ISR)

GPIO edge select register (GPIO_EDEG_SEL )

简单介绍一下

DR 当作为输出时控制管脚高低电平

GDIR 控制管脚作为输入还是输出

PSR 作为输出时获取管脚的高低电平

ICR1 ICR2 是配置中断的触发方式 高/低电平触发 上升/下降沿 触发

IMR 中断屏蔽寄存器

ISR 中断状态寄存器 哪个管脚触发了中断

EDEG_SEL 边缘触发模式(上/下沿都触发)

GPIO有7组,每组32个,最后一组14个

2.设备树

我们了解了一下内部的结构,接着就要开始看代码了,在看代码之前看看设备树,才能定位到代码在哪里。

这里只列出一个gpio-controller

aliases {

ethernet0 = &fec;

can0 = &can1;

can1 = &can2;

gpio0 = &gpio1;

gpio1 = &gpio2;

.....

}

gpio1: gpio@0209c000 {

compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";

reg = <0x0209c000 0x4000>;

interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>,

<0 67 IRQ_TYPE_LEVEL_HIGH>;

gpio-controller;

#gpio-cells = <2>;

interrupt-controller;

#interrupt-cells = <2>;

};

我们通过compatible的值可以找到对应的驱动代码路径 driver/gpio/gpio-mxc.c

GPIO1控制寄存器的地址是0x0209c000,长度0x4000,使用66和67号中断。

这里疑惑的地方是为什只用了两个中断号,而不是32个?

我们知道一个GPIO控制是通过总线连接到CPU,中断连接到中断控制器(GIC),那么中断线太多就以为着GIC的数量也需要增加,如果GPIO控制器内部进行判断是哪个管脚触发的那么就可以避免GIC的数量。

而我们的芯片内部只有一个GIC.

IRQ

Source

Interrupt Description

32

IOMUXC

General Purpose Register 1 from IOMUXC. Used to notify cores on exception condition whileboot.

33

DAP

Debug Access Port interrupt request

98

GPIO1

Combined interrupt indication for GPIO1 signals 0 - 15.

99

GPIO1

Combined interrupt indication for GPIO1 signals 16 - 31.

这里中断号的来源是芯片手册,因为GIC的连接是这样的,这里0-31是内部使用,32开始用作外设。

驱动中用编号0直接开始编号。

地址参考寄存器MAP

Absolute

address

Register name Widt (bits)

Access

Reset value

209_C000

GPIO data register (GPIO1_DR)

32

R/W

0000_0000h

209_C004

GPIO direction register (GPIO1_GDIR)

32

R/W

0000_0000h

209_C008

GPIO pad status register (GPIO1_PSR)

32

R

0000_0000h

209_C00C

GPIO interrupt configuration register1 (GPIO1_ICR1)

32

R/W

0000_0000h

209_C010

GPIO interrupt configuration register2 (GPIO1_ICR2)

32

R/W

0000_0000h

209_C014

GPIO interrupt mask register (GPIO1_IMR)

32

R/W

0000_0000h

209_C018

GPIO interrupt status register (GPIO1_ISR)

32

w1c

0000_0000h

209_C018

GPIO interrupt status register (GPIO1_ISR)

32

w1c

0000_0000h

209_C01C

GPIO edge select register (GPIO1_EDGE_SEL)

32

R/W

0000_0000h

20A_0000

GPIO data register (GPIO2_DR)

32

R/W

0000_0000h

3.代码

从设备树中我们知道了代码的路径位置,我们先看看gpio这个目录的Makefile:

obj-$(CONFIG_GPIO_DEVRES) += devres.o

obj-$(CONFIG_GPIOLIB) += gpiolib.o

obj-$(CONFIG_GPIOLIB) += gpiolib-legacy.o

obj-$(CONFIG_OF_GPIO) += gpiolib-of.o

obj-$(CONFIG_GPIO_SYSFS) += gpiolib-sysfs.o

obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o

# Device drivers. Generally keep list sorted alphabetically

obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o

obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o

.....(省略一些无关紧要的内容)

obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o

这里分三类:

gpiolib的代码

gpio-generic代码

gpio特定平台的代码

代码的结构:

GPIOLIB 调用 GPIO_GENRIC 调用 GPIO_MXC

接着我们开始分析代码:

代码主要讲了初始化GPIO控制器和GPIO的中断控制器,这里先分析gpio控制器和如何与gpiolib联系

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

};

enum mxc_gpio_hwtype {

IMX1_GPIO, /* runs on i.mx1

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值