Включить подтягивание GPIO

Я работаю с платой AT91SAM9G25, которая имеет 4 контроллера PIO, управляющих до 32 программируемыми линиями ввода / вывода. Каждый вывод конфигурируется либо как линия ввода / вывода общего назначения, либо как линия ввода / вывода, мультиплексированная до двух периферийных входов / выходов. Так, например, в соответствии с документацией ( SAM9G25, стр. 14), сигнал PC0 может быть мультиплексирован, например, в линию ввода / вывода общего назначения или в качестве линии ISI_D0 VIDEO_ATMEL_ISI (ISI интерфейса датчика изображения).

╔════════════╦════════════╦════════════╦════════════╦════════════╗
║  Primary   ║ Alternates ║   PeripA   ║   PeripB   ║  PeripC    ║
╠════════════╬════════════╬════════════╬════════════╬════════════╣
║ Signal/Dir ║ Signal/Dir ║ Signal/Dir ║ Signal/Dir ║ Signal/Dir ║
║ ---------  ║ ---------  ║ ---------  ║ ---------  ║ ---------  ║
║ PC0 / I/O  ║            ║            ║ ISI_D0 / I ║            ║
╚════════════╩════════════╩════════════╩════════════╩════════════╝

Состояние сброса всех линий GPIO с включенным направлением IN и Pullup. Когда я использую GPIOLIB через sysfs, я читаю значение "1" как INPUT в нескольких GPIO из-за подтягивания. Является ли это нормальным безопасным состоянием GPIO (INPUT с подтягивающим резистором) при сбросе на нескольких платах, когда они могут быть мультиплексированы с другими периферийными устройствами? Я не вижу, как я могу отключить подтягивание через пользовательское пространство с GPIOLIB. Так, например, я вижу, что когда ядро ​​загружается, оно проверяет, включена ли периферия датчика изображения в ядре или как модуль, и если да, то устанавливает PC0 в Периферийное устройство B. Это находится в исходных кодах ядра в /arch/arm/mach-at91/at91sam9x5_devices.c

#if defined(CONFIG_VIDEO_ATMEL_ISI) || defined(CONFIG_VIDEO_ATMEL_ISI_MODULE)
....
         at91_set_B_periph(AT91_PIN_PC0, 0);    /* ISI_D0 */
...
#endif

Тогда, если я не включу поддержку ISI в ядре, я могу использовать сигнал PC0 в качестве линии GPIO. Это /sys/kernel/debug/gpio:

    # cat /sys/kernel/debug/gpio

    GPIOs 32-63, A:

    GPIOs 64-95, B:
    [atmel_usba_udc] GPIOB16: [gpio] set
    [d1] GPIOB18: [gpio] clear

    GPIOs 96-127, C:

    GPIOs 128-159, D:
    [ohci_vbus] GPIOD19: [gpio] clear
    [ohci_vbus] GPIOD20: [gpio] clear
    [d2] GPIOD21: [gpio] set

И это /sys/kernel/debug/at91_gpio

    # cat /sys/kernel/debug/at91_gpio

    Pin     PIOA            PIOB            PIOC            PIOD

    0:      A               A               GPIO:1          A
    1:      A               A               GPIO:1          A
    2:      GPIO:1          A               GPIO:1          A
    3:      GPIO:1          A               GPIO:1          A
    4:      GPIO:1          A               GPIO:1          GPIO:1
    5:      GPIO:1          A               GPIO:1          GPIO:1
    6:      GPIO:1          A               GPIO:1          A
    7:      B               A               GPIO:1          A
    8:      GPIO:1          GPIO:1          GPIO:1          A
    9:      A               A               GPIO:1          A
    10:     A               A               GPIO:1          A
    11:     A               GPIO:1          GPIO:1          A
    12:     A               GPIO:1          GPIO:1          A
    13:     A               GPIO:1          GPIO:1          A
    14:     A               GPIO:1          GPIO:1          GPIO:1
    15:     GPIO:1          GPIO:1          GPIO:1          A
    16:     GPIO:1          GPIO:1          GPIO:0          A
    17:     GPIO:1          GPIO:1          GPIO:1          A
    18:     GPIO:1          GPIO:1          GPIO:1          A
    19:     GPIO:1          A               GPIO:1          GPIO:0
    20:     GPIO:1          A               GPIO:0          GPIO:0
    21:     GPIO:1          A               GPIO:0          GPIO:1
    22:     GPIO:1          A               GPIO:1          A
    23:     GPIO:1          A               GPIO:1          A
    24:     GPIO:1          A               GPIO:1          A
    25:     GPIO:1          A               GPIO:1          A
    26:     GPIO:1          A               GPIO:1          A
    27:     GPIO:0          A               GPIO:1          A
    28:     GPIO:1          A               GPIO:0          A
    29:     GPIO:1          A               GPIO:0          A
    30:     GPIO:1          A               GPIO:1          A
    31:     GPIO:1          A               GPIO:1          A

Вышеуказанные выходные данные показывают, что PIOA0 мультиплексируется в периферийное устройство A (линия UART TXD0), и, например, PIOC20 очищается, но в документации говорится, что все линии GPIO в состоянии сброса являются входами с pullup, и я не могу найти, где отключение ядра или u-boot подтягивание этого GPIO (может быть, GPIO сохраняют свое состояние, если никто не касается его регистров?)

Но он главный вопрос, как я могу очистить регистр подтягивания линий GPIO? Я нахожу в исходниках ядра, что /arch/arm/mach-at91/at91sam9x5_devices.c использует эту функцию, реализованную в linux-2.6.39/arch/arm/mach-at91/gpio.c .

    /*
    * enable/disable the pull-down.
    * If pull-up already enabled while calling the function, we disable it.
    */
    int __init_or_module at91_set_pulldown(unsigned pin, int is_on)
    {
        void __iomem    *pio = pin_to_controller(pin);
        unsigned    mask = pin_to_mask(pin);

        if (!pio || !cpu_has_pio3())
            return -EINVAL;

        /* Disable pull-up anyway */
        __raw_writel(mask, pio + PIO_PUDR);
        __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR));
        return 0;
    }
    EXPORT_SYMBOL(at91_set_pulldown);

Арка для жатки / на руку / mach-at91 / включает /mach/gpio.h

    #ifndef __ASSEMBLY__
    /* setup setup routines, called from board init or driver probe() */
    .....
    extern int __init_or_module at91_set_pulldown(unsigned pin, int is_on);
    .....
    #endif  /* __ASSEMBLY__ */

Как использовать эти функции с моей цепочкой инструментов, или я должен сделать модуль ядра?

Спасибо

PD: Извините за любые ошибки в моем английском, я знаю, что мне нужно его улучшить.

2 ответа

Решение

Может быть, вы можете просто оставить подтягивание в покое. Я использовал GPIO на OMAP SoC, на самом низком уровне есть аналогичные варианты pin mux, но не нужно было беспокоиться о подтягиваниях. Обычно все, что движет, может потреблять достаточно тока (это точка зрения EE/ схема, не беспокойтесь, если вы незнакомы). Плавающий ввод может быть случайным и хлопотным; высоко поднятый должен быть в порядке.

Я не думаю, что вам нужно сделать модуль ядра. Я бы посоветовал вам поэкспериментировать с использованием существующих интерфейсов пользовательского режима. В вашем ядре уже должны быть подключены низкоуровневые драйверы для предоставления доступа через sysfs. Обратитесь к sysfs, omap gpio. Я не думаю, что видел варианты подтягивания в sysfs. Если вы получаете что-то работающее и вам нужно вызвать его из кода на C, тогда вы можете искать API или просто использовать system().

В более новых ядрах, использующих дерево устройств, вы можете управлять им, перекомпилировав "blob" devicetree, и не нужно менять ядро ​​или писать драйвер ядра.

http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt

Но было бы очень приятно, если бы у pinctrl был интерфейс пользовательского пространства, такой как gpio, поэтому полное решение для управления контактами было бы под контролем пользовательского пространства.

Другие вопросы по тегам