1 /* 2 * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com> 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 #include <config.h> 12 #include <common.h> 13 #include <asm/io.h> 14 #include <asm/sizes.h> 15 #include <asm/arch/hardware.h> 16 #include <asm/arch/at91_pio.h> 17 18 static struct at91_port *at91_pio_get_port(unsigned port) 19 { 20 switch (port) { 21 case AT91_PIO_PORTA: 22 return (struct at91_port *)ATMEL_BASE_PIOA; 23 case AT91_PIO_PORTB: 24 return (struct at91_port *)ATMEL_BASE_PIOB; 25 case AT91_PIO_PORTC: 26 return (struct at91_port *)ATMEL_BASE_PIOC; 27 #if (ATMEL_PIO_PORTS > 3) 28 case AT91_PIO_PORTD: 29 return (struct at91_port *)ATMEL_BASE_PIOD; 30 #if (ATMEL_PIO_PORTS > 4) 31 case AT91_PIO_PORTE: 32 return (struct at91_port *)ATMEL_BASE_PIOE; 33 #endif 34 #endif 35 default: 36 return NULL; 37 } 38 } 39 40 int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup) 41 { 42 struct at91_port *at91_port = at91_pio_get_port(port); 43 u32 mask; 44 45 if (at91_port && (pin < 32)) { 46 mask = 1 << pin; 47 if (use_pullup) 48 writel(1 << pin, &at91_port->puer); 49 else 50 writel(1 << pin, &at91_port->pudr); 51 writel(mask, &at91_port->per); 52 } 53 54 return 0; 55 } 56 57 /* 58 * mux the pin to the "GPIO" peripheral role. 59 */ 60 int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup) 61 { 62 struct at91_port *at91_port = at91_pio_get_port(port); 63 u32 mask; 64 65 if (at91_port && (pin < 32)) { 66 mask = 1 << pin; 67 writel(mask, &at91_port->idr); 68 at91_set_pio_pullup(port, pin, use_pullup); 69 writel(mask, &at91_port->per); 70 } 71 72 return 0; 73 } 74 75 /* 76 * mux the pin to the "A" internal peripheral role. 77 */ 78 int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup) 79 { 80 struct at91_port *at91_port = at91_pio_get_port(port); 81 u32 mask; 82 83 if (at91_port && (pin < 32)) { 84 mask = 1 << pin; 85 writel(mask, &at91_port->idr); 86 at91_set_pio_pullup(port, pin, use_pullup); 87 #if defined(CPU_HAS_PIO3) 88 writel(readl(&at91_port->abcdsr1) & ~mask, 89 &at91_port->abcdsr1); 90 writel(readl(&at91_port->abcdsr2) & ~mask, 91 &at91_port->abcdsr2); 92 #else 93 writel(mask, &at91_port->asr); 94 #endif 95 writel(mask, &at91_port->pdr); 96 } 97 98 return 0; 99 } 100 101 /* 102 * mux the pin to the "B" internal peripheral role. 103 */ 104 int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup) 105 { 106 struct at91_port *at91_port = at91_pio_get_port(port); 107 u32 mask; 108 109 if (at91_port && (pin < 32)) { 110 mask = 1 << pin; 111 writel(mask, &at91_port->idr); 112 at91_set_pio_pullup(port, pin, use_pullup); 113 #if defined(CPU_HAS_PIO3) 114 writel(readl(&at91_port->abcdsr1) | mask, 115 &at91_port->abcdsr1); 116 writel(readl(&at91_port->abcdsr2) & ~mask, 117 &at91_port->abcdsr2); 118 #else 119 writel(mask, &at91_port->bsr); 120 #endif 121 writel(mask, &at91_port->pdr); 122 } 123 124 return 0; 125 } 126 127 #if defined(CPU_HAS_PIO3) 128 /* 129 * mux the pin to the "C" internal peripheral role. 130 */ 131 int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup) 132 { 133 struct at91_port *at91_port = at91_pio_get_port(port); 134 u32 mask; 135 136 if (at91_port && (pin < 32)) { 137 mask = 1 << pin; 138 writel(mask, &at91_port->idr); 139 at91_set_pio_pullup(port, pin, use_pullup); 140 writel(readl(&at91_port->abcdsr1) & ~mask, 141 &at91_port->abcdsr1); 142 writel(readl(&at91_port->abcdsr2) | mask, 143 &at91_port->abcdsr2); 144 writel(mask, &at91_port->pdr); 145 } 146 147 return 0; 148 } 149 150 /* 151 * mux the pin to the "D" internal peripheral role. 152 */ 153 int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup) 154 { 155 struct at91_port *at91_port = at91_pio_get_port(port); 156 u32 mask; 157 158 if (at91_port && (pin < 32)) { 159 mask = 1 << pin; 160 writel(mask, &at91_port->idr); 161 at91_set_pio_pullup(port, pin, use_pullup); 162 writel(readl(&at91_port->abcdsr1) | mask, 163 &at91_port->abcdsr1); 164 writel(readl(&at91_port->abcdsr2) | mask, 165 &at91_port->abcdsr2); 166 writel(mask, &at91_port->pdr); 167 } 168 169 return 0; 170 } 171 #endif 172 173 /* 174 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and 175 * configure it for an input. 176 */ 177 int at91_set_pio_input(unsigned port, u32 pin, int use_pullup) 178 { 179 struct at91_port *at91_port = at91_pio_get_port(port); 180 u32 mask; 181 182 if (at91_port && (pin < 32)) { 183 mask = 1 << pin; 184 writel(mask, &at91_port->idr); 185 at91_set_pio_pullup(port, pin, use_pullup); 186 writel(mask, &at91_port->odr); 187 writel(mask, &at91_port->per); 188 } 189 190 return 0; 191 } 192 193 /* 194 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), 195 * and configure it for an output. 196 */ 197 int at91_set_pio_output(unsigned port, u32 pin, int value) 198 { 199 struct at91_port *at91_port = at91_pio_get_port(port); 200 u32 mask; 201 202 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { 203 mask = 1 << pin; 204 writel(mask, &at91_port->idr); 205 writel(mask, &at91_port->pudr); 206 if (value) 207 writel(mask, &at91_port->sodr); 208 else 209 writel(mask, &at91_port->codr); 210 writel(mask, &at91_port->oer); 211 writel(mask, &at91_port->per); 212 } 213 214 return 0; 215 } 216 217 /* 218 * enable/disable the glitch filter. mostly used with IRQ handling. 219 */ 220 int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on) 221 { 222 struct at91_port *at91_port = at91_pio_get_port(port); 223 u32 mask; 224 225 if (at91_port && (pin < 32)) { 226 mask = 1 << pin; 227 if (is_on) { 228 #if defined(CPU_HAS_PIO3) 229 writel(mask, &at91_port->ifscdr); 230 #endif 231 writel(mask, &at91_port->ifer); 232 } else { 233 writel(mask, &at91_port->ifdr); 234 } 235 } 236 237 return 0; 238 } 239 240 #if defined(CPU_HAS_PIO3) 241 /* 242 * enable/disable the debounce filter. 243 */ 244 int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div) 245 { 246 struct at91_port *at91_port = at91_pio_get_port(port); 247 u32 mask; 248 249 if (at91_port && (pin < 32)) { 250 mask = 1 << pin; 251 if (is_on) { 252 writel(mask, &at91_port->ifscer); 253 writel(div & PIO_SCDR_DIV, &at91_port->scdr); 254 writel(mask, &at91_port->ifer); 255 } else { 256 writel(mask, &at91_port->ifdr); 257 } 258 } 259 260 return 0; 261 } 262 263 /* 264 * enable/disable the pull-down. 265 * If pull-up already enabled while calling the function, we disable it. 266 */ 267 int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on) 268 { 269 struct at91_port *at91_port = at91_pio_get_port(port); 270 u32 mask; 271 272 if (at91_port && (pin < 32)) { 273 mask = 1 << pin; 274 writel(mask, &at91_port->pudr); 275 if (is_on) 276 writel(mask, &at91_port->ppder); 277 else 278 writel(mask, &at91_port->ppddr); 279 } 280 281 return 0; 282 } 283 284 /* 285 * disable Schmitt trigger 286 */ 287 int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin) 288 { 289 struct at91_port *at91_port = at91_pio_get_port(port); 290 u32 mask; 291 292 if (at91_port && (pin < 32)) { 293 mask = 1 << pin; 294 writel(readl(&at91_port->schmitt) | mask, 295 &at91_port->schmitt); 296 } 297 298 return 0; 299 } 300 #endif 301 302 /* 303 * enable/disable the multi-driver. This is only valid for output and 304 * allows the output pin to run as an open collector output. 305 */ 306 int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on) 307 { 308 struct at91_port *at91_port = at91_pio_get_port(port); 309 u32 mask; 310 311 if (at91_port && (pin < 32)) { 312 mask = 1 << pin; 313 if (is_on) 314 writel(mask, &at91_port->mder); 315 else 316 writel(mask, &at91_port->mddr); 317 } 318 319 return 0; 320 } 321 322 /* 323 * assuming the pin is muxed as a gpio output, set its value. 324 */ 325 int at91_set_pio_value(unsigned port, unsigned pin, int value) 326 { 327 struct at91_port *at91_port = at91_pio_get_port(port); 328 u32 mask; 329 330 if (at91_port && (pin < 32)) { 331 mask = 1 << pin; 332 if (value) 333 writel(mask, &at91_port->sodr); 334 else 335 writel(mask, &at91_port->codr); 336 } 337 338 return 0; 339 } 340 341 /* 342 * read the pin's value (works even if it's not muxed as a gpio). 343 */ 344 int at91_get_pio_value(unsigned port, unsigned pin) 345 { 346 struct at91_port *at91_port = at91_pio_get_port(port); 347 u32 pdsr = 0, mask; 348 349 if (at91_port && (pin < 32)) { 350 mask = 1 << pin; 351 pdsr = readl(&at91_port->pdsr) & mask; 352 } 353 354 return pdsr != 0; 355 } 356 357 /* Common GPIO API */ 358 359 #define at91_gpio_to_port(gpio) (gpio / 32) 360 #define at91_gpio_to_pin(gpio) (gpio % 32) 361 362 int gpio_request(unsigned gpio, const char *label) 363 { 364 return 0; 365 } 366 367 int gpio_free(unsigned gpio) 368 { 369 return 0; 370 } 371 372 int gpio_direction_input(unsigned gpio) 373 { 374 at91_set_pio_input(at91_gpio_to_port(gpio), 375 at91_gpio_to_pin(gpio), 0); 376 return 0; 377 } 378 379 int gpio_direction_output(unsigned gpio, int value) 380 { 381 at91_set_pio_output(at91_gpio_to_port(gpio), 382 at91_gpio_to_pin(gpio), value); 383 return 0; 384 } 385 386 int gpio_get_value(unsigned gpio) 387 { 388 return at91_get_pio_value(at91_gpio_to_port(gpio), 389 at91_gpio_to_pin(gpio)); 390 } 391 392 int gpio_set_value(unsigned gpio, int value) 393 { 394 at91_set_pio_value(at91_gpio_to_port(gpio), 395 at91_gpio_to_pin(gpio), value); 396 397 return 0; 398 } 399