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.