完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
以I2C4为例作简单的介绍。
查规格表可知,I2C4_SDA与I2C4_SCL的功能定义如下: #func0func1I2C4_SDA/GPIO1_B3gpio1b3i2c4_sdaI2C4_SCL/GPIO1_B4gpio1b4i2c4_scl 在kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi里有: i2c4:i2c@ff3d0000{;reg=<0x00xff3d00000x00x1000>;clocks=pmucruSCLK_I2C4_PMU>,pmucruPCLK_I2C4_PMU>;,"pclk";interrupts=;,"gpio";pinctrl-0=i2c4_xfer>;pinctrl-1=i2c4_gpio>;//此处源码未添加#address-cells=<1>;#size-cells=<0>;;}; 此处,跟复用控制相关的是pinctrl-开头的属性:pinctrl-names定义了状态名称列表:default(i2c功能)和gpio两种状态。 pinctrl-0定义了状态0(即default)时需要设置的pinctrl:&i2c4_xfer pinctrl-1定义了状态1(即gpio)时需要设置的pinctrl:&i2c4_gpio 这些pinctrl在kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi中这样定义: pinctrl:pinctrl{;rockchip,grf=grf>;rockchip,pmu=pmugrf>;#address-cells=<0x2>;#size-cells=<0x2>;ranges;i2c4{i2c4_xfer:i2c4-xfer{rockchip,pins=<112RK_FUNC_1&pcfg_pull_none>,<111RK_FUNC_1&pcfg_pull_none>;};i2c4_gpio:i2c4-gpio{rockchip,pins=<112RK_FUNC_GPIO&pcfg_pull_none>,<111RK_FUNC_GPIO&pcfg_pull_none>;};}; RK_FUNC_1,RK_FUNC_GPIO的定义在kernel/include/dt-bindings/pinctrl/rk.h中: #defineRK_FUNC_GPIO0#defineRK_FUNC_11#defineRK_FUNC_22#defineRK_FUNC_33#defineRK_FUNC_44#defineRK_FUNC_55#defineRK_FUNC_66#defineRK_FUNC_77 另外,像”111”,”112”这样的值是有编码规则的,编码方式与上一小节”输入输出”描述的一样,”111”代表GPIO1_B3,”112”代表GPIO1_B4。 在复用时,如果选择了“default”(即i2c功能),系统会应用i2c4_xfer这个pinctrl,最终将GPIO1_B3和GPIO1_B4两个针脚切换成对应的i2c功能;而如果选择了“gpio”,系统会应用i2c4_gpio这个pinctrl,将GPIO1_B3和GPIO1_B4两个针脚还原为GPIO功能。 我们看看i2c的驱动程序kernel/drivers/i2c/busses/i2c-rockchip.c是如何切换复用功能的: staticintrockchip_i2c_probe(structplatform_device*pdev){structrockchip_i2c*i2c=NULL;structresource*res;structdevice_node*np=pdev->dev.of_node;intret;//...i2c->sda_gpio=of_get_gpio(np,0);if(!gpio_is_valid(i2c->sda_gpio)){dev_err(&pdev->dev,"sdagpioisinvalidn");return-EINVAL;}ret=devm_gpio_request(&pdev->dev,i2c->sda_gpio,dev_name(&i2c->adap.dev));if(ret){dev_err(&pdev->dev,"failedtorequestsdagpion");returnret;}i2c->scl_gpio=of_get_gpio(np,1);if(!gpio_is_valid(i2c->scl_gpio)){dev_err(&pdev->dev,"sclgpioisinvalidn");return-EINVAL;}ret=devm_gpio_request(&pdev->dev,i2c->scl_gpio,dev_name(&i2c->adap.dev));if(ret){dev_err(&pdev->dev,"failedtorequestsclgpion");returnret;}i2c->gpio_state=pinctrl_lookup_state(i2c->dev->pins->p,"gpio");if(IS_ERR(i2c->gpio_state)){dev_err(&pdev->dev,"nogpiopinctrlstaten");returnPTR_ERR(i2c->gpio_state);}pinctrl_select_state(i2c->dev->pins->p,i2c->gpio_state);gpio_direction_input(i2c->sda_gpio);gpio_direction_input(i2c->scl_gpio);pinctrl_select_state(i2c->dev->pins->p,i2c->dev->pins->default_state);//...} 首先是调用of_get_gpio取出设备树中i2c4结点的gpios属于所定义的两个gpio: gpios=gpio1GPIO_B3GPIO_ACTIVE_LOW>,gpio1GPIO_B4GPIO_ACTIVE_LOW>; 然后是调用devm_gpio_request来申请gpio,接着是调用pinctrl_lookup_state来查找“gpio”状态,而默认状态“default”已经由框架保存到i2c->dev-pins->default_state中了。 最后调用pinctrl_select_state来选择是“default”还是“gpio”功能。 下面是常用的复用API定义: #includestructdevice{//...#ifdefCONFIG_PINCTRLstructdev_pin_info*pins;#endif//...};structdev_pin_info{structpinctrl*p;structpinctrl_state*default_state;#ifdefCONFIG_PMstructpinctrl_state*sleep_state;structpinctrl_state*idle_state;#endif};structpinctrl_state*pinctrl_lookup_state(structpinctrl*p,constchar*name);intpinctrl_select_state(structpinctrl*p,structpinctrl_state*s); |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
基于米尔瑞芯微RK3576核心板/开发板的人脸疲劳检测应用方案
937 浏览 0 评论
1138 浏览 1 评论
935 浏览 1 评论
2163 浏览 1 评论
3475 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-27 18:30 , Processed in 0.682571 second(s), Total 72, Slave 56 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号