mirror of
				https://source.denx.de/u-boot/u-boot.git
				synced 2025-10-25 22:41:21 +02:00 
			
		
		
		
	Setting the direction and an output value should be done by 1) set the desired output value, 2) switch to output. If this is done in the inverse order, there can be a glitch on the GPIO line. This patch fixes this by using the order as described above. Signed-off-by: Michael Heimpold <mhei@heimpold.de> Acked-by: Stefano Babic <sbabic@denx.de>
		
			
				
	
	
		
			117 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Freescale i.MX28 GPIO control code
 | |
|  *
 | |
|  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
 | |
|  * on behalf of DENX Software Engineering GmbH
 | |
|  *
 | |
|  * SPDX-License-Identifier:	GPL-2.0+
 | |
|  */
 | |
| 
 | |
| #include <common.h>
 | |
| #include <netdev.h>
 | |
| #include <asm/errno.h>
 | |
| #include <asm/io.h>
 | |
| #include <asm/arch/iomux.h>
 | |
| #include <asm/arch/imx-regs.h>
 | |
| 
 | |
| #if	defined(CONFIG_MX23)
 | |
| #define	PINCTRL_BANKS		3
 | |
| #define	PINCTRL_DOUT(n)		(0x0500 + ((n) * 0x10))
 | |
| #define	PINCTRL_DIN(n)		(0x0600 + ((n) * 0x10))
 | |
| #define	PINCTRL_DOE(n)		(0x0700 + ((n) * 0x10))
 | |
| #define	PINCTRL_PIN2IRQ(n)	(0x0800 + ((n) * 0x10))
 | |
| #define	PINCTRL_IRQEN(n)	(0x0900 + ((n) * 0x10))
 | |
| #define	PINCTRL_IRQSTAT(n)	(0x0c00 + ((n) * 0x10))
 | |
| #elif	defined(CONFIG_MX28)
 | |
| #define	PINCTRL_BANKS		5
 | |
| #define	PINCTRL_DOUT(n)		(0x0700 + ((n) * 0x10))
 | |
| #define	PINCTRL_DIN(n)		(0x0900 + ((n) * 0x10))
 | |
| #define	PINCTRL_DOE(n)		(0x0b00 + ((n) * 0x10))
 | |
| #define	PINCTRL_PIN2IRQ(n)	(0x1000 + ((n) * 0x10))
 | |
| #define	PINCTRL_IRQEN(n)	(0x1100 + ((n) * 0x10))
 | |
| #define	PINCTRL_IRQSTAT(n)	(0x1400 + ((n) * 0x10))
 | |
| #else
 | |
| #error "Please select CONFIG_MX23 or CONFIG_MX28"
 | |
| #endif
 | |
| 
 | |
| #define GPIO_INT_FALL_EDGE	0x0
 | |
| #define GPIO_INT_LOW_LEV	0x1
 | |
| #define GPIO_INT_RISE_EDGE	0x2
 | |
| #define GPIO_INT_HIGH_LEV	0x3
 | |
| #define GPIO_INT_LEV_MASK	(1 << 0)
 | |
| #define GPIO_INT_POL_MASK	(1 << 1)
 | |
| 
 | |
| void mxs_gpio_init(void)
 | |
| {
 | |
| 	int i;
 | |
| 
 | |
| 	for (i = 0; i < PINCTRL_BANKS; i++) {
 | |
| 		writel(0, MXS_PINCTRL_BASE + PINCTRL_PIN2IRQ(i));
 | |
| 		writel(0, MXS_PINCTRL_BASE + PINCTRL_IRQEN(i));
 | |
| 		/* Use SCT address here to clear the IRQSTAT bits */
 | |
| 		writel(0xffffffff, MXS_PINCTRL_BASE + PINCTRL_IRQSTAT(i) + 8);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int gpio_get_value(unsigned gpio)
 | |
| {
 | |
| 	uint32_t bank = PAD_BANK(gpio);
 | |
| 	uint32_t offset = PINCTRL_DIN(bank);
 | |
| 	struct mxs_register_32 *reg =
 | |
| 		(struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
 | |
| 
 | |
| 	return (readl(®->reg) >> PAD_PIN(gpio)) & 1;
 | |
| }
 | |
| 
 | |
| void gpio_set_value(unsigned gpio, int value)
 | |
| {
 | |
| 	uint32_t bank = PAD_BANK(gpio);
 | |
| 	uint32_t offset = PINCTRL_DOUT(bank);
 | |
| 	struct mxs_register_32 *reg =
 | |
| 		(struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
 | |
| 
 | |
| 	if (value)
 | |
| 		writel(1 << PAD_PIN(gpio), ®->reg_set);
 | |
| 	else
 | |
| 		writel(1 << PAD_PIN(gpio), ®->reg_clr);
 | |
| }
 | |
| 
 | |
| int gpio_direction_input(unsigned gpio)
 | |
| {
 | |
| 	uint32_t bank = PAD_BANK(gpio);
 | |
| 	uint32_t offset = PINCTRL_DOE(bank);
 | |
| 	struct mxs_register_32 *reg =
 | |
| 		(struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
 | |
| 
 | |
| 	writel(1 << PAD_PIN(gpio), ®->reg_clr);
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int gpio_direction_output(unsigned gpio, int value)
 | |
| {
 | |
| 	uint32_t bank = PAD_BANK(gpio);
 | |
| 	uint32_t offset = PINCTRL_DOE(bank);
 | |
| 	struct mxs_register_32 *reg =
 | |
| 		(struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset);
 | |
| 
 | |
| 	gpio_set_value(gpio, value);
 | |
| 
 | |
| 	writel(1 << PAD_PIN(gpio), ®->reg_set);
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int gpio_request(unsigned gpio, const char *label)
 | |
| {
 | |
| 	if (PAD_BANK(gpio) >= PINCTRL_BANKS)
 | |
| 		return -1;
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int gpio_free(unsigned gpio)
 | |
| {
 | |
| 	return 0;
 | |
| }
 |