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 * SPDX-License-Identifier: GPL-2.0+ 9 */ 10 11 /* 12 * WARNING: 13 * 14 * As the code is right now, it expects all PIO ports A,B,C,... 15 * to be evenly spaced in the memory map: 16 * ATMEL_BASE_PIOA + port * sizeof at91pio_t 17 * This might not necessaryly be true in future Atmel SoCs. 18 * This code should be fixed to use a pointer array to the ports. 19 */ 20 21 #include <config.h> 22 #include <common.h> 23 #include <asm/io.h> 24 #include <asm/sizes.h> 25 #include <asm/arch/hardware.h> 26 #include <asm/arch/at91_pio.h> 27 28 int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup) 29 { 30 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 31 u32 mask; 32 33 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 34 mask = 1 << pin; 35 if (use_pullup) 36 writel(1 << pin, &pio->port[port].puer); 37 else 38 writel(1 << pin, &pio->port[port].pudr); 39 writel(mask, &pio->port[port].per); 40 } 41 return 0; 42 } 43 44 /* 45 * mux the pin to the "GPIO" peripheral role. 46 */ 47 int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup) 48 { 49 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 50 u32 mask; 51 52 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 53 mask = 1 << pin; 54 writel(mask, &pio->port[port].idr); 55 at91_set_pio_pullup(port, pin, use_pullup); 56 writel(mask, &pio->port[port].per); 57 } 58 return 0; 59 } 60 61 /* 62 * mux the pin to the "A" internal peripheral role. 63 */ 64 int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup) 65 { 66 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 67 u32 mask; 68 69 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 70 mask = 1 << pin; 71 writel(mask, &pio->port[port].idr); 72 at91_set_pio_pullup(port, pin, use_pullup); 73 #if defined(CPU_HAS_PIO3) 74 writel(readl(&pio->port[port].abcdsr1) & ~mask, 75 &pio->port[port].abcdsr1); 76 writel(readl(&pio->port[port].abcdsr2) & ~mask, 77 &pio->port[port].abcdsr2); 78 #else 79 writel(mask, &pio->port[port].asr); 80 #endif 81 writel(mask, &pio->port[port].pdr); 82 } 83 return 0; 84 } 85 86 /* 87 * mux the pin to the "B" internal peripheral role. 88 */ 89 int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup) 90 { 91 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 92 u32 mask; 93 94 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 95 mask = 1 << pin; 96 writel(mask, &pio->port[port].idr); 97 at91_set_pio_pullup(port, pin, use_pullup); 98 #if defined(CPU_HAS_PIO3) 99 writel(readl(&pio->port[port].abcdsr1) | mask, 100 &pio->port[port].abcdsr1); 101 writel(readl(&pio->port[port].abcdsr2) & ~mask, 102 &pio->port[port].abcdsr2); 103 #else 104 writel(mask, &pio->port[port].bsr); 105 #endif 106 writel(mask, &pio->port[port].pdr); 107 } 108 return 0; 109 } 110 111 #if defined(CPU_HAS_PIO3) 112 /* 113 * mux the pin to the "C" internal peripheral role. 114 */ 115 int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup) 116 { 117 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 118 u32 mask; 119 120 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 121 mask = 1 << pin; 122 writel(mask, &pio->port[port].idr); 123 at91_set_pio_pullup(port, pin, use_pullup); 124 writel(readl(&pio->port[port].abcdsr1) & ~mask, 125 &pio->port[port].abcdsr1); 126 writel(readl(&pio->port[port].abcdsr2) | mask, 127 &pio->port[port].abcdsr2); 128 writel(mask, &pio->port[port].pdr); 129 } 130 return 0; 131 } 132 133 /* 134 * mux the pin to the "D" internal peripheral role. 135 */ 136 int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup) 137 { 138 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 139 u32 mask; 140 141 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 142 mask = 1 << pin; 143 writel(mask, &pio->port[port].idr); 144 at91_set_pio_pullup(port, pin, use_pullup); 145 writel(readl(&pio->port[port].abcdsr1) | mask, 146 &pio->port[port].abcdsr1); 147 writel(readl(&pio->port[port].abcdsr2) | mask, 148 &pio->port[port].abcdsr2); 149 writel(mask, &pio->port[port].pdr); 150 } 151 return 0; 152 } 153 #endif 154 155 /* 156 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and 157 * configure it for an input. 158 */ 159 int at91_set_pio_input(unsigned port, u32 pin, int use_pullup) 160 { 161 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 162 u32 mask; 163 164 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 165 mask = 1 << pin; 166 writel(mask, &pio->port[port].idr); 167 at91_set_pio_pullup(port, pin, use_pullup); 168 writel(mask, &pio->port[port].odr); 169 writel(mask, &pio->port[port].per); 170 } 171 return 0; 172 } 173 174 /* 175 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), 176 * and configure it for an output. 177 */ 178 int at91_set_pio_output(unsigned port, u32 pin, int value) 179 { 180 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 181 u32 mask; 182 183 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 184 mask = 1 << pin; 185 writel(mask, &pio->port[port].idr); 186 writel(mask, &pio->port[port].pudr); 187 if (value) 188 writel(mask, &pio->port[port].sodr); 189 else 190 writel(mask, &pio->port[port].codr); 191 writel(mask, &pio->port[port].oer); 192 writel(mask, &pio->port[port].per); 193 } 194 return 0; 195 } 196 197 /* 198 * enable/disable the glitch filter. mostly used with IRQ handling. 199 */ 200 int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on) 201 { 202 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 203 u32 mask; 204 205 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 206 mask = 1 << pin; 207 if (is_on) { 208 #if defined(CPU_HAS_PIO3) 209 writel(mask, &pio->port[port].ifscdr); 210 #endif 211 writel(mask, &pio->port[port].ifer); 212 } else { 213 writel(mask, &pio->port[port].ifdr); 214 } 215 } 216 return 0; 217 } 218 219 #if defined(CPU_HAS_PIO3) 220 /* 221 * enable/disable the debounce filter. 222 */ 223 int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div) 224 { 225 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 226 u32 mask; 227 228 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 229 mask = 1 << pin; 230 if (is_on) { 231 writel(mask, &pio->port[port].ifscer); 232 writel(div & PIO_SCDR_DIV, &pio->port[port].scdr); 233 writel(mask, &pio->port[port].ifer); 234 } else { 235 writel(mask, &pio->port[port].ifdr); 236 } 237 } 238 return 0; 239 } 240 241 /* 242 * enable/disable the pull-down. 243 * If pull-up already enabled while calling the function, we disable it. 244 */ 245 int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on) 246 { 247 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 248 u32 mask; 249 250 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 251 mask = 1 << pin; 252 writel(mask, &pio->port[port].pudr); 253 if (is_on) 254 writel(mask, &pio->port[port].ppder); 255 else 256 writel(mask, &pio->port[port].ppddr); 257 } 258 return 0; 259 } 260 261 /* 262 * disable Schmitt trigger 263 */ 264 int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin) 265 { 266 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 267 u32 mask; 268 269 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 270 mask = 1 << pin; 271 writel(readl(&pio->port[port].schmitt) | mask, 272 &pio->port[port].schmitt); 273 } 274 return 0; 275 } 276 #endif 277 278 /* 279 * enable/disable the multi-driver. This is only valid for output and 280 * allows the output pin to run as an open collector output. 281 */ 282 int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on) 283 { 284 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 285 u32 mask; 286 287 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 288 mask = 1 << pin; 289 if (is_on) 290 writel(mask, &pio->port[port].mder); 291 else 292 writel(mask, &pio->port[port].mddr); 293 } 294 return 0; 295 } 296 297 /* 298 * assuming the pin is muxed as a gpio output, set its value. 299 */ 300 int at91_set_pio_value(unsigned port, unsigned pin, int value) 301 { 302 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 303 u32 mask; 304 305 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 306 mask = 1 << pin; 307 if (value) 308 writel(mask, &pio->port[port].sodr); 309 else 310 writel(mask, &pio->port[port].codr); 311 } 312 return 0; 313 } 314 315 /* 316 * read the pin's value (works even if it's not muxed as a gpio). 317 */ 318 int at91_get_pio_value(unsigned port, unsigned pin) 319 { 320 u32 pdsr = 0; 321 at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; 322 u32 mask; 323 324 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 325 mask = 1 << pin; 326 pdsr = readl(&pio->port[port].pdsr) & mask; 327 } 328 return pdsr != 0; 329 } 330