8. 5.7. Подсистема pinctrl в Linux Kernel

8.1. Введение

Подсистема pinctrl (pin controller subsystem) предназначена для управления функциями пинов ввода-вывода (GPIO) на уровне ядра Linux. Ранее каждая архитектура реализовывала мультиплексирование пинов по-своему, что усложняло разработку и сопровождение драйверов. pinctrl решает эту проблему, обеспечивая унифицированный API и интеграцию с Device Tree.

8.2. Задачи подсистемы

  • Управление альтернативными функциями пинов (UART, SPI, I2C и т.д.)

  • Установка подтягивающих резисторов (pull-up/down)

  • Настройка drive-strength, slew-rate и других параметров

  • Интеграция с Device Tree для декларативной конфигурации

  • Поддержка групп пинов и функций

8.3. Компоненты pinctrl

  • pinctrl-core — базовая логика подсистемы

  • pinctrl_ops — API для определения групп пинов

  • pinmux_ops — API для установки альтернативных функций

  • pinconf_ops — API для конфигурации уровня (pull-up, bias и т.д.)

  • pinctrl_desc — структура описания контроллера пинов

8.4. Реализация в Raspberry Pi (BCM2835)

Конкретная реализация контроллера pinctrl для Raspberry Pi 3 находится в:

drivers/pinctrl/bcm/pinctrl-bcm2835.c

Она взаимодействует с регистрами:

  • GPFSELn — выбор функции пина

  • GPPUD и GPPUDCLKn — конфигурация подтягивающих резисторов

8.5. Пример использования в Device Tree

&uart0 {
    pinctrl-names = "default";
    pinctrl-0 = <&uart0_pins>;
    status = "okay";
};

uart0_pins: uart0_pins {
    pins = "gpio14", "gpio15";
    function = "alt0";
    bias-disable;
};

8.6. Как вызывается pinctrl из драйвера

Внутри probe() драйвера:

static int my_probe(struct platform_device *pdev)
{
    struct pinctrl *pctl;

    pctl = devm_pinctrl_get_select_default(&pdev->dev);
    if (IS_ERR(pctl)) {
        dev_err(&pdev->dev, "Pinctrl setup failed\n");
        return PTR_ERR(pctl);
    }

    return 0;
}

Функция devm_pinctrl_get_select_default():

  • Получает состояние «default» из pinctrl-names в DT

  • Находит соответствующие пины и функции через pinctrl_ops и pinmux_ops

  • Устанавливает конфигурацию через pinconf_ops

Вся цепочка работает автоматически при правильной настройке DT.

8.7. Вывод

Подсистема pinctrl является важным связующим звеном между Device Tree, драйверами устройств и регистровой настройкой периферии. Она позволяет конфигурировать пины декларативно, обеспечивает повторное использование кода и упрощает портирование драйверов между платформами.

pinctrl — это не просто настройка вывода, это фундаментальная часть архитектуры управления GPIO в Linux.