Интерпретация gpio: в записи дерева устройств с фиксированным регулятором?

Я пытаюсь контролировать (вкл./выкл.) регулятор напряжения, который сопоставляется с выводом GPIO и подключает внешнее устройство. Дерево устройств для регулятора имеет следующую запись:

    reg_usb1_vbus: usb1_vbus {
        compatible = "regulator-fixed";
        regulator-name = "usb1_vbus";
        regulator-min-microvolt = <5000000>;
        regulator-max-microvolt = <5000000>;
        gpio = <&gpio3 28 0>;
        enable-active-high;
    };

Когда я прочитал документацию, я запутался в ней:

Дополнительные свойства:

  • gpio: gpio использовать для включения управления

Однако я не могу экспортировать интерфейс sysfs этого GPIO и использовать его для управления источником питания (просто вкл/выкл) для внешнего устройства. Кроме того, если я прокомментирую gpio = <&gpio3 28 0>; из дерева устройств, внешнее устройство не получает питания (когда он не комментирует, устройство всегда включено).

У регулятора есть экспортированный интерфейс sysfs:

80090000.usb-vbus      power                  suspend_standby_state
device                 state                  type
microvolts             subsystem              uevent
name                   suspend_disk_state
num_users              suspend_mem_state

однако я не могу писать никому из файлов.

Каков правильный способ интерпретации записи gpio:?

  • gpio для включения управления

    В этом случае мне не хватает отображения между выводом, на котором я хочу иметь напряжение регулятора.

  • gpio, который будет иметь напряжение от регулятора для питания какого-либо внешнего устройства

    В этом случае у меня отсутствует способ включить и выключить

Ответ 1

Я пытаюсь контролировать (вкл./выкл.) регулятор напряжения, который сопоставляется с выводом GPIO и питает внешнее устройство.
...

Каков правильный способ интерпретации gpio: entry?

Похоже, вы задаете вопрос XY.
Сначала часть Y относится к GPIO.

Запись gpio DT, на которую вы ссылаетесь, будет для управления включением/отключением с помощью структуры регулятора. Он предназначен для исключительного использования драйвером регулятора для управления оборудованием (внешним?) Регулятором. Он не предназначен для программного управления регулятором вне рамки пользователем (как вы пытаетесь сделать).

Этот GPIO определяется как выход в drivers/regulator/core.c:

 static int regulator_ena_gpio_request(struct regulator_dev *rdev,
                                 const struct regulator_config *config)
 {
        ...
         ret = gpio_request_one(config->ena_gpio,
                                 GPIOF_DIR_OUT | config->ena_gpio_flags,
                                 rdev_get_name(rdev));
         ...
 }

Вывод GPIO не считывается для "enable control", но имеет значение, установленное в regulator_ena_gpio_ctrl(), чтобы активно включать или отключать (внешний) регулятор.

Невозможность экспортировать один и тот же вывод GPIO с помощью sysfs, когда этот вывод также объявлен в дереве устройств, легко объясняется. Как только драйвер приобретет указанный GPIO для его использования (через DT), он больше не будет использоваться, и вы не сможете экспортировать этот GPIO через sysfs. GPIO - это управляемый ресурс, который нужно выделять и освобождать (с помощью драйвера или sysfs), как и любой другой ресурс, такой как память. Если бы вы могли экспортировать этот GPIO, который также использовался драйвером, вы могли бы поместить GPIO в состояние, которое не соответствовало бы тому, что делал драйвер. Это, в свою очередь, приведет к нестабильному или неправильному коду.

В этом случае мне не хватает отображения между выводом, на котором я хочу иметь напряжение регулятора.

Вывод GPIO, указанный в дереве устройств, является логическим (то есть цифровым) выходом. Это не выход регулятора, который будет аналоговым выходом.

Вам следует проконсультироваться с схемой вашей платы, чтобы подтвердить, что этот GPIO подключен к управляющему входу регулятора.


Что касается части X относительно включения/выключения регулятора:

Программный контроль выхода регулятора документируется в Documentation/power/regulator/consumer.txt

Пользовательский драйвер может получить доступ к своему регулятору питания, позвонив: -

regulator = regulator_get(dev, "Vcc");

Пользователь может включить свой источник питания, позвонив: -

int regulator_enable(regulator);

Потребитель может отключить его поставку, когда он больше не нужен, позвонив: -

int regulator_disable(regulator);

"Пользователь" - это электронное устройство, которое подает питание регулятором.

По-видимому, предполагаемая структура имеет собственный потребительский драйвер и управляет его регулятором и не позволяет внешнему интерфейсу (например, sysfs) вмешиваться в этот "потребительский драйвер". Если вы настаиваете на управлении пользовательской правкой, вы можете реализовать интерфейс ioctl() или sysfs для "потребительского драйвера" (чтобы избежать конфликта/конфликта с драйвером регулятора).

В этом случае у меня отсутствует способ включить и выключить его

То, что вы действительно ищете, - это (верхний уровень) управление питанием, и у него есть своя структура, из которых регуляторы являются более низким уровнем (который обычно недоступен для пользователя контроль). Вы должны изучить Documentation/power/devices.txt.

Ответ 2

Я не очень хорошо знаком с ядром регулятора в ядре, но мне кажется, что интерфейс регулятора должен предоставить вам доступ к GPIO иначе, чем стандартный метод GPIO для экспорта.

Я не рассматривал это, но возможно, что интерфейс регулятора открывает персональное устройство в пользовательском пространстве для контроля над регулятором. (Не держите меня за это)

Я вижу в документации и в исходном коде драйвера drivers/regulator/fixed.c, что GPIO не является обязательным атрибутом DT. Вы можете оставить его вне DT, и в этом случае драйвер никогда не получит ваш GPIO, а затем вы можете вручную управлять им через стандартный экспортный интерфейс GPIO.