今天的文章稍微晚了一点,因为一口君阳了。
烧的很难受,昨天晚上和今天下午各吃了1颗布洛芬,现在好一些了,希望大家都晚一点阳,症状都轻一点。
最近在玩瑞芯微平台的产品,移植了几个设备的驱动,遇到了一些问题,总结后发现大部分问题都出在了GPIO配置的问题上,写下本篇文章,用来分享一下调试的心得。
0、前言
本文基于rk3568平台。
要查看rk3568 GPIO分组及地址信息,需要查看TRM手册,下载地址:
一、RXW-GPIO介绍
GPIO(General Purpose Input/Output Port):通用输入输出端口。
除作为一般的输入/输出功能外,还可以配置为中断和模拟UART、CAN、PWM、I2C、SDMMC、CLK等功能。
1. GPIO分组
一共有5组GPIO(GPIO0~4),每组GPIO为一个Bank,共32个引脚。每个Bank包括4个 **Group (GPIOA(0~7) ~ D( 0~7)) **。RK3568共160个GPIO引脚。
GRF(General Register Files)做了分组,
要查找GPIO对应的配置寄存器地址,必须知道他属于哪个分组:
2. GPIO引脚号计算方式:
例如GPIO2 A2:
在这里插入图片描述
由上图可得:
gpio0 bank属于PMU分组, 基地址:0xFDC20000
gpio0~4 bank 属于SYS分组,基地址:0xFDC60000
GPIO0 bank控制pin0~31
GPIO1 bank控制pin32~63
GPIO2 bank控制pin64~95
GPIO3 bank控制pin96~127
GPIO4 bank控制pin128~159
通过上图,很方便查找到对应的GPIO引脚号以及IOMUX control寄存器地址。一口君还画了下面这个图,大家根据自己喜好,看看哪一个比较好:
3. sys文件查看pin与gpio号之间映射
也可以用debugfs来查看pin与gpio号之间映射关系
二、rk3568GPIO控制器驱动
1. gpio相关api
Linux内核GPIO主要实现文件:
GPIO子系统有两套API:
基于描述符(descriptor-based)
前缀为:
参考:
老版本接口(legacy)
前缀为:
参考:
API对比:
2. rk3568 GPIO控制器驱动
GPIO控制器驱动实现文件:
gpio涉及主要函数:
三、gpio驱动编写实例
下面以实际项目中的一个应用为例来讲解,如何在一个项目中增加一个控制GPIO的逻辑,一看就会。
0. 应用场景:
触摸屏GT1X,触摸屏的设备树和驱动官方均已提供,硬件信息比如INT、RST、I2C按照实例填写即可。
但是实际应用中,因为硬件设计需要,有一路点供电引脚AVDD需要由gpio2 A2来提供,
下面我们介绍一下如何再已有的设备树、驱动基础上添加这个GPIO的功能。
1. 设备树
首先我们需要添加该引脚的设备树信息,
其中添加的设备树节点含义如下:
RK_PA2、RK_FUNC_GPIO 定义位于:
pcfg_pull_none 定义位于:
如果gpio的驱动强度不够,可以修改对应属性。
2. 驱动代码编写
我们把所有GPIO操作相关代码抽取出来如下:
定义
注册
控制电平
释放
3. 添加到触摸屏GT1X驱动中
关于触摸屏驱动,一口君后面会写相应的文章来给大家详细讲解。
下面讲解一下,我是如何将GPIO的操作移植到gt1x驱动中的。
瑞芯微的sdk已经包含了触摸屏驱动:
增加该GPIO变量定义
设备解析函数gt1x_parse_dt(),添加解析该引脚的代码
在函数gt1x_request_io_port()中增加申请申请该GPIO资源的代码
在释放GPIO和中断的函数gt1x_remove_gpio_and_power()释放该gpio资源
在什么位置控制该GPIO?
触摸屏上电时序图:
由上图可知,上电的时候,必须首先把AVDD拉高,然后才能继续后续的操作。
之前的驱动是借用系统的电,但是本例是用GPIO来提供这个电。
触摸屏驱动已经写好了相应的架构,AVDD上电/关闭均封装到了函数gt1x_power_switch(),
系统上电初始化会调用该函数,
同时当屏幕息屏的时候pm子系统会通过对应的回调函数,调用休眠函数gt1x_pm_suspend(),唤醒屏幕会调用gt1x_pm_resume(),
他们也会在何时的实际调用gt1x_power_switch(),
我们只需要在该函数中加上GPIO拉高、拉低的操作即可。
此外 ,原有的供电代码都需要删除。
四、 查看已经申请了的GPIO
系统启动后,可以通过debugfs查看GPIO分配情况
可以看到设备树中的3个GPIO信息:
如果debugfs没有挂在,使用下面命令挂载
五、总结
实际上,GPIO编写还是很简单的,驱动不论多复杂,最终都还是由这些基本的函数来实现的,
这是因为在开发一个新的产品的时候,sdk中很多硬件的配置信息,往往是厂家自己出厂的一个demo板子的硬件信息,
而很多GPIO功能的配置可能和我们实际需求有差异,
经常出现某个设备的GPIO配置了,但是工作却不正常的情况发生,
原因就是iomux并不是自己所需要的功能,
下一篇,给大家详细讲解,如何定位GPIO复用的问题。
领取专属 10元无门槛券
私享最新 技术干货