核心api及其功能
/*获取pinctrldts的句柄,简单的说就是driver中的of_match_table中的compatible和dts匹配*/
struct pinctrl *devm_pinctrl_get(struct device *dev);
/*字面意思,查找到这个pinctrl的状态*/
struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p, const char *name);
/*这个是真正设置pinctrl的功能,执行这个以后才生效*/
int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state);
/*最简单的方法,相当同时执行了上面所以命令,后面例子中可以看到*/
static inline struct pinctrl * __must_check devm_pinctrl_get_select(
struct device *dev, const char *name);
/*和上面类似,默认使用default的pinctrl*/
static inline struct pinctrl * __must_check devm_pinctrl_get_select_default(
struct device *dev);
/*释放掉pinctrl的控制*/
pinctrl_put(struct pinctrl *p);
以上是主要常用的api,其他不常用的不做过多叙述,可以参考源码
用法举例
dts中对应的设备中添加
eggdemo {
compatible = "jasegg, demo";
status = "okay";
pinctrl-names="default,damo_pins";
pinctrl-0=<&egg_pins0>;
pinctrl-1=<&egg_pins1>;
}
对应的driver中
static int egg_demo_probe(struct platform_device *pdev)
{
struct pinctrl *pinctrldemo;
struct pinctrl_state *s;
struct device *dev = &pdev->dev;
int ret = 0;
/*****************方法一 start*******************/
pinctrldemo= devm_pinctrl_get(dev);
if (IS_ERR(pinctrldemo)) {
ret = PTR_ERR(pinctrldemo);
pr_err("Cannot find pinctrlaud!\n");
return;
}
s = pinctrl_lookup_state(pinctrldemo, "damo_pins");
if (IS_ERR(s )) {
ret = PTR_ERR(s );
pr_err("Cannot find pinctrlookup_state!\n");
return;
}
ret = pinctrl_select_state(pinctrldemo, s);//这里就会设置成pinctrl-1的功能了
/*****************方法一 end*******************/
/*****************方法二 start*******************/
pinctrldemo=devm_pinctrl_get_select(dev, "damo_pins");//一步设置成pinctrl-1的功能了
pinctrldemo=devm_pinctrl_get_select_default(dev);//一步设置成pinctrl-0(default)的功能了
/*****************方法二 end*******************/
/*************释放的时候使用***************/
pinctrl_put(pinctrldemo);
}
static const struct of_device_id egg_dt_match[] = {
{
.compatible = "jasegg, demo",
},
{},
};
static struct platform_driver eggdamo_driver = {
.driver = {
.name =xxx,
.owner = THIS_MODULE,
.of_match_table = egg_dt_match,
};
.probe = egg_demo_probe,
.remove = __exit_p(egg_demo_remove),
};
static int __init eggdamo_init(void)
{
if (platform_driver_register(&eggdamo_driver)) {
pr_err("xxxxxx\n");
return -ENODEV;
}
return 0;
}
fs_initcall(eggdamo_init);
debug方法
工具
在使用时候,有可能pin已经呗占用掉了,导致一直失败,这个时候可以通过debugfs来查看
节点在 sys/kernel/debug
大部分的平台会软链接到根目录的d下面,如下图
亦可以创建一个目录手动挂载,
mount -t debugfs debugfs xxxxx
案例
以下述案例为例
进入目录后
Cat pinctrl/pinctrl@xxxxxx/pinmux-pins,查看目前被用作的功能
如上图,GPIOZ_6已经被用于pwm_d的功能,这时候我们可以去dts中查找,去掉这个功能,可以直接把okay改成disabled或者注释掉pinctrl
如果发现不是pinctrl占用的,也能是gpio request了
可以cat gpio
如上图被用作了switch_gpio 输入低,可以在dts中或者driver中去掉switch_gpio
如何查找pin支持的功能?
可以使用一下两个节点
cat pinctrl/pinctrl@ff6346c0/pingroups
Cat pinctrl/pinctrl@ff6346c0/pinmux-functions
文章主要用于总结问题,如有其他更好的方案,或者错误,欢迎留言指教
谢谢!