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 * See file CREDITS for list of people who contributed to this 8 * project. 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License as 12 * published by the Free Software Foundation; either version 2 of 13 * the License, or (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 23 * MA 02111-1307 USA 24 */ 25 26 #include <common.h> 27 #include <netdev.h> 28 #include <asm/errno.h> 29 #include <asm/io.h> 30 #include <asm/arch/iomux.h> 31 #include <asm/arch/imx-regs.h> 32 33 #if defined(CONFIG_MX23) 34 #define PINCTRL_BANKS 3 35 #define PINCTRL_DOUT(n) (0x0500 + ((n) * 0x10)) 36 #define PINCTRL_DIN(n) (0x0600 + ((n) * 0x10)) 37 #define PINCTRL_DOE(n) (0x0700 + ((n) * 0x10)) 38 #define PINCTRL_PIN2IRQ(n) (0x0800 + ((n) * 0x10)) 39 #define PINCTRL_IRQEN(n) (0x0900 + ((n) * 0x10)) 40 #define PINCTRL_IRQSTAT(n) (0x0c00 + ((n) * 0x10)) 41 #elif defined(CONFIG_MX28) 42 #define PINCTRL_BANKS 5 43 #define PINCTRL_DOUT(n) (0x0700 + ((n) * 0x10)) 44 #define PINCTRL_DIN(n) (0x0900 + ((n) * 0x10)) 45 #define PINCTRL_DOE(n) (0x0b00 + ((n) * 0x10)) 46 #define PINCTRL_PIN2IRQ(n) (0x1000 + ((n) * 0x10)) 47 #define PINCTRL_IRQEN(n) (0x1100 + ((n) * 0x10)) 48 #define PINCTRL_IRQSTAT(n) (0x1400 + ((n) * 0x10)) 49 #else 50 #error "Please select CONFIG_MX23 or CONFIG_MX28" 51 #endif 52 53 #define GPIO_INT_FALL_EDGE 0x0 54 #define GPIO_INT_LOW_LEV 0x1 55 #define GPIO_INT_RISE_EDGE 0x2 56 #define GPIO_INT_HIGH_LEV 0x3 57 #define GPIO_INT_LEV_MASK (1 << 0) 58 #define GPIO_INT_POL_MASK (1 << 1) 59 60 void mxs_gpio_init(void) 61 { 62 int i; 63 64 for (i = 0; i < PINCTRL_BANKS; i++) { 65 writel(0, MXS_PINCTRL_BASE + PINCTRL_PIN2IRQ(i)); 66 writel(0, MXS_PINCTRL_BASE + PINCTRL_IRQEN(i)); 67 /* Use SCT address here to clear the IRQSTAT bits */ 68 writel(0xffffffff, MXS_PINCTRL_BASE + PINCTRL_IRQSTAT(i) + 8); 69 } 70 } 71 72 int gpio_get_value(unsigned gpio) 73 { 74 uint32_t bank = PAD_BANK(gpio); 75 uint32_t offset = PINCTRL_DIN(bank); 76 struct mx28_register *reg = 77 (struct mx28_register *)(MXS_PINCTRL_BASE + offset); 78 79 return (readl(®->reg) >> PAD_PIN(gpio)) & 1; 80 } 81 82 void gpio_set_value(unsigned gpio, int value) 83 { 84 uint32_t bank = PAD_BANK(gpio); 85 uint32_t offset = PINCTRL_DOUT(bank); 86 struct mx28_register *reg = 87 (struct mx28_register *)(MXS_PINCTRL_BASE + offset); 88 89 if (value) 90 writel(1 << PAD_PIN(gpio), ®->reg_set); 91 else 92 writel(1 << PAD_PIN(gpio), ®->reg_clr); 93 } 94 95 int gpio_direction_input(unsigned gpio) 96 { 97 uint32_t bank = PAD_BANK(gpio); 98 uint32_t offset = PINCTRL_DOE(bank); 99 struct mx28_register *reg = 100 (struct mx28_register *)(MXS_PINCTRL_BASE + offset); 101 102 writel(1 << PAD_PIN(gpio), ®->reg_clr); 103 104 return 0; 105 } 106 107 int gpio_direction_output(unsigned gpio, int value) 108 { 109 uint32_t bank = PAD_BANK(gpio); 110 uint32_t offset = PINCTRL_DOE(bank); 111 struct mx28_register *reg = 112 (struct mx28_register *)(MXS_PINCTRL_BASE + offset); 113 114 writel(1 << PAD_PIN(gpio), ®->reg_set); 115 116 gpio_set_value(gpio, value); 117 118 return 0; 119 } 120 121 int gpio_request(unsigned gpio, const char *label) 122 { 123 if (PAD_BANK(gpio) >= PINCTRL_BANKS) 124 return -1; 125 126 return 0; 127 } 128 129 int gpio_free(unsigned gpio) 130 { 131 return 0; 132 } 133