GPIO子系统API函数
1.申请GPIO函数
int gpio_request(unsigned gpio, const char *label)
gpio: 要申请的GPIO编号,一般是首先从设备树中通过of_get_named_gpio获取,此函数会返回这个GPIO的编号。
label: 给GPIO设定一个名字。
返回值:
0:申请成功。
其他:申请失败。
2.释放GPIO函数
void gpio_free(unsigned gpio)
gpio:要释放的GPIO编号。
返回值:无
3.设置GPIO为输入模式函数
int gpio_direction_input(unsigned gpio)
gpio:要设置的GPIO编号。
返回值:
0:设置成功
负值:设置失败
4.设置GPIO为输出模式的函数
int gpio_direction_output(unsigned gpio, int value)
gpio:要设置的GPIO编号
value:GPIO默认输出值
返回值:
0:设置成功
负值:设置失败
5.获取GPIO电平函数(其实是一个宏)
#define gpio_get_value __gpio_get_value
int __gpio_get_value(unsigned gpio)
gpio:要获取的GPIO编号
返回值:
非负值:得到的GPIO电平值
负值:获取失败
6.设置GPIO电平函数(宏)
#define gpio_set_value __gpio_set_value
void __gpio_set_value(unsigned gpio, int value)
gpio:要设置的GPIO编号
value:设置的电平值
返回值:无
关于全志平台GPIO编号配置
实际GPIO编号的计算也是十分简单:
GPIO编号 = 控制器端口号 * 32 + 索引序号
对于控制器端口号,例如GPIOA就是0 GPIOC就是2 等等
对于Orangepi Zero3有如下空闲GPIO:
这里已经给出了GPIO编号,例如PC6 :2 * 32 + 6 = 70
注意这些GPIO只要没有正在被使用,都是可以request的,若request不成功,大概率都是引脚功能冲突,若出现冲突,可以查看设备树来选择不冲突的引脚进行request。
全志pinctrl驱动分析
设备树中找到对应的compatible
在驱动中搜索这个compatible:
找到驱动名称:pinctrl-sun50iw9.c
驱动中含有:
static struct of_device_id sun50iw9_pinctrl_match[] = {
{
.compatible = "allwinner,sun50iw9-pinctrl", },
{
}
};
MODULE_DEVICE_TABLE(of, sun50iw9_pinctrl_match);
当然,最主要的驱动还是pinctrl-sunxi.c
上面的pinctrl-sun50iw9.c是对于各个芯片的引脚的功能定义,而pinctrl-sunxi.c是对于总体的一个控制接口,是和平台无关的。
这里以UART0的引脚分析这个驱动解析设备树的过程:
设备树中有描述:
uart0-ph-pins {
pins = "PH0", "PH1";
function = "uart0";
bias-pull-up;
phandle = <0x29>;
};
关于"pins"属性的识别:
static const char *sunxi_pctrl_find_pins_prop(struct device_node *node,
int *npins)
{
int count;
/* Try the generic binding */
count = of_property_count_strings(node, "pins");
if (count > 0) {
*npins &