본문 바로가기
임베디드

디바이스트리 pinctrl -bindings.txt

by I!i어★떤☆날★에Ι!i 2022. 11. 4.
반응형

리눅스 커널을 오랜만에 살펴보려니 디바이스 트리(DeviceTree)가 은근히 헷갈린다.

그래서 혼자 공부할겸, pinctrl 문서를 변역하면서 살펴 보았다. pinctrl을 사용해서 kernel driver 초기화 시에 사용할 pin들을 제어해 보자.

 

참고문서 : https://gitlab.freedesktop.org/lima/linux/-/blob/b773b3bf1916a368c29a19916abf0f5eca8b3c33/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt

 

Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt · b773b3bf1916a368c29a19916abf0f5eca8b3c33 · Lima / linux · Gi

Lima kernel driver for ARM Mali400/450 (deprecated, please refer to upstream linux)

gitlab.freedesktop.org

 

 

pinctrl은 linux kernel device tree에서 gpio pin을 구성하기 위해 사용한다.

 

pinctrl_bindings.txt
pinctrl-bindings.txt

 

== 소개 ==

 

핀 다중화(pin multiplexing)를 control하거나 pull-up/pull-down, tri-state, drive-strength 등과 같은 구성 매개변수(configuration parameters) 를 제어하는 ​​하드웨어 모듈은 핀 컨트롤러(pin controller)로 지정됩니다. 각각의 핀 컨트롤러는 다른 하드웨어 모듈과 마찬가지로 device tree에서 node로 표시되어야 합니다.

 

Signal이 핀 구성의 영향을 받는 하드웨어 모듈은 클라이언트 장치(Client devices)로 지정됩니다. 다시 한번 말하지만, 각 클라이언트 장치는 다른 하드웨어 모듈과 마찬가지로 device tree의 node로 표시되어야 합니다.

 

클라이언트 장치(client device)가 올바르게 작동하려면 특정 핀 컨트롤러가 특정 핀 구성을 설정해야 합니다.

일부 클라이언트 장치에는 예를 들면 초기화 중의 설정(setup) 같은 단일 고정 핀 구성(single static pin configuration)이 필요합니다. 다른 것들은 런타임 시 핀을 재구성해야 합니다. (예를 들어 장치가 비활성(inactive) 상태일 때 3상태 핀(tri-state pins)으로 구성하는 등의 )

따라서 각 클라이언트 장치는 일련의 이름을 정의한 상태 집합으로 정의할 수 있습니다. 이런 상태의 number와 name은 클라이언트 장치의 자체 바인딩(own binding)에 의해 정의됩니다.

 

이 파일에 정의된 공통 pinctrl binding은 상태 이름을 해당 상태에서 사용되는 핀 구성에 매핑하기 위해서 클라이언트 device tree node에 대한 인프라를 제공합니다.

 

핀 컨트롤러 자체가 자체 클라이언트 장치일 수도 있습니다.
예를 들어, 핀 컨트롤러는 드라이버가 로드될 때 자체 "active" 상태를 설정할 수 있습니다. 이렇게 하면 여러 클라이언트 장치 노드에 분할하지 않고 보드의 고정 핀 구성을 한 곳에서 나타낼 수 있습니다. 이 작업을 수행할지 여부에 대한 결정은 개별 board device tree 파일의 작성자와 해당 보드에서 사용 중인 개별 클라이언트 장치에 대한 바인딩에 의해 부과된 요구 사항, 즉 dynamic pin configuration을 위해 특정 명명된 상태가 필요한지 여부에 달려 있습니다.

 

 


== Pinctrl 클라이언트 장치 ==


각 클라이언트 장치에 대해 개별적으로 모든 핀 상태에 숫자 ID가 할당됩니다. 이 숫자는 0에서 시작하며 연속적입니다. 각 상태 ID에는 핀 구성을 정의하는 고유한 속성이 있습니다. 각각의 상태에는 이름이 할당될 수도 있습니다. 이름이 사용되면 해당 이름에서 정수 ID로 매핑되는 다른 속성이 있습니다.


각 클라이언트 장치의 고유한 binding은

device tree node에 정의해야 하는 상태 집합과 제공해야 하는 상태 ID 집합을 정의할지 여부 또는 제공해야 하는 상태 이름 집합을 정의할지 여부를 결정합니다.



필수 속성:
pinctrl-0:
각각 핀 구성 노드를 가리키는 phandle의 목록입니다. 이러한 참조된 핀 구성 노드는 구성하는 핀 컨트롤러의 자식 노드여야 합니다. 이 목록에 여러 항목이 있을 수 있으므로 여러 핀 컨트롤러를 구성하거나 단일 핀 컨트롤러에 대해 여러 노드에서 상태를 구축할 수 있습니다. 각 노드는 전체 구성에 기여합니다. 이러한 핀 구성 노드의 형식에 대한 자세한 내용은 이 문서의 다음 섹션을 참조하십시오.

 

어떤 경우에는 상태를 정의하는 것이 유용할 수 있지만, 비어 있어야 하는 경우도 있습니다. 이것은 핀 컨트롤러가 없거나 핀 컨트롤러가 해당 HW 모듈에 영향을 미치지 않는 SoC에서 공통 IP 블록을 사용할 때 필요할 수 있습니다. 해당 IP 블록에 대한 바인딩에서 특정 핀 상태가 존재해야 하는 경우 해당 핀 상태를 정의해야 하지만 비워 둘 수도 있습니다.

 


선택적 속성:
pinctrl-1:
각각 핀 컨트롤러 내의 pin configuration node를 가리키는phandles의 list 입니다.

...
pinctrl-n:

각각 핀 컨트롤러 내의 pin configuration node를 가리키는phandles의 list 입니다.

 

pinctrl-names:
상태를 할당할 name List입니다. List 항목 0은 정수 상태 ID 0의 이름을 정의하고, List 항목 1은 상태 ID 1을 정의합니다.

 

예를 들면

/* For a client device requiring named states */
device {
    pinctrl-names = "active", "idle";
    pinctrl-0 = <&state_0_node_a>;
    pinctrl-1 = <&state_1_node_a &state_1_node_b>;
};

/* For the same device if using state IDs */
device {
    pinctrl-0 = <&state_0_node_a>;
    pinctrl-1 = <&state_1_node_a &state_1_node_b>;
};

/*
 * For an IP block whose binding supports pin configuration,
 * but in use on an SoC that doesn't have any pin control hardware
 */
device {
    pinctrl-names = "active", "idle";
    pinctrl-0 = <>;
    pinctrl-1 = <>;
};
/*
* 바인딩이 핀 구성을 지원하지만 핀 제어 하드웨어가 없는 SoC에서 사용 중인 IP 블록의 경우.

* or an IP block whose binding supports pin configuration, but in use on an SoC that doesn't have any pin control hardware */
device {
    pinctrl-names = "active", "idle";
    pinctrl-0 = <>;
    pinctrl-1 = <>;
};

 

 

Documentation/devicetree/bindings/pinctrl/pinctrl.yaml

 

== 핀 컨트롤러 장치 ==

 

필수 properties: 핀 컨트롤러 드라이버 관련 문서 참조

 

선택적 속성:
#pinctrl-cells:
핀 컨트롤러 장치 인스턴스 내의 index 로 추가되는 핀 컨트롤 셀의 수

핀 컨트롤러 장치는 클라이언트 장치가 참조하는 핀 구성 노드를 포함해야 합니다.


예를 들어:

pincontroller {
    ... /* Standard DT properties for the device itself elided */

    state_0_node_a {
        ...
    };
    state_1_node_a {
        ...
    };
    state_1_node_b {
        ...
    };
}


각 핀 구성 자식 노드의 내용은 개별 핀 컨트롤러 장치에 대한 바인딩에 의해 정의됩니다. 이 콘텐츠에 대한 공통 표준은 없습니다. pinctrl 프레임워크는 핀 컨트롤러 드라이버가 사용할 수 있는 일반 도우미 바인딩만 제공합니다.

 

핀 구성 nodes는 핀 컨트롤러 장치의 직접적인 자식일 필요는 없습니다. 예를 들어, 그들은 손자일 수 있습니다. 이것이 규칙에 맞는지 여부와 자식 노드와 중간 부모 노드 사이에 상호 작용이 있는지 여부는 개별 핀 컨트롤러 장치에 대한 바인딩에 의해 완전히 재정의됩니다.

 


== 일반 핀 다중화 노드 내용 ==

핀 다중화 노드: pin multiplexing nodes

function      :  선택할 mux function
groups       :  이 기능으로 선택할 그룹 목록  (this 또는 "pins"중 하나를 지정해야 합니다.)
pins           : 이 기능으로 선택할 핀 목록(this 또는 ""groups"이 지정되어야 함)

예시:

state_0_node_a {
    uart0 {
        function = "uart0";
        groups = "u0rxtx", "u0rtscts";
    };
};
state_1_node_a {
    spi0 {
        function = "spi0";
        groups = "spi0pins";
    };
};
state_2_node_a {

    function = "i2c0";
    pins= "mfio29", "mfio30";
};


핀 컨트롤러 하드웨어에 따라 더 적합한 경우 선택적으로 대체 바인딩을 사용할 수 있습니다.

동일한 핀 컨트롤러 인스턴스가 많은 하드웨어의 경우 각 pinfunction의 이름을 지정하는 것은 쉽게 유지 관리할 수 없게 될 수 있습니다. 이는 SoC 개정 및 패키징에 따라 동일한 컨트롤러가 다른 핀과 기능에 사용되는 경우 특히 그렇습니다.


이와 같은 경우 핀 컨트롤러 드라이버는 하드웨어 기반 인덱스 및 여러 핀 구성 값과 함께 pinctrl-pin-array 도우미 바인딩을 사용할 수 있습니다.

pincontroller {
        ... /* 장치 자체에 대한 표준 DT 속성이 생략됨 */
        #pinctrl-cells = <2>;

        state_0_node_a {
                pinctrl-pin-array = <
                        0 A_DELAY_PS(0) G_DELAY_PS(120)
                        4 A_DELAY_PS(0) G_DELAY_PS(360)
                        ...
                >;
        };
        ...
};



위의 #pinctrl-cells는 레지스터 인덱스 외에 값 셀의 수를 지정합니다. 이것은 한 가지 예외를 제외하고 인터럽트 확장 바인딩과 유사합니다. 정의된 핀은 항상 핀 컨트롤러 노드의 자식이므로 각 항목에 대해 phandle을 지정할 필요가 없습니다. 또한 pinctrl 프레임워크가 각 핀 제어 장치에 대해 핀을 그룹화하기 위해 명명된 모드를 사용하기 때문에 phandle이 다른 핀 컨트롤러를 가리키도록 하는 것은 현재 작동하지 않습니다.

pinctrl-pin-array에 대한 인덱스는 pinctrl 레지스터에 대한 하드웨어와 관련되어야 하며 핀 인스턴스의 가상 인덱스가 아니어야 합니다. 그 이유는 dts 파일의 인덱스와 핀 컨트롤러 드라이버가 변경될 수 있으므로 매핑을 피하기 위함입니다.

각 단일 핀에 대해 핀 다중화 구성을 지정해야 하는 하드웨어의 경우 "pin" 및 "function" 속성을 포함하는 필수 하위 노드의 수가 빠르게 증가하고 작성 및 유지 관리가 어려워질 수 있습니다.

이와 같은 경우 핀 컨트롤러 드라이버는 pinmux 그룹의 mux 구성 설정과 함께 핀 식별자가 제공되는 pinmux 도우미 속성을 사용할 수 있습니다. pinmux 그룹은 단일 정수 또는 정수 배열로 표시되는 핀 식별자와 mux 설정으로 구성됩니다.

pinmux 속성은 각각 단일 핀 다중화 구성을 설명하는 pinmux 그룹의 배열을 허용합니다.

pincontroller {
        state_0_node_a {
                pinmux = <PINMUX_GROUP>, <PINMUX_GROUP>, ...;
        };
};


각 개별 핀 컨트롤러 드라이버 바인딩 문서는 핀 ID와 핀 다중화 구성이 어떻게 정의되고 pinmux 그룹에서 함께 조합되는지 지정해야 합니다.



== 일반 핀 구성 노드 내용 ==

핀 구성 노드에 표시되는 많은 데이터 항목은 공통적이고 일반적입니다. 핀 제어 바인딩은 적용 가능한 경우 아래에 정의된 속성을 사용해야 합니다. 이러한 모든 속성이 모든 하드웨어 또는 바인딩 구조에 관련되거나 유용한 것은 아닙니다. 각 개별 바인딩 문서는 이러한 일반 속성(있는 경우)과 이러한 속성을 포함하는 DT 노드의 구조를 명시해야 합니다.

지원되는 일반 속성은 다음과 같습니다.

pins        - 노드의 속성이 적용되는 핀 목록("group" 또는 "pinmux"가 지정되어야 함)
group      - 드라이버가 개별 핀이 아닌 전체 그룹의 구성을 지원하는 경우 속성을 적용할 그룹

                   (여기서 "pins" 또는 "pinmux"를 지정해야 함)
pinmux    - 노드의 속성이 적용되는 숫자 핀 ID 및 해당 mux 설정 목록("핀" 또는 "그룹"이 지정되어야 함)

bias-disable            - 모든 핀 바이어스 비활성화
bias-high-impedance - 고 임피던스 모드("제3 상태", "플로팅")
bias-bus-hold         - 약하게 래치
bias-pull-up            - pull up the pin
bias-pull-down        - pull down the pin
bias-pull-pin-default - 핀 기본 풀 상태 사용
drive-push-pull - 능동적으로 높고 낮게 드라이브
drive-open-drain -  drive with open drain
drive-open-source - 오픈 소스로 드라이브
drive-strength - 최대 XmA의 싱크 또는 소스
input-enable - 핀에서 입력 활성화(입력 버퍼 활성화와 같이 출력에 영향 없음)
input-disable - 핀의 입력 비활성화(입력 버퍼 비활성화와 같은 출력에 영향 없음)
input-schmitt-enable - 슈미트 트리거 모드 활성화
input-schmitt-disable - 슈미트 트리거 모드 비활성화
input-debounce - 디바운스 시간 X가 있는 디바운스 모드
power-source - 다른 전원 공급 장치 중에서 선택
low-power-enable - 저전력 모드 활성화
low-power-disable - 저전력 모드 비활성화
output-disable - 핀의 출력 비활성화(예: 출력 버퍼 비활성화)
output-enable - 능동적으로 구동하지 않고 핀의 출력을 활성화합니다.
(예: 출력 버퍼 활성화)
output-low - 핀을 로우 레벨로 출력 모드로 설정
output-high - 핀을 하이 레벨로 출력 모드로 설정
sleep-hardware-state - 이것이 슬립 상태에 대한 레지스터에 프로그래밍될 슬립 관련 상태임을 나타냅니다.
slew-rate - 슬루율을 설정합니다.

예를 들어:

state_0_node_a {
        cts_rxd {
                pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
        bias-pull-up;
        };
};
state_1_node_a {
        rts_txd {
                pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */
                output-high;
        };
};
state_2_node_a {
        foo {
                group = "foo-group";
                bias-pull-up;
        };
};
state_3_node_a {
        mux {
                pinmux = <GPIOx_PINm_MUXn>, <GPIOx_PINj_MUXk)>;
                input-enable;
        };
};

 


일부 일반 속성은 인수를 사용합니다. 이 경우에 대한, 인수들은 아래에 설명되어 있습니다.

- 핀은 핀 이름 또는 ID 목록을 필수 인수로 사용합니다. 

               하드웨어에 대한 특정 바인딩은 다음을 정의합니다. 
- 항목이 정수인지 문자열인지 여부와 그 의미.
- pinmux는 핀 ID 및 mux 설정 목록을 필수 인수로 사용합니다. 

              하드웨어에 대한 특정 바인딩은 다음을 정의합니다.
- 핀 ID 및 mux 설정이 단일 정수 또는 정수 배열로 함께 정의되고 조합되는 방법.

- bias-pull-up, -down 및 -pin-default는 옴 단위의 풀 강도를 지원하는 하드웨어에서 선택적 인수로 사용됩니다. bias-disable은 풀을 비활성화합니다.

- 구동 강도는 목표 강도(mA)를 인수로 사용합니다.

- input-debounce는 usec의 디바운스 시간을 인수로 사용하거나 0을 사용하여 디바운싱을 비활성화합니다.

 

 


이 매개변수에 대한 더 자세한 문서는 <include/linux/pinctrl/pinconf-generic.h>에서 찾을 수 있습니다.

반응형

댓글