1 /* 2 * Memory Setup stuff - taken from blob memsetup.S 3 * 4 * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) 5 * 6 * Copyright (C) 2005 HP Labs 7 * 8 * See file CREDITS for list of people who contributed to this 9 * project. 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License as 13 * published by the Free Software Foundation; either version 2 of 14 * the License, or (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 24 * MA 02111-1307 USA 25 */ 26 27 #include <config.h> 28 #include <common.h> 29 #include <asm/sizes.h> 30 #include <asm/arch/hardware.h> 31 #include <asm/arch/io.h> 32 #include <asm/arch/at91_pio.h> 33 34 int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup) 35 { 36 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; 37 u32 mask; 38 39 if ((port < AT91_PIO_PORTS) && (pin < 32)) { 40 mask = 1 << pin; 41 if (use_pullup) 42 writel(1 << pin, &pio->port[port].puer); 43 else 44 writel(1 << pin, &pio->port[port].pudr); 45 writel(mask, &pio->port[port].per); 46 } 47 return 0; 48 } 49 50 /* 51 * mux the pin to the "GPIO" peripheral role. 52 */ 53 int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup) 54 { 55 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; 56 u32 mask; 57 58 if ((port < AT91_PIO_PORTS) && (pin < 32)) { 59 mask = 1 << pin; 60 writel(mask, &pio->port[port].idr); 61 at91_set_pio_pullup(port, pin, use_pullup); 62 writel(mask, &pio->port[port].per); 63 } 64 return 0; 65 } 66 67 /* 68 * mux the pin to the "A" internal peripheral role. 69 */ 70 int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup) 71 { 72 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; 73 u32 mask; 74 75 if ((port < AT91_PIO_PORTS) && (pin < 32)) { 76 mask = 1 << pin; 77 writel(mask, &pio->port[port].idr); 78 at91_set_pio_pullup(port, pin, use_pullup); 79 writel(mask, &pio->port[port].asr); 80 writel(mask, &pio->port[port].pdr); 81 } 82 return 0; 83 } 84 85 /* 86 * mux the pin to the "B" internal peripheral role. 87 */ 88 int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup) 89 { 90 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; 91 u32 mask; 92 93 if ((port < AT91_PIO_PORTS) && (pin < 32)) { 94 mask = 1 << pin; 95 writel(mask, &pio->port[port].idr); 96 at91_set_pio_pullup(port, pin, use_pullup); 97 writel(mask, &pio->port[port].bsr); 98 writel(mask, &pio->port[port].pdr); 99 } 100 return 0; 101 } 102 103 /* 104 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and 105 * configure it for an input. 106 */ 107 int at91_set_pio_input(unsigned port, u32 pin, int use_pullup) 108 { 109 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; 110 u32 mask; 111 112 if ((port < AT91_PIO_PORTS) && (pin < 32)) { 113 mask = 1 << pin; 114 writel(mask, &pio->port[port].idr); 115 at91_set_pio_pullup(port, pin, use_pullup); 116 writel(mask, &pio->port[port].odr); 117 writel(mask, &pio->port[port].per); 118 } 119 return 0; 120 } 121 122 /* 123 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), 124 * and configure it for an output. 125 */ 126 int at91_set_pio_output(unsigned port, u32 pin, int value) 127 { 128 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; 129 u32 mask; 130 131 if ((port < AT91_PIO_PORTS) && (pin < 32)) { 132 mask = 1 << pin; 133 writel(mask, &pio->port[port].idr); 134 writel(mask, &pio->port[port].pudr); 135 if (value) 136 writel(mask, &pio->port[port].sodr); 137 else 138 writel(mask, &pio->port[port].codr); 139 writel(mask, &pio->port[port].oer); 140 writel(mask, &pio->port[port].per); 141 } 142 return 0; 143 } 144 145 /* 146 * enable/disable the glitch filter. mostly used with IRQ handling. 147 */ 148 int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on) 149 { 150 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; 151 u32 mask; 152 153 if ((port < AT91_PIO_PORTS) && (pin < 32)) { 154 mask = 1 << pin; 155 if (is_on) 156 writel(mask, &pio->port[port].ifer); 157 else 158 writel(mask, &pio->port[port].ifdr); 159 } 160 return 0; 161 } 162 163 /* 164 * enable/disable the multi-driver. This is only valid for output and 165 * allows the output pin to run as an open collector output. 166 */ 167 int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on) 168 { 169 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; 170 u32 mask; 171 172 if ((port < AT91_PIO_PORTS) && (pin < 32)) { 173 mask = 1 << pin; 174 if (is_on) 175 writel(mask, &pio->port[port].mder); 176 else 177 writel(mask, &pio->port[port].mddr); 178 } 179 return 0; 180 } 181 182 /* 183 * assuming the pin is muxed as a gpio output, set its value. 184 */ 185 int at91_set_pio_value(unsigned port, unsigned pin, int value) 186 { 187 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; 188 u32 mask; 189 190 if ((port < AT91_PIO_PORTS) && (pin < 32)) { 191 mask = 1 << pin; 192 if (value) 193 writel(mask, &pio->port[port].sodr); 194 else 195 writel(mask, &pio->port[port].codr); 196 } 197 return 0; 198 } 199 200 /* 201 * read the pin's value (works even if it's not muxed as a gpio). 202 */ 203 int at91_get_pio_value(unsigned port, unsigned pin) 204 { 205 u32 pdsr = 0; 206 at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; 207 u32 mask; 208 209 if ((port < AT91_PIO_PORTS) && (pin < 32)) { 210 mask = 1 << pin; 211 pdsr = readl(&pio->port[port].pdsr) & mask; 212 } 213 return pdsr != 0; 214 } 215