pinctrl
Posted 四季帆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pinctrl相关的知识,希望对你有一定的参考价值。
1. pinctrl简介
pinctrl子系统管理的Pin可以用作iic,也可以用作gpio;但是gpio子系统管理的pin只能用作输出或输入等功能(用作gpio的pin也是通过pinctrl子系统来管理的)。
2. pinctrl使用方法
1、其他驱动(除了IOMUX驱动本身或者说是pinctrl子系统本身外)通过pinctrl子系统提供的接口改变设备状态的接口如下,通常都是如下三个步骤:
1>pinctrl=devm_pinctrl_get(struct device)
2>pinctrl_state=pinctrl_lookup_state(pinctrl,state)
3>pinctrl_select_state(pinctrl,pinctrl_state)
2、pinctrl子系统会调用类似1中的三个步骤初始化IOMUX节点下的字节点,所以有想要使能的PIN脚但是又不属于其它设备节点的pin脚可以都添加在IOMUX节点的子节点中;其他驱动的设备在平台总线被绑定之后会调用1中的三个步骤对设备相关的pin脚做初始化。
3、pinctrl子系统提供的三个接口只能使能在设备节点中通过pinctrl-%d的形式明确标识的fsl,pins属性对应的pin脚。所以设备树文件的关键点还是在于设备节点是否使用pinctrl-%d的方式引用pin_grp,只需确保被外设引用的pin_grp是对的即可。
3. pinctrl注册流程
pinctrl子系统会将SOC可配置的引脚及其对应的功能全部注册到内核,驱动中通过pinctrl-pinctrl-%d的形式明确标识需要使用的引脚和功能,通过pinctrl_get()从内核获取引脚的使用权。注册全部引脚的代码流程如下:
1>drivers/pinctrl/pinctrl-imx6dl.c
static const struct pinctrl_pin_desc imx6dl_pinctrl_pads[] =
IMX_PINCTRL_PIN(MX6DL_PAD_RESERVE0),
······省去214行
IMX_PINCTRL_PIN(MX6DL_PAD_SD4_DAT7),
; #IMX6DL这款SOC可配置的引脚共214个
static struct imx_pinctrl_soc_info imx6dl_pinctrl_info =
.pins = imx6dl_pinctrl_pads,
.npins = ARRAY_SIZE(imx6dl_pinctrl_pads), #注意
;
static int imx6dl_pinctrl_probe(struct platform_device *pdev)
return imx_pinctrl_probe(pdev, &imx6dl_pinctrl_info);
2>drivers/pinctrl/pinctrl-imx.c
int imx_pinctrl_probe(struct platform_device *pdev,
struct imx_pinctrl_soc_info *info)
imx_pinctrl_desc.pins = info->pins;
imx_pinctrl_desc.npins = info->npins; #注意
#解析设备树中关于Pin的配置信息,并将其放到链表中管理起来
imx_pinctrl_probe_dt(pdev, info);
#向内核注册SOC的所有可配置引脚
pinctrl_register(&imx_pinctrl_desc, &pdev->dev, ipctl);
3>drivers/pinctrl/core.c
struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
struct device *dev, void *driver_data)
pinctrl_register_pins(pctldev, pctldesc->pins, pctldesc->npins);
static int pinctrl_register_pins(struct pinctrl_dev *pctldev,
struct pinctrl_pin_desc const *pins,unsigned num_descs)
/*遍历传入的所有Pin的数据结构,一个个处理,pinctrl drvier会传入所有的pin管脚及对应的名称*/
for (i = 0; i < num_descs; i++)
ret = pinctrl_register_one_pin(pctldev,pins[i].number, pins[i].name);
以上是关于pinctrl的主要内容,如果未能解决你的问题,请参考以下文章
Linux虚拟Pinctrl Demo驱动 -- Debug FS之Pinctrl分析
Linux虚拟Pinctrl Demo驱动 -- Debug FS之Pinctrl分析