1 /* 2 * Freescale i.MX28 GPIO control code 3 * 4 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> 5 * on behalf of DENX Software Engineering GmbH 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <netdev.h> 12 #include <asm/errno.h> 13 #include <asm/io.h> 14 #include <asm/arch/iomux.h> 15 #include <asm/arch/imx-regs.h> 16 17 #if defined(CONFIG_MX23) 18 #define PINCTRL_BANKS 3 19 #define PINCTRL_DOUT(n) (0x0500 + ((n) * 0x10)) 20 #define PINCTRL_DIN(n) (0x0600 + ((n) * 0x10)) 21 #define PINCTRL_DOE(n) (0x0700 + ((n) * 0x10)) 22 #define PINCTRL_PIN2IRQ(n) (0x0800 + ((n) * 0x10)) 23 #define PINCTRL_IRQEN(n) (0x0900 + ((n) * 0x10)) 24 #define PINCTRL_IRQSTAT(n) (0x0c00 + ((n) * 0x10)) 25 #elif defined(CONFIG_MX28) 26 #define PINCTRL_BANKS 5 27 #define PINCTRL_DOUT(n) (0x0700 + ((n) * 0x10)) 28 #define PINCTRL_DIN(n) (0x0900 + ((n) * 0x10)) 29 #define PINCTRL_DOE(n) (0x0b00 + ((n) * 0x10)) 30 #define PINCTRL_PIN2IRQ(n) (0x1000 + ((n) * 0x10)) 31 #define PINCTRL_IRQEN(n) (0x1100 + ((n) * 0x10)) 32 #define PINCTRL_IRQSTAT(n) (0x1400 + ((n) * 0x10)) 33 #else 34 #error "Please select CONFIG_MX23 or CONFIG_MX28" 35 #endif 36 37 #define GPIO_INT_FALL_EDGE 0x0 38 #define GPIO_INT_LOW_LEV 0x1 39 #define GPIO_INT_RISE_EDGE 0x2 40 #define GPIO_INT_HIGH_LEV 0x3 41 #define GPIO_INT_LEV_MASK (1 << 0) 42 #define GPIO_INT_POL_MASK (1 << 1) 43 44 void mxs_gpio_init(void) 45 { 46 int i; 47 48 for (i = 0; i < PINCTRL_BANKS; i++) { 49 writel(0, MXS_PINCTRL_BASE + PINCTRL_PIN2IRQ(i)); 50 writel(0, MXS_PINCTRL_BASE + PINCTRL_IRQEN(i)); 51 /* Use SCT address here to clear the IRQSTAT bits */ 52 writel(0xffffffff, MXS_PINCTRL_BASE + PINCTRL_IRQSTAT(i) + 8); 53 } 54 } 55 56 int gpio_get_value(unsigned gpio) 57 { 58 uint32_t bank = PAD_BANK(gpio); 59 uint32_t offset = PINCTRL_DIN(bank); 60 struct mxs_register_32 *reg = 61 (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset); 62 63 return (readl(®->reg) >> PAD_PIN(gpio)) & 1; 64 } 65 66 void gpio_set_value(unsigned gpio, int value) 67 { 68 uint32_t bank = PAD_BANK(gpio); 69 uint32_t offset = PINCTRL_DOUT(bank); 70 struct mxs_register_32 *reg = 71 (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset); 72 73 if (value) 74 writel(1 << PAD_PIN(gpio), ®->reg_set); 75 else 76 writel(1 << PAD_PIN(gpio), ®->reg_clr); 77 } 78 79 int gpio_direction_input(unsigned gpio) 80 { 81 uint32_t bank = PAD_BANK(gpio); 82 uint32_t offset = PINCTRL_DOE(bank); 83 struct mxs_register_32 *reg = 84 (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset); 85 86 writel(1 << PAD_PIN(gpio), ®->reg_clr); 87 88 return 0; 89 } 90 91 int gpio_direction_output(unsigned gpio, int value) 92 { 93 uint32_t bank = PAD_BANK(gpio); 94 uint32_t offset = PINCTRL_DOE(bank); 95 struct mxs_register_32 *reg = 96 (struct mxs_register_32 *)(MXS_PINCTRL_BASE + offset); 97 98 writel(1 << PAD_PIN(gpio), ®->reg_set); 99 100 gpio_set_value(gpio, value); 101 102 return 0; 103 } 104 105 int gpio_request(unsigned gpio, const char *label) 106 { 107 if (PAD_BANK(gpio) >= PINCTRL_BANKS) 108 return -1; 109 110 return 0; 111 } 112 113 int gpio_free(unsigned gpio) 114 { 115 return 0; 116 } 117