基于pinctrl 和 devcice tree的SOC GPIO 使用

来源:互联网 发布:centos7修改ssh端口号 编辑:程序博客网 时间:2024/05/17 21:39

在嵌入式系统开发中,我们不可避免的要跟SOC 的GPIO模块打交道。在单片机的开发中,我们一般使用的是下面的模式

void XXX_init()

{

//gpio fuction mux select


//peripheral regsiter configure


//other related software resourece init


}

其实在早期的linux系统中,外设的初始化也是一个类似的过程,只不过是要使用linux提供提供的一些接口而已,不像单片机可以随心所欲的写code


但是随着linux的发展 device tree已经慢慢统治了powerpc linux和arm linux。就使用来说,的确是简单了很多,但是linux引入了大量的框架来支持这些便利,要多了一些需要精读的代码,这里不分析代码实现的细节,只是从使用的角度来记录一下,方便以后的工作中,查询使用。

这里分三种情况来举例说明

1. 外围控制器的mux功能选择,以IPQ409的SPI控制器举例,这里主要用的是PINCTRL 的MUX 设定

要想把某组pin分配给SPI0控制器,需要在dts里做如下定义:

1).定义一个pn mux

spi_0_pins: spi_0_pinmux {
mux {
pins = "gpio12", "gpio13", "gpio14", "gpio15"; //pin列表,可以查看芯片手册获取这个group
function = "blsp_spi0";
bias-disable;
};

2).在spi的控制器节点引用之

spi_0: spi@78b5000 {

/* BLSP1 QUP1 */
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "ok";



m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
compatible = "n25q128a11";
linux,modalias = "m25p80", "n25q128a11";
spi-max-frequency = <24000000>;
use-default-sizes;
};
};

2. 定义pin为gpio,并设置默认的 输入输出属性已经上下拉配置以及驱动电流等

dts文件里在pinctrl节点下添加以下定义,可以定义若干pin group,或者只对某个pin做特殊的描述,

gpio可以配置的属性如下:


 bias-disable – disable any pin bias
 bias-pull-up – pull up the pin
 bias-pull-down – pull down the pin
 drive-strength – sink or source at most X mA
 input-enable – enable input on pin (no effect on output)
 input-disable – disable input on pin (no effect on output)
 output-low – set the pin to output mode with low-level
 output-high – set the pin to output mode with high-level

 pinctrl@0x01000000 {
            pinctrl-0 = <&example_gpio>;
            pinctrl-names = "default";


            ............
            example_gpio: hw_gpio{
                led{
                    pins = "gpio37","gpio42","gpio51","gpio52","gpio61","gpio68";
                    output-low;
                };
                gpio{
                    pins = "gpio49";
                    output-high;
                };
                gpio_i2c{
                    pins = "gpio21","gpio20";
                    drive-strength = <4>;
                };
            };
          .................

};

3. 在某个device node需要使用gpio,或者使用gpio作为中断输入

这里以一个GPIO模拟的I2C控制器举例

i2c_1 {
        compatible = "atmel,i2c-gpio";
        status = "ok";
        gpios = <&tlmm 21 0      &tlmm 20 0>; /*i2c pin */
        i2c-gpio,delay-us = <2>;
        i2c-gpio,scl-open-drain;
        #address-cells = <1>;
        #size-cells = <0>;

        isl28022@40 {
                /* power monitor */
                compatible = "isl,isl28022";
                reg = <0x40>;

              /*use gpio 43 as gpio interrupt,tlmmis the gpio controller defined in the example soc system*/

                interrupt-parent = <&tlmm>;
                interrupts = <43 0x8>;
                irq-gpio = <&tlmm 43 0>;

        };


0 0