Enable pullup GPIO

匿名 (未验证) 提交于 2019-12-03 00:56:02

问题:

im working with a AT91SAM9G25 board which has 4 PIO controller managing up to 32 programmable I/O lines. Each pin is configurable as either a general-purpose I/O line only or as an I/O line multiplexed up to two peripheral I/Os. So, for example, according with the documentation (SAM9G25, page 14), signal PC0 can be multiplexed such a general purpose I/O line or as the ISI_D0 line of the VIDEO_ATMEL_ISI (ISI of Image Sensor Interface).

The reset state of all GPIO lines is with direction IN and Pullup enabled. when i use GPIOLIB via sysfs i read a "1" value as INPUT in several GPIOs due to pullup. Is this a normal safe state of GPIO (INPUT with Pullup resistor) at reset in several boards when they can be multiplexed with other Peripherals?. I dont see how i can disable the pullup via userspace with GPIOLIB. So for example, i see that when kernel is booting it checks if the Image Sensor Peripheral is enabled at kernel or as a module and if so it sets the PC0 to Peripheral B. This is in the kernel sources at /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 

Then if i dont enable ISI support in kernel i can use the PC0 signal as GPIO line. This is the /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 

And this is /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 

The above output show that PIOA0 is multiplexed to Peripheral A (TXD0 UART Line), and for example PIOC20 is cleared, but the documentation says that all GPIO lines at reset state are INPUTS with pullup and i dont find where kernel or u-boot disable the pullup of this GPIO (maybe GPIOs keep their state if none touch his registers?)

But he main question is, how can i clear the pullup register of the GPIO lines? I find in kernel sources that /arch/arm/mach-at91/at91sam9x5_devices.c uses this function implemented in 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); 

Header arch/arm/mach-at91/include/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__ */ 

How can use this functions with my toolchain, or should i make a kernel module?

Thanks

PD: Sorry for any mistakes in my english, i know i need to improve it.

回答1:

Maybe you can just leave the pullup alone. I've used GPIO on OMAP SoCs, at lowest level there are similar pin mux options, but it wasn't necessary to worry about pullups. Usually whatever is driving it can sink enough current (this is EE/circuit viewpoint, don't worry if you are unfamiliar). Floating input could be random and troublesome; pulled up high should be OK.

I would not think you should need to make a kernel module. I'd suggest you experiment using existing user mode interfaces. Your kernel should already have low-level drivers hooked in to provide access through sysfs. Refer to sysfs, omap gpio. I don't think I've seen pullup options in sysfs. If you get something working and need to call it from C code, then you can look for APIs, or just use system().



回答2:

On newer kernels using device tree you can control it by recompiling the devicetree "blob" and do not need to change the kernel or write a kernel driver.

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

But it would be really sweet if pinctrl had a user space interface like the gpio so the complete solution in controlling pin's was user space controlled.



文章来源: Enable pullup GPIO
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!