gpio: port to am335x
* port libgpio to am335x. * increase NR_IRQ to 16 to avoid too many IRQs requested error. * move gpio binary to /sbin (that's where mount looks for drivers). * fix bug that re-enabled banks that were disabled due to bad revision. * fix padconf masks for dm37xx in gpio driver (should be 16-bit). * fix a few typos in README.txt and comments. Change-Id: I32374415a97135174c5224f76374a870909fa90c
This commit is contained in:
		
							parent
							
								
									74bc88581c
								
							
						
					
					
						commit
						0a9eab0bb6
					
				@ -13,6 +13,7 @@
 | 
			
		||||
./multiboot/mod10_vm			minix-sys
 | 
			
		||||
./multiboot/mod11_pfs			minix-sys
 | 
			
		||||
./multiboot/mod12_init			minix-sys
 | 
			
		||||
./sbin/gpio				minix-sys
 | 
			
		||||
./usr/bin/eepromread			minix-sys
 | 
			
		||||
./usr/include/arm			minix-sys
 | 
			
		||||
./usr/include/arm/aeabi.h		minix-sys
 | 
			
		||||
@ -108,7 +109,6 @@
 | 
			
		||||
./usr/sbin/bmp085			minix-sys
 | 
			
		||||
./usr/sbin/cat24c256			minix-sys
 | 
			
		||||
./usr/sbin/fb				minix-sys
 | 
			
		||||
./usr/sbin/gpio				minix-sys
 | 
			
		||||
./usr/sbin/i2c				minix-sys
 | 
			
		||||
./usr/sbin/lan8710a			minix-sys
 | 
			
		||||
./usr/sbin/random			minix-sys
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
PROG=	gpio
 | 
			
		||||
SRCS=	gpio.c
 | 
			
		||||
 | 
			
		||||
DPADD+=	${LIBBLOCKDRIVER} ${LIBSYS}
 | 
			
		||||
DPADD+=	${LIBBLOCKDRIVER} ${LIBSYS} ${LIBGPIO} ${LIBCLKCONF}
 | 
			
		||||
LDADD+=	-lvtreefs -lsys -lgpio -lclkconf
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
@ -11,6 +11,6 @@ CPPFLAGS+= -D_SYSTEM=1
 | 
			
		||||
 | 
			
		||||
MAN=
 | 
			
		||||
 | 
			
		||||
BINDIR?= /usr/sbin
 | 
			
		||||
BINDIR?= /sbin
 | 
			
		||||
 | 
			
		||||
.include <minix.service.mk>
 | 
			
		||||
 | 
			
		||||
@ -1,35 +1,35 @@
 | 
			
		||||
General Purpose Input and Output
 | 
			
		||||
 | 
			
		||||
To make MINIX more usable on embedded hardware we need some way to access the
 | 
			
		||||
GPIO features of the system on chip’s. Generally System on Chips (SoC) designs
 | 
			
		||||
provide some way configure pads to perform basic Input/Output configuration on
 | 
			
		||||
selected ports. These ports are also usually grouped into a bank. The end
 | 
			
		||||
To make MINIX more usable on embedded hardware, we need some way to access the
 | 
			
		||||
GPIO features of the system on a chip. Generally System on Chips (SoC) designs
 | 
			
		||||
provide some way to configure pads to perform basic Input/Output operations on
 | 
			
		||||
selected ports. These ports are also usually grouped into banks. The end
 | 
			
		||||
result is that you have a functional general input output block where you need
 | 
			
		||||
to configure some the following functions.
 | 
			
		||||
 | 
			
		||||
Functional requirements
 | 
			
		||||
Functional Requirements
 | 
			
		||||
 | 
			
		||||
We envision that the short term usage of the GPIO library will be booth input
 | 
			
		||||
We envision that the short term usage of the GPIO library will be both input
 | 
			
		||||
and output handling. Input handling as we want to be able to listen to button
 | 
			
		||||
presses and genrate key events and output handling because we want to be able
 | 
			
		||||
to control leds.
 | 
			
		||||
presses and generate key events, and output handling because we want to be able
 | 
			
		||||
to control LEDs.
 | 
			
		||||
 | 
			
		||||
GPIO required functionality
 | 
			
		||||
-Configure pins as input or output.
 | 
			
		||||
-Configure the impedance of the pins.
 | 
			
		||||
-Get or set the values of the pins(possibly in a single call).
 | 
			
		||||
-Get or set the values of the pins (possibly in a single call).
 | 
			
		||||
-Configure interrupt levels for input pins.
 | 
			
		||||
-Configure debouncing of pins.
 | 
			
		||||
 | 
			
		||||
Configure debouncing of pins.
 | 
			
		||||
 | 
			
		||||
Additional kernel requirements
 | 
			
		||||
Additional kernel requirements:
 | 
			
		||||
-Manage the GPIO resources (who may access what)
 | 
			
		||||
-Access the GPIO pins from within driver (for the keyboard)
 | 
			
		||||
-Access the GPIO pins from within userland (for toggeling leds)
 | 
			
		||||
-Access the GPIO pins from within userland (for toggling LEDs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Usage: 
 | 
			
		||||
You have to manualy mount the gpio fs using the following command
 | 
			
		||||
You have to manually mount the gpio fs using the following command
 | 
			
		||||
 | 
			
		||||
# mkdir -p /gpio
 | 
			
		||||
# mount -t gpio none /gpio
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -165,15 +165,34 @@ init_hook(void)
 | 
			
		||||
		log_warn(&log, "Failed to init gpio driver\n");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef AM335X
 | 
			
		||||
 | 
			
		||||
	/* Export GPIO3_19 (P9-27 on BBB) output as LCD_EN */
 | 
			
		||||
 | 
			
		||||
	sys_padconf(CONTROL_CONF_MCASP0_FSR, 0xffffffff,
 | 
			
		||||
	    (CONTROL_CONF_PUTYPESEL | CONTROL_CONF_MUXMODE(7)));
 | 
			
		||||
 | 
			
		||||
	add_gpio_inode("LCD_EN", (32 * 3) + 19, GPIO_MODE_OUTPUT);
 | 
			
		||||
 | 
			
		||||
	/* Export GPIO1_17 (P9-23 on BBB) input as RIGHT */
 | 
			
		||||
 | 
			
		||||
	/* assumes external pull-up resistor (10K) */
 | 
			
		||||
	sys_padconf(CONTROL_CONF_SPI0_D0, 0xffffffff, (CONTROL_CONF_RXACTIVE |
 | 
			
		||||
	    CONTROL_CONF_PUDEN | CONTROL_CONF_MUXMODE(7)));
 | 
			
		||||
	
 | 
			
		||||
	add_gpio_inode("RIGHT", (32 * 1) + 17, GPIO_MODE_INPUT);
 | 
			
		||||
 | 
			
		||||
#elif DM37XX
 | 
			
		||||
 | 
			
		||||
	add_gpio_inode("USR0", 149, GPIO_MODE_OUTPUT);
 | 
			
		||||
	add_gpio_inode("USR1", 150, GPIO_MODE_OUTPUT);
 | 
			
		||||
	add_gpio_inode("Button", 4, GPIO_MODE_INPUT);
 | 
			
		||||
 | 
			
		||||
	/* configure GPIO_144 to be exported */
 | 
			
		||||
	sys_padconf(CONTROL_PADCONF_UART2_CTS, 0xff,
 | 
			
		||||
	sys_padconf(CONTROL_PADCONF_UART2_CTS, 0x0000ffff,
 | 
			
		||||
	    PADCONF_MUXMODE(4) | PADCONF_PULL_MODE_PD_EN |
 | 
			
		||||
	    PADCONF_INPUT_ENABLE(1));
 | 
			
		||||
	sys_padconf(CONTROL_PADCONF_MMC2_DAT6, 0xff00,
 | 
			
		||||
	sys_padconf(CONTROL_PADCONF_MMC2_DAT6, 0xffff0000,
 | 
			
		||||
	    (PADCONF_MUXMODE(4) | PADCONF_PULL_MODE_PD_EN |
 | 
			
		||||
		PADCONF_INPUT_ENABLE(1)) << 16);
 | 
			
		||||
 | 
			
		||||
@ -181,6 +200,8 @@ init_hook(void)
 | 
			
		||||
	add_gpio_inode("BigRedButton", 144, GPIO_MODE_INPUT);
 | 
			
		||||
	add_gpio_inode("BigRedButtonLed", 139, GPIO_MODE_OUTPUT);
 | 
			
		||||
 | 
			
		||||
#endif /* DM37XX */
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
@ -197,7 +218,7 @@ static int
 | 
			
		||||
 | 
			
		||||
	if (gpio_cbdata->type == GPIO_CB_ON
 | 
			
		||||
	    || gpio_cbdata->type == GPIO_CB_OFF) {
 | 
			
		||||
		/* turn on or of */
 | 
			
		||||
		/* turn on or off */
 | 
			
		||||
		if (gpio_set(gpio_cbdata->gpio,
 | 
			
		||||
			(gpio_cbdata->type == GPIO_CB_ON) ? 1 : 0)) {
 | 
			
		||||
			*len = 0;
 | 
			
		||||
 | 
			
		||||
@ -585,12 +585,18 @@ service gpio
 | 
			
		||||
		PADCONF		# 57
 | 
			
		||||
	;
 | 
			
		||||
	irq	
 | 
			
		||||
		29	# GPIO module 1
 | 
			
		||||
		30	# GPIO module 2
 | 
			
		||||
		31	# GPIO module 3 
 | 
			
		||||
		32	# GPIO module 4 
 | 
			
		||||
		33	# GPIO module 5 
 | 
			
		||||
		34	# GPIO module 6
 | 
			
		||||
		29	# GPIO module 1 (dm37xx)
 | 
			
		||||
		30	# GPIO module 2 (dm37xx)
 | 
			
		||||
		31	# GPIO module 3 (dm37xx)
 | 
			
		||||
		32	# GPIO module 4 (dm37xx) / module 2a (am335x)
 | 
			
		||||
		33	# GPIO module 5 (dm37xx) / module 2b (am335x)
 | 
			
		||||
		34	# GPIO module 6 (dm37xx)
 | 
			
		||||
		62	# GPIO module 3a (am335x)
 | 
			
		||||
		63	# GPIO module 3b (am335x)
 | 
			
		||||
		96	# GPIO module 0a (am335x)
 | 
			
		||||
		97	# GPIO module 0b (am335x)
 | 
			
		||||
		98	# GPIO module 1a (am335x)
 | 
			
		||||
		99	# GPIO module 1b (am335x)
 | 
			
		||||
	;		
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -63,7 +63,7 @@
 | 
			
		||||
#define NR_MEM_RANGE	20
 | 
			
		||||
 | 
			
		||||
/* Max. number of IRQs that can be assigned to a process */
 | 
			
		||||
#define NR_IRQ	8
 | 
			
		||||
#define NR_IRQ	16
 | 
			
		||||
 | 
			
		||||
/* Scheduling priorities. Values must start at zero (highest
 | 
			
		||||
 * priority) and increment.
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@
 | 
			
		||||
#include <minix/mmio.h>
 | 
			
		||||
#include <minix/gpio.h>
 | 
			
		||||
#include <minix/clkconf.h>
 | 
			
		||||
#include <minix/type.h>
 | 
			
		||||
 | 
			
		||||
/* system headers */
 | 
			
		||||
#include <sys/mman.h>
 | 
			
		||||
@ -19,6 +20,7 @@
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
/* local headers */
 | 
			
		||||
#include "gpio_omap.h"
 | 
			
		||||
 | 
			
		||||
/* used for logging */
 | 
			
		||||
static struct log log = {
 | 
			
		||||
@ -57,107 +59,171 @@ struct omap_gpio_bank
 | 
			
		||||
	uint32_t irq_nr;	/* irq number */
 | 
			
		||||
	uint32_t base_address;
 | 
			
		||||
	int32_t disabled;
 | 
			
		||||
	int irq_id;		/* orignhal hook id??? */
 | 
			
		||||
	int irq_id;		/* original hook id??? */
 | 
			
		||||
	int irq_hook_id;	/* hook id */
 | 
			
		||||
	uint32_t inter_values;	/* values when the interrupt was called */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define GPIO1_BASE (0x48310000)
 | 
			
		||||
#define GPIO2_BASE (0x49050000)
 | 
			
		||||
#define GPIO3_BASE (0x49052000)
 | 
			
		||||
#define GPIO4_BASE (0x49054000)
 | 
			
		||||
#define GPIO5_BASE (0x49056000)
 | 
			
		||||
#define GPIO6_BASE (0x49058000)
 | 
			
		||||
#define GPIO1_IRQ  29		/* GPIO module 1 */
 | 
			
		||||
#define GPIO2_IRQ  30		/* GPIO module 2 */
 | 
			
		||||
#define GPIO3_IRQ  31		/* GPIO module 3 */
 | 
			
		||||
#define GPIO4_IRQ  32		/* GPIO module 4 */
 | 
			
		||||
#define GPIO5_IRQ  33		/* GPIO module 5 */
 | 
			
		||||
#define GPIO6_IRQ  34		/* GPIO module 6 */
 | 
			
		||||
#define GPIO1_IRQ_HOOK_ID 0
 | 
			
		||||
#define GPIO2_IRQ_HOOK_ID 1
 | 
			
		||||
#define GPIO3_IRQ_HOOK_ID 2
 | 
			
		||||
#define GPIO4_IRQ_HOOK_ID 3
 | 
			
		||||
#define GPIO5_IRQ_HOOK_ID 4
 | 
			
		||||
#define GPIO6_IRQ_HOOK_ID 5
 | 
			
		||||
 | 
			
		||||
#define GPIO_IRQSTATUS1 (0x18)
 | 
			
		||||
#define GPIO_IRQENABLE1 (0x01C)
 | 
			
		||||
#define GPIO_DATAOUT (0x3c)
 | 
			
		||||
#define GPIO_DATAIN (0x38)
 | 
			
		||||
#define GPIO_OE    (0x34)	/* Output Data Enable */
 | 
			
		||||
#define GPIO_RISINGDETECT1 (0x048)
 | 
			
		||||
#define GPIO_FALLINGDETECT1 (0x04c)
 | 
			
		||||
#define GPIO_CLEARDATAOUT (0x90)
 | 
			
		||||
#define GPIO_SETDATAOUT (0x94)
 | 
			
		||||
 | 
			
		||||
static struct omap_gpio_bank omap_gpio_banks[] = {
 | 
			
		||||
#ifdef AM335X
 | 
			
		||||
	{
 | 
			
		||||
		    .name = "GPIO1",
 | 
			
		||||
		    .register_address = GPIO1_BASE,
 | 
			
		||||
		    .irq_nr = GPIO1_IRQ,
 | 
			
		||||
		    .name = "GPIO0",
 | 
			
		||||
		    .register_address = AM335X_GPIO0_BASE,
 | 
			
		||||
		    .irq_nr = AM335X_GPIO0A_IRQ,
 | 
			
		||||
		    .base_address = 0,
 | 
			
		||||
		    .disabled = 0,
 | 
			
		||||
		    .irq_id = GPIO1_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = GPIO1_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_id = AM335X_GPIO0A_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = AM335X_GPIO0A_IRQ_HOOK_ID,
 | 
			
		||||
 | 
			
		||||
	    },
 | 
			
		||||
	{
 | 
			
		||||
		    .name = "GPIO1",
 | 
			
		||||
		    .register_address = AM335X_GPIO1_BASE,
 | 
			
		||||
		    .irq_nr = AM335X_GPIO1A_IRQ,
 | 
			
		||||
		    .base_address = 0,
 | 
			
		||||
		    .disabled = 0,
 | 
			
		||||
		    .irq_id = AM335X_GPIO1A_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = AM335X_GPIO1A_IRQ_HOOK_ID,
 | 
			
		||||
 | 
			
		||||
	    },
 | 
			
		||||
	{
 | 
			
		||||
		    .name = "GPIO2",
 | 
			
		||||
		    .register_address = GPIO2_BASE,
 | 
			
		||||
		    .irq_nr = GPIO2_IRQ,
 | 
			
		||||
		    .register_address = AM335X_GPIO2_BASE,
 | 
			
		||||
		    .irq_nr = AM335X_GPIO2A_IRQ,
 | 
			
		||||
		    .base_address = 0,
 | 
			
		||||
		    .disabled = 0,
 | 
			
		||||
		    .irq_id = GPIO2_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = GPIO2_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_id = AM335X_GPIO2A_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = AM335X_GPIO2A_IRQ_HOOK_ID,
 | 
			
		||||
 | 
			
		||||
	    },
 | 
			
		||||
	{
 | 
			
		||||
		    .name = "GPIO3",
 | 
			
		||||
		    .register_address = GPIO3_BASE,
 | 
			
		||||
		    .irq_nr = GPIO3_IRQ,
 | 
			
		||||
		    .register_address = AM335X_GPIO3_BASE,
 | 
			
		||||
		    .irq_nr = AM335X_GPIO3A_IRQ,
 | 
			
		||||
		    .base_address = 0,
 | 
			
		||||
		    .disabled = 0,
 | 
			
		||||
		    .irq_id = GPIO3_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = GPIO3_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_id = AM335X_GPIO3A_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = AM335X_GPIO3A_IRQ_HOOK_ID,
 | 
			
		||||
 | 
			
		||||
	    },
 | 
			
		||||
#elif DM37XX
 | 
			
		||||
	{
 | 
			
		||||
		    .name = "GPIO1",
 | 
			
		||||
		    .register_address = DM37XX_GPIO1_BASE,
 | 
			
		||||
		    .irq_nr = DM37XX_GPIO1_IRQ,
 | 
			
		||||
		    .base_address = 0,
 | 
			
		||||
		    .disabled = 0,
 | 
			
		||||
		    .irq_id = DM37XX_GPIO1_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = DM37XX_GPIO1_IRQ_HOOK_ID,
 | 
			
		||||
	    },
 | 
			
		||||
	{
 | 
			
		||||
		    .name = "GPIO2",
 | 
			
		||||
		    .register_address = DM37XX_GPIO2_BASE,
 | 
			
		||||
		    .irq_nr = DM37XX_GPIO2_IRQ,
 | 
			
		||||
		    .base_address = 0,
 | 
			
		||||
		    .disabled = 0,
 | 
			
		||||
		    .irq_id = DM37XX_GPIO2_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = DM37XX_GPIO2_IRQ_HOOK_ID,
 | 
			
		||||
	    },
 | 
			
		||||
	{
 | 
			
		||||
		    .name = "GPIO3",
 | 
			
		||||
		    .register_address = DM37XX_GPIO3_BASE,
 | 
			
		||||
		    .irq_nr = DM37XX_GPIO3_IRQ,
 | 
			
		||||
		    .base_address = 0,
 | 
			
		||||
		    .disabled = 0,
 | 
			
		||||
		    .irq_id = DM37XX_GPIO3_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = DM37XX_GPIO3_IRQ_HOOK_ID,
 | 
			
		||||
	    },
 | 
			
		||||
	{
 | 
			
		||||
		    .name = "GPIO4",
 | 
			
		||||
		    .register_address = GPIO4_BASE,
 | 
			
		||||
		    .irq_nr = GPIO4_IRQ,
 | 
			
		||||
		    .register_address = DM37XX_GPIO4_BASE,
 | 
			
		||||
		    .irq_nr = DM37XX_GPIO4_IRQ,
 | 
			
		||||
		    .base_address = 0,
 | 
			
		||||
		    .disabled = 0,
 | 
			
		||||
		    .irq_id = GPIO4_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = GPIO4_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_id = DM37XX_GPIO4_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = DM37XX_GPIO4_IRQ_HOOK_ID,
 | 
			
		||||
	    },
 | 
			
		||||
	{
 | 
			
		||||
		    .name = "GPIO5",
 | 
			
		||||
		    .register_address = GPIO5_BASE,
 | 
			
		||||
		    .irq_nr = GPIO5_IRQ,
 | 
			
		||||
		    .register_address = DM37XX_GPIO5_BASE,
 | 
			
		||||
		    .irq_nr = DM37XX_GPIO5_IRQ,
 | 
			
		||||
		    .base_address = 0,
 | 
			
		||||
		    .disabled = 0,
 | 
			
		||||
		    .irq_id = GPIO5_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = GPIO5_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_id = DM37XX_GPIO5_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = DM37XX_GPIO5_IRQ_HOOK_ID,
 | 
			
		||||
	    },
 | 
			
		||||
	{
 | 
			
		||||
		    .name = "GPIO6",
 | 
			
		||||
		    .register_address = GPIO6_BASE,
 | 
			
		||||
		    .irq_nr = GPIO6_IRQ,
 | 
			
		||||
		    .register_address = DM37XX_GPIO6_BASE,
 | 
			
		||||
		    .irq_nr = DM37XX_GPIO6_IRQ,
 | 
			
		||||
		    .base_address = 0,
 | 
			
		||||
		    .disabled = 0,
 | 
			
		||||
		    .irq_id = GPIO6_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = GPIO6_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_id = DM37XX_GPIO6_IRQ_HOOK_ID,
 | 
			
		||||
		    .irq_hook_id = DM37XX_GPIO6_IRQ_HOOK_ID,
 | 
			
		||||
	    },
 | 
			
		||||
#endif /* DM37XX */
 | 
			
		||||
	{NULL, 0, 0, 0, 0, 0, 0, 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define GPIO_REVISION 0x00
 | 
			
		||||
#define GPIO_REVISION_MAJOR(X) ((X & 0xF0) >> 4)
 | 
			
		||||
#define GPIO_REVISION_MINOR(X) (X & 0XF)
 | 
			
		||||
#define NBANKS ((int)((sizeof(omap_gpio_banks)/sizeof(omap_gpio_banks[0])) - 1))
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Defines the set of registers. There is a lot of commonality between the
 | 
			
		||||
 * AM335X and DM37XX gpio registers. To avoid ifdefs everywhere, we define
 | 
			
		||||
 * a central register set and only use ifdefs where they differ.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct gpio_omap_registers {
 | 
			
		||||
	vir_bytes REVISION;
 | 
			
		||||
	vir_bytes IRQENABLE;
 | 
			
		||||
	vir_bytes IRQSTATUS;
 | 
			
		||||
	vir_bytes DATAOUT;
 | 
			
		||||
	vir_bytes DATAIN;
 | 
			
		||||
	vir_bytes OE;
 | 
			
		||||
	vir_bytes RISINGDETECT;
 | 
			
		||||
	vir_bytes FALLINGDETECT;
 | 
			
		||||
	vir_bytes CLEARDATAOUT;
 | 
			
		||||
	vir_bytes SETDATAOUT;
 | 
			
		||||
} gpio_omap_regs_t;
 | 
			
		||||
 | 
			
		||||
/* Define the registers for each chip */
 | 
			
		||||
 | 
			
		||||
gpio_omap_regs_t gpio_omap_dm37xx = {
 | 
			
		||||
	.REVISION = DM37XX_GPIO_REVISION,
 | 
			
		||||
	.IRQENABLE = DM37XX_GPIO_IRQENABLE1,
 | 
			
		||||
	.IRQSTATUS = DM37XX_GPIO_IRQSTATUS1,
 | 
			
		||||
	.DATAOUT = DM37XX_GPIO_DATAOUT,
 | 
			
		||||
	.DATAIN = DM37XX_GPIO_DATAIN,
 | 
			
		||||
	.OE = DM37XX_GPIO_OE,
 | 
			
		||||
	.RISINGDETECT = DM37XX_GPIO_RISINGDETECT1,
 | 
			
		||||
	.FALLINGDETECT = DM37XX_GPIO_FALLINGDETECT1,
 | 
			
		||||
	.CLEARDATAOUT = DM37XX_GPIO_CLEARDATAOUT,
 | 
			
		||||
	.SETDATAOUT = DM37XX_GPIO_SETDATAOUT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
gpio_omap_regs_t gpio_omap_am335x = {
 | 
			
		||||
	.REVISION = AM335X_GPIO_REVISION,
 | 
			
		||||
	.IRQENABLE = AM335X_GPIO_IRQSTATUS_SET_0,
 | 
			
		||||
	.IRQSTATUS = AM335X_GPIO_IRQSTATUS_0,
 | 
			
		||||
	.DATAOUT = AM335X_GPIO_DATAOUT,
 | 
			
		||||
	.DATAIN = AM335X_GPIO_DATAIN,
 | 
			
		||||
	.OE = AM335X_GPIO_OE,
 | 
			
		||||
	.RISINGDETECT = AM335X_GPIO_RISINGDETECT,
 | 
			
		||||
	.FALLINGDETECT = AM335X_GPIO_FALLINGDETECT,
 | 
			
		||||
	.CLEARDATAOUT = AM335X_GPIO_CLEARDATAOUT,
 | 
			
		||||
	.SETDATAOUT = AM335X_GPIO_SETDATAOUT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef AM335X
 | 
			
		||||
static gpio_omap_regs_t *regs = &gpio_omap_am335x;
 | 
			
		||||
#elif DM37XX
 | 
			
		||||
static gpio_omap_regs_t *regs = &gpio_omap_dm37xx;
 | 
			
		||||
#endif /* DM37XX */
 | 
			
		||||
 | 
			
		||||
static struct omap_gpio_bank *
 | 
			
		||||
omap_gpio_bank_get(int gpio_nr)
 | 
			
		||||
{
 | 
			
		||||
	struct omap_gpio_bank *bank;
 | 
			
		||||
	assert(gpio_nr >= 0 && gpio_nr <= 32 * 6);
 | 
			
		||||
	assert(gpio_nr >= 0 && gpio_nr <= 32 * NBANKS);
 | 
			
		||||
	bank = &omap_gpio_banks[gpio_nr / 32];
 | 
			
		||||
	return bank;
 | 
			
		||||
}
 | 
			
		||||
@ -167,7 +233,7 @@ omap_gpio_claim(char *owner, int nr, struct gpio **gpio)
 | 
			
		||||
{
 | 
			
		||||
	log_trace(&log, "%s s claiming %d\n", owner, nr);
 | 
			
		||||
 | 
			
		||||
	if (nr < 0 && nr >= 32 * 6) {
 | 
			
		||||
	if (nr < 0 && nr >= 32 * NBANKS) {
 | 
			
		||||
		log_warn(&log, "%s is claiming unknown GPIO number %d\n",
 | 
			
		||||
		    owner, nr);
 | 
			
		||||
		return EINVAL;
 | 
			
		||||
@ -197,17 +263,17 @@ omap_gpio_pin_mode(struct gpio *gpio, int mode)
 | 
			
		||||
	bank = omap_gpio_bank_get(gpio->nr);
 | 
			
		||||
	log_debug(&log,
 | 
			
		||||
	    "pin mode bank %s, base address 0x%x -> register address (0x%x,0x%x,0x%x)\n",
 | 
			
		||||
	    bank->name, bank->base_address, bank->register_address, GPIO_OE,
 | 
			
		||||
	    bank->register_address + GPIO_OE);
 | 
			
		||||
	    bank->name, bank->base_address, bank->register_address, regs->OE,
 | 
			
		||||
	    bank->register_address + regs->OE);
 | 
			
		||||
 | 
			
		||||
	if (mode == GPIO_MODE_OUTPUT) {
 | 
			
		||||
		set32(bank->base_address + GPIO_OE, BIT(gpio->nr % 32), 0);
 | 
			
		||||
		set32(bank->base_address + regs->OE, BIT(gpio->nr % 32), 0);
 | 
			
		||||
	} else {
 | 
			
		||||
		set32(bank->base_address + GPIO_FALLINGDETECT1,
 | 
			
		||||
		set32(bank->base_address + regs->FALLINGDETECT,
 | 
			
		||||
		    BIT(gpio->nr % 32), 0xffffffff);
 | 
			
		||||
		set32(bank->base_address + GPIO_IRQENABLE1, BIT(gpio->nr % 32),
 | 
			
		||||
		set32(bank->base_address + regs->IRQENABLE, BIT(gpio->nr % 32),
 | 
			
		||||
		    0xffffffff);
 | 
			
		||||
		set32(bank->base_address + GPIO_OE, BIT(gpio->nr % 32),
 | 
			
		||||
		set32(bank->base_address + regs->OE, BIT(gpio->nr % 32),
 | 
			
		||||
		    0xffffffff);
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
@ -218,14 +284,14 @@ omap_gpio_set(struct gpio *gpio, int value)
 | 
			
		||||
{
 | 
			
		||||
	struct omap_gpio_bank *bank;
 | 
			
		||||
	assert(gpio != NULL);
 | 
			
		||||
	assert(gpio->nr >= 0 && gpio->nr <= 32 * 6);
 | 
			
		||||
	assert(gpio->nr >= 0 && gpio->nr <= 32 * NBANKS);
 | 
			
		||||
 | 
			
		||||
	bank = omap_gpio_bank_get(gpio->nr);
 | 
			
		||||
	if (value == 1) {
 | 
			
		||||
		write32(bank->base_address + GPIO_SETDATAOUT,
 | 
			
		||||
		write32(bank->base_address + regs->SETDATAOUT,
 | 
			
		||||
		    BIT(gpio->nr % 32));
 | 
			
		||||
	} else {
 | 
			
		||||
		write32(bank->base_address + GPIO_CLEARDATAOUT,
 | 
			
		||||
		write32(bank->base_address + regs->CLEARDATAOUT,
 | 
			
		||||
		    BIT(gpio->nr % 32));
 | 
			
		||||
	}
 | 
			
		||||
	return OK;
 | 
			
		||||
@ -236,21 +302,21 @@ omap_gpio_read(struct gpio *gpio, int *value)
 | 
			
		||||
{
 | 
			
		||||
	struct omap_gpio_bank *bank;
 | 
			
		||||
	assert(gpio != NULL);
 | 
			
		||||
	assert(gpio->nr >= 0 && gpio->nr <= 32 * 6);
 | 
			
		||||
	assert(gpio->nr >= 0 && gpio->nr <= 32 * NBANKS);
 | 
			
		||||
 | 
			
		||||
	bank = omap_gpio_bank_get(gpio->nr);
 | 
			
		||||
	log_trace(&log, "mode=%d OU/IN 0x%08x 0x%08x\n", gpio->mode,
 | 
			
		||||
	    read32(bank->base_address + GPIO_DATAIN),
 | 
			
		||||
	    read32(bank->base_address + GPIO_DATAOUT));
 | 
			
		||||
	    read32(bank->base_address + regs->DATAIN),
 | 
			
		||||
	    read32(bank->base_address + regs->DATAOUT));
 | 
			
		||||
 | 
			
		||||
	if (gpio->mode == GPIO_MODE_INPUT) {
 | 
			
		||||
		*value =
 | 
			
		||||
		    (read32(bank->base_address +
 | 
			
		||||
			GPIO_DATAIN) >> (gpio->nr % 32)) & 0x1;
 | 
			
		||||
			regs->DATAIN) >> (gpio->nr % 32)) & 0x1;
 | 
			
		||||
	} else {
 | 
			
		||||
		*value =
 | 
			
		||||
		    (read32(bank->base_address +
 | 
			
		||||
			GPIO_DATAOUT) >> (gpio->nr % 32)) & 0x1;
 | 
			
		||||
			regs->DATAOUT) >> (gpio->nr % 32)) & 0x1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return OK;
 | 
			
		||||
@ -261,7 +327,7 @@ omap_gpio_intr_read(struct gpio *gpio, int *value)
 | 
			
		||||
{
 | 
			
		||||
	struct omap_gpio_bank *bank;
 | 
			
		||||
	assert(gpio != NULL);
 | 
			
		||||
	assert(gpio->nr >= 0 && gpio->nr <= 32 * 6);
 | 
			
		||||
	assert(gpio->nr >= 0 && gpio->nr <= 32 * NBANKS);
 | 
			
		||||
 | 
			
		||||
	bank = omap_gpio_bank_get(gpio->nr);
 | 
			
		||||
	/* TODO: check if interrupt where enabled?? */
 | 
			
		||||
@ -293,9 +359,9 @@ omap_message_hook(message * m)
 | 
			
		||||
				    bank->name);
 | 
			
		||||
				bank->inter_values |=
 | 
			
		||||
				    read32(bank->base_address +
 | 
			
		||||
				    GPIO_IRQSTATUS1);
 | 
			
		||||
				    regs->IRQSTATUS);
 | 
			
		||||
				/* clear the interrupts */
 | 
			
		||||
				write32(bank->base_address + GPIO_IRQSTATUS1,
 | 
			
		||||
				write32(bank->base_address + regs->IRQSTATUS,
 | 
			
		||||
				    0xffffffff);
 | 
			
		||||
				if (sys_irqenable(&bank->irq_hook_id) != OK) {
 | 
			
		||||
					log_warn(&log,
 | 
			
		||||
@ -306,7 +372,7 @@ omap_message_hook(message * m)
 | 
			
		||||
		}
 | 
			
		||||
		return OK;
 | 
			
		||||
	default:
 | 
			
		||||
		log_warn(&log, "Unknown message\n");
 | 
			
		||||
		log_debug(&log, "Unknown message\n");
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	return OK;
 | 
			
		||||
@ -343,16 +409,25 @@ omap_gpio_init(struct gpio_driver *gpdrv)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		revision = 0;
 | 
			
		||||
		revision = read32(bank->base_address + GPIO_REVISION);
 | 
			
		||||
		revision = read32(bank->base_address + regs->REVISION);
 | 
			
		||||
		/* test if we can access it */
 | 
			
		||||
		if (GPIO_REVISION_MAJOR(revision) != 2
 | 
			
		||||
		    || GPIO_REVISION_MINOR(revision) != 5) {
 | 
			
		||||
		if (
 | 
			
		||||
#ifdef AM335X
 | 
			
		||||
		    AM335X_GPIO_REVISION_MAJOR(revision) != 0
 | 
			
		||||
		    || AM335X_GPIO_REVISION_MINOR(revision) != 1
 | 
			
		||||
#elif DM37XX	    
 | 
			
		||||
		    DM37XX_GPIO_REVISION_MAJOR(revision) != 2
 | 
			
		||||
		    || DM37XX_GPIO_REVISION_MINOR(revision) != 5
 | 
			
		||||
#endif /* DM37XX */
 | 
			
		||||
		    ) {
 | 
			
		||||
			log_warn(&log,
 | 
			
		||||
			    "Failed to read the revision of GPIO bank %s.. disabling\n",
 | 
			
		||||
			    bank->name);
 | 
			
		||||
			log_warn(&log, "Got 0x%x\n", revision);
 | 
			
		||||
			bank->disabled = 1;
 | 
			
		||||
		} else {
 | 
			
		||||
			bank->disabled = 0;
 | 
			
		||||
		}
 | 
			
		||||
		bank->disabled = 0;
 | 
			
		||||
 | 
			
		||||
		if (sys_irqsetpolicy(bank->irq_nr, 0,
 | 
			
		||||
			&bank->irq_hook_id) != OK) {
 | 
			
		||||
@ -376,9 +451,13 @@ omap_gpio_init(struct gpio_driver *gpdrv)
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	clkconf_init();
 | 
			
		||||
#ifdef AM335X
 | 
			
		||||
	/* Nothing to enable for GPIO on AM335X */
 | 
			
		||||
#elif DM37XX
 | 
			
		||||
	/* enable the interface and functional clock on GPIO bank 1 */
 | 
			
		||||
	clkconf_set(CM_FCLKEN_WKUP, BIT(3), 0xffffffff);
 | 
			
		||||
	clkconf_set(CM_ICLKEN_WKUP, BIT(3), 0xffffffff);
 | 
			
		||||
#endif /* DM37XX */
 | 
			
		||||
	clkconf_release();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										88
									
								
								lib/libgpio/gpio_omap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								lib/libgpio/gpio_omap.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
			
		||||
#ifndef __GPIO_OMAP_H
 | 
			
		||||
#define __GPIO_OMAP_H
 | 
			
		||||
 | 
			
		||||
#define AM335X_GPIO0_BASE (0x44e07000)
 | 
			
		||||
#define AM335X_GPIO1_BASE (0x4804c000)
 | 
			
		||||
#define AM335X_GPIO2_BASE (0x481ac000)
 | 
			
		||||
#define AM335X_GPIO3_BASE (0x481ae000)
 | 
			
		||||
#define AM335X_GPIO0A_IRQ 96
 | 
			
		||||
#define AM335X_GPIO0B_IRQ 97
 | 
			
		||||
#define AM335X_GPIO1A_IRQ 98
 | 
			
		||||
#define AM335X_GPIO1B_IRQ 99
 | 
			
		||||
#define AM335X_GPIO2A_IRQ 32
 | 
			
		||||
#define AM335X_GPIO2B_IRQ 33
 | 
			
		||||
#define AM335X_GPIO3A_IRQ 62
 | 
			
		||||
#define AM335X_GPIO3B_IRQ 63
 | 
			
		||||
#define AM335X_GPIO0A_IRQ_HOOK_ID 0
 | 
			
		||||
#define AM335X_GPIO0B_IRQ_HOOK_ID 1
 | 
			
		||||
#define AM335X_GPIO1A_IRQ_HOOK_ID 2
 | 
			
		||||
#define AM335X_GPIO1B_IRQ_HOOK_ID 3
 | 
			
		||||
#define AM335X_GPIO2A_IRQ_HOOK_ID 4
 | 
			
		||||
#define AM335X_GPIO2B_IRQ_HOOK_ID 5
 | 
			
		||||
#define AM335X_GPIO3A_IRQ_HOOK_ID 6
 | 
			
		||||
#define AM335X_GPIO3B_IRQ_HOOK_ID 7
 | 
			
		||||
 | 
			
		||||
#define AM335X_GPIO_REVISION 0x000
 | 
			
		||||
#define AM335X_GPIO_SYSCONFIG 0x010
 | 
			
		||||
#define AM335X_GPIO_EOI 0x020
 | 
			
		||||
#define AM335X_GPIO_IRQSTATUS_RAW_0 0x024
 | 
			
		||||
#define AM335X_GPIO_IRQSTATUS_RAW_1 0x028
 | 
			
		||||
#define AM335X_GPIO_IRQSTATUS_0 0x02C
 | 
			
		||||
#define AM335X_GPIO_IRQSTATUS_1 0x030
 | 
			
		||||
#define AM335X_GPIO_IRQSTATUS_SET_0 0x034
 | 
			
		||||
#define AM335X_GPIO_IRQSTATUS_SET_1 0x038
 | 
			
		||||
#define AM335X_GPIO_IRQSTATUS_CLR_0 0x03C
 | 
			
		||||
#define AM335X_GPIO_IRQSTATUS_CLR_1 0x040
 | 
			
		||||
#define AM335X_GPIO_IRQWAKEN_0 0x044
 | 
			
		||||
#define AM335X_GPIO_IRQWAKEN_1 0x048
 | 
			
		||||
#define AM335X_GPIO_SYSSTATUS 0x114
 | 
			
		||||
#define AM335X_GPIO_CTRL 0x130
 | 
			
		||||
#define AM335X_GPIO_OE 0x134
 | 
			
		||||
#define AM335X_GPIO_DATAIN 0x138
 | 
			
		||||
#define AM335X_GPIO_DATAOUT 0x13C
 | 
			
		||||
#define AM335X_GPIO_LEVELDETECT0 0x140
 | 
			
		||||
#define AM335X_GPIO_LEVELDETECT1 0x144
 | 
			
		||||
#define AM335X_GPIO_RISINGDETECT 0x148
 | 
			
		||||
#define AM335X_GPIO_FALLINGDETECT 0x14C
 | 
			
		||||
#define AM335X_GPIO_DEBOUNCENABLE 0x150
 | 
			
		||||
#define AM335X_GPIO_DEBOUNCINGTIME 0x154
 | 
			
		||||
#define AM335X_GPIO_CLEARDATAOUT 0x190
 | 
			
		||||
#define AM335X_GPIO_SETDATAOUT 0x194
 | 
			
		||||
 | 
			
		||||
#define AM335X_GPIO_REVISION_MAJOR(X) ((X >> 8) & 0x07)
 | 
			
		||||
#define AM335X_GPIO_REVISION_MINOR(X) (X & 0x3f)
 | 
			
		||||
 | 
			
		||||
#define DM37XX_GPIO1_BASE (0x48310000)
 | 
			
		||||
#define DM37XX_GPIO2_BASE (0x49050000)
 | 
			
		||||
#define DM37XX_GPIO3_BASE (0x49052000)
 | 
			
		||||
#define DM37XX_GPIO4_BASE (0x49054000)
 | 
			
		||||
#define DM37XX_GPIO5_BASE (0x49056000)
 | 
			
		||||
#define DM37XX_GPIO6_BASE (0x49058000)
 | 
			
		||||
#define DM37XX_GPIO1_IRQ  29		/* GPIO module 1 */
 | 
			
		||||
#define DM37XX_GPIO2_IRQ  30		/* GPIO module 2 */
 | 
			
		||||
#define DM37XX_GPIO3_IRQ  31		/* GPIO module 3 */
 | 
			
		||||
#define DM37XX_GPIO4_IRQ  32		/* GPIO module 4 */
 | 
			
		||||
#define DM37XX_GPIO5_IRQ  33		/* GPIO module 5 */
 | 
			
		||||
#define DM37XX_GPIO6_IRQ  34		/* GPIO module 6 */
 | 
			
		||||
#define DM37XX_GPIO1_IRQ_HOOK_ID 0
 | 
			
		||||
#define DM37XX_GPIO2_IRQ_HOOK_ID 1
 | 
			
		||||
#define DM37XX_GPIO3_IRQ_HOOK_ID 2
 | 
			
		||||
#define DM37XX_GPIO4_IRQ_HOOK_ID 3
 | 
			
		||||
#define DM37XX_GPIO5_IRQ_HOOK_ID 4
 | 
			
		||||
#define DM37XX_GPIO6_IRQ_HOOK_ID 5
 | 
			
		||||
 | 
			
		||||
#define DM37XX_GPIO_IRQSTATUS1 (0x18)
 | 
			
		||||
#define DM37XX_GPIO_IRQENABLE1 (0x01C)
 | 
			
		||||
#define DM37XX_GPIO_DATAOUT (0x3c)
 | 
			
		||||
#define DM37XX_GPIO_DATAIN (0x38)
 | 
			
		||||
#define DM37XX_GPIO_OE    (0x34)	/* Output Data Enable */
 | 
			
		||||
#define DM37XX_GPIO_RISINGDETECT1 (0x048)
 | 
			
		||||
#define DM37XX_GPIO_FALLINGDETECT1 (0x04c)
 | 
			
		||||
#define DM37XX_GPIO_CLEARDATAOUT (0x90)
 | 
			
		||||
#define DM37XX_GPIO_SETDATAOUT (0x94)
 | 
			
		||||
 | 
			
		||||
#define DM37XX_GPIO_REVISION 0x00
 | 
			
		||||
#define DM37XX_GPIO_REVISION_MAJOR(X) ((X & 0xF0) >> 4)
 | 
			
		||||
#define DM37XX_GPIO_REVISION_MINOR(X) (X & 0XF)
 | 
			
		||||
 | 
			
		||||
#endif /* __GPIO_OMAP_H */
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user