uboot/drivers/gpio/at91_gpio.c
<<
>>
Prefs
   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 <dm.h>
  14#include <asm/io.h>
  15#include <linux/sizes.h>
  16#include <asm/gpio.h>
  17#include <asm/arch/hardware.h>
  18#include <asm/arch/at91_pio.h>
  19
  20#define GPIO_PER_BANK   32
  21
  22static struct at91_port *at91_pio_get_port(unsigned port)
  23{
  24        switch (port) {
  25        case AT91_PIO_PORTA:
  26                return (struct at91_port *)ATMEL_BASE_PIOA;
  27        case AT91_PIO_PORTB:
  28                return (struct at91_port *)ATMEL_BASE_PIOB;
  29        case AT91_PIO_PORTC:
  30                return (struct at91_port *)ATMEL_BASE_PIOC;
  31#if (ATMEL_PIO_PORTS > 3)
  32        case AT91_PIO_PORTD:
  33                return (struct at91_port *)ATMEL_BASE_PIOD;
  34#if (ATMEL_PIO_PORTS > 4)
  35        case AT91_PIO_PORTE:
  36                return (struct at91_port *)ATMEL_BASE_PIOE;
  37#endif
  38#endif
  39        default:
  40                printf("Error: at91_gpio: Fail to get PIO base!\n");
  41                return NULL;
  42        }
  43}
  44
  45static void at91_set_port_pullup(struct at91_port *at91_port, unsigned offset,
  46                                 int use_pullup)
  47{
  48        u32 mask;
  49
  50        mask = 1 << offset;
  51        if (use_pullup)
  52                writel(mask, &at91_port->puer);
  53        else
  54                writel(mask, &at91_port->pudr);
  55        writel(mask, &at91_port->per);
  56}
  57
  58int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
  59{
  60        struct at91_port *at91_port = at91_pio_get_port(port);
  61
  62#if defined(CPU_HAS_PIO3)
  63        if (use_pullup)
  64                at91_set_pio_pulldown(port, pin, 0);
  65#endif
  66
  67        if (at91_port && (pin < GPIO_PER_BANK))
  68                at91_set_port_pullup(at91_port, pin, use_pullup);
  69
  70        return 0;
  71}
  72
  73/*
  74 * mux the pin to the "GPIO" peripheral role.
  75 */
  76int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
  77{
  78        struct at91_port *at91_port = at91_pio_get_port(port);
  79        u32 mask;
  80
  81        if (at91_port && (pin < GPIO_PER_BANK)) {
  82                mask = 1 << pin;
  83                writel(mask, &at91_port->idr);
  84                at91_set_pio_pullup(port, pin, use_pullup);
  85                writel(mask, &at91_port->per);
  86        }
  87
  88        return 0;
  89}
  90
  91/*
  92 * mux the pin to the "A" internal peripheral role.
  93 */
  94int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
  95{
  96        struct at91_port *at91_port = at91_pio_get_port(port);
  97        u32 mask;
  98
  99        if (at91_port && (pin < GPIO_PER_BANK)) {
 100                mask = 1 << pin;
 101                writel(mask, &at91_port->idr);
 102                at91_set_pio_pullup(port, pin, use_pullup);
 103#if defined(CPU_HAS_PIO3)
 104                writel(readl(&at91_port->abcdsr1) & ~mask,
 105                       &at91_port->abcdsr1);
 106                writel(readl(&at91_port->abcdsr2) & ~mask,
 107                       &at91_port->abcdsr2);
 108#else
 109                writel(mask, &at91_port->asr);
 110#endif
 111                writel(mask, &at91_port->pdr);
 112        }
 113
 114        return 0;
 115}
 116
 117/*
 118 * mux the pin to the "B" internal peripheral role.
 119 */
 120int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
 121{
 122        struct at91_port *at91_port = at91_pio_get_port(port);
 123        u32 mask;
 124
 125        if (at91_port && (pin < GPIO_PER_BANK)) {
 126                mask = 1 << pin;
 127                writel(mask, &at91_port->idr);
 128                at91_set_pio_pullup(port, pin, use_pullup);
 129#if defined(CPU_HAS_PIO3)
 130                writel(readl(&at91_port->abcdsr1) | mask,
 131                       &at91_port->abcdsr1);
 132                writel(readl(&at91_port->abcdsr2) & ~mask,
 133                       &at91_port->abcdsr2);
 134#else
 135                writel(mask, &at91_port->bsr);
 136#endif
 137                writel(mask, &at91_port->pdr);
 138        }
 139
 140        return 0;
 141}
 142
 143#if defined(CPU_HAS_PIO3)
 144/*
 145 * mux the pin to the "C" internal peripheral role.
 146 */
 147int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)
 148{
 149        struct at91_port *at91_port = at91_pio_get_port(port);
 150        u32 mask;
 151
 152        if (at91_port && (pin < GPIO_PER_BANK)) {
 153                mask = 1 << pin;
 154                writel(mask, &at91_port->idr);
 155                at91_set_pio_pullup(port, pin, use_pullup);
 156                writel(readl(&at91_port->abcdsr1) & ~mask,
 157                       &at91_port->abcdsr1);
 158                writel(readl(&at91_port->abcdsr2) | mask,
 159                       &at91_port->abcdsr2);
 160                writel(mask, &at91_port->pdr);
 161        }
 162
 163        return 0;
 164}
 165
 166/*
 167 * mux the pin to the "D" internal peripheral role.
 168 */
 169int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
 170{
 171        struct at91_port *at91_port = at91_pio_get_port(port);
 172        u32 mask;
 173
 174        if (at91_port && (pin < GPIO_PER_BANK)) {
 175                mask = 1 << pin;
 176                writel(mask, &at91_port->idr);
 177                at91_set_pio_pullup(port, pin, use_pullup);
 178                writel(readl(&at91_port->abcdsr1) | mask,
 179                       &at91_port->abcdsr1);
 180                writel(readl(&at91_port->abcdsr2) | mask,
 181                       &at91_port->abcdsr2);
 182                writel(mask, &at91_port->pdr);
 183        }
 184
 185        return 0;
 186}
 187#endif
 188
 189#ifdef CONFIG_DM_GPIO
 190static bool at91_get_port_output(struct at91_port *at91_port, int offset)
 191{
 192        u32 mask, val;
 193
 194        mask = 1 << offset;
 195        val = readl(&at91_port->osr);
 196        return val & mask;
 197}
 198#endif
 199
 200static void at91_set_port_input(struct at91_port *at91_port, int offset,
 201                                int use_pullup)
 202{
 203        u32 mask;
 204
 205        mask = 1 << offset;
 206        writel(mask, &at91_port->idr);
 207        at91_set_port_pullup(at91_port, offset, use_pullup);
 208        writel(mask, &at91_port->odr);
 209        writel(mask, &at91_port->per);
 210}
 211
 212/*
 213 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
 214 * configure it for an input.
 215 */
 216int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
 217{
 218        struct at91_port *at91_port = at91_pio_get_port(port);
 219
 220        if (at91_port && (pin < GPIO_PER_BANK))
 221                at91_set_port_input(at91_port, pin, use_pullup);
 222
 223        return 0;
 224}
 225
 226static void at91_set_port_output(struct at91_port *at91_port, int offset,
 227                                 int value)
 228{
 229        u32 mask;
 230
 231        mask = 1 << offset;
 232        writel(mask, &at91_port->idr);
 233        writel(mask, &at91_port->pudr);
 234        if (value)
 235                writel(mask, &at91_port->sodr);
 236        else
 237                writel(mask, &at91_port->codr);
 238        writel(mask, &at91_port->oer);
 239        writel(mask, &at91_port->per);
 240}
 241
 242/*
 243 * mux the pin to the gpio controller (instead of "A" or "B" peripheral),
 244 * and configure it for an output.
 245 */
 246int at91_set_pio_output(unsigned port, u32 pin, int value)
 247{
 248        struct at91_port *at91_port = at91_pio_get_port(port);
 249
 250        if (at91_port && (pin < GPIO_PER_BANK))
 251                at91_set_port_output(at91_port, pin, value);
 252
 253        return 0;
 254}
 255
 256/*
 257 * enable/disable the glitch filter. mostly used with IRQ handling.
 258 */
 259int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
 260{
 261        struct at91_port *at91_port = at91_pio_get_port(port);
 262        u32 mask;
 263
 264        if (at91_port && (pin < GPIO_PER_BANK)) {
 265                mask = 1 << pin;
 266                if (is_on) {
 267#if defined(CPU_HAS_PIO3)
 268                        writel(mask, &at91_port->ifscdr);
 269#endif
 270                        writel(mask, &at91_port->ifer);
 271                } else {
 272                        writel(mask, &at91_port->ifdr);
 273                }
 274        }
 275
 276        return 0;
 277}
 278
 279#if defined(CPU_HAS_PIO3)
 280/*
 281 * enable/disable the debounce filter.
 282 */
 283int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)
 284{
 285        struct at91_port *at91_port = at91_pio_get_port(port);
 286        u32 mask;
 287
 288        if (at91_port && (pin < GPIO_PER_BANK)) {
 289                mask = 1 << pin;
 290                if (is_on) {
 291                        writel(mask, &at91_port->ifscer);
 292                        writel(div & PIO_SCDR_DIV, &at91_port->scdr);
 293                        writel(mask, &at91_port->ifer);
 294                } else {
 295                        writel(mask, &at91_port->ifdr);
 296                }
 297        }
 298
 299        return 0;
 300}
 301
 302/*
 303 * enable/disable the pull-down.
 304 * If pull-up already enabled while calling the function, we disable it.
 305 */
 306int at91_set_pio_pulldown(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 < GPIO_PER_BANK)) {
 312                mask = 1 << pin;
 313                if (is_on) {
 314                        at91_set_pio_pullup(port, pin, 0);
 315                        writel(mask, &at91_port->ppder);
 316                } else
 317                        writel(mask, &at91_port->ppddr);
 318        }
 319
 320        return 0;
 321}
 322
 323/*
 324 * disable Schmitt trigger
 325 */
 326int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)
 327{
 328        struct at91_port *at91_port = at91_pio_get_port(port);
 329        u32 mask;
 330
 331        if (at91_port && (pin < GPIO_PER_BANK)) {
 332                mask = 1 << pin;
 333                writel(readl(&at91_port->schmitt) | mask,
 334                       &at91_port->schmitt);
 335        }
 336
 337        return 0;
 338}
 339#endif
 340
 341/*
 342 * enable/disable the multi-driver. This is only valid for output and
 343 * allows the output pin to run as an open collector output.
 344 */
 345int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
 346{
 347        struct at91_port *at91_port = at91_pio_get_port(port);
 348        u32 mask;
 349
 350        if (at91_port && (pin < GPIO_PER_BANK)) {
 351                mask = 1 << pin;
 352                if (is_on)
 353                        writel(mask, &at91_port->mder);
 354                else
 355                        writel(mask, &at91_port->mddr);
 356        }
 357
 358        return 0;
 359}
 360
 361static void at91_set_port_value(struct at91_port *at91_port, int offset,
 362                                int value)
 363{
 364        u32 mask;
 365
 366        mask = 1 << offset;
 367        if (value)
 368                writel(mask, &at91_port->sodr);
 369        else
 370                writel(mask, &at91_port->codr);
 371}
 372
 373/*
 374 * assuming the pin is muxed as a gpio output, set its value.
 375 */
 376int at91_set_pio_value(unsigned port, unsigned pin, int value)
 377{
 378        struct at91_port *at91_port = at91_pio_get_port(port);
 379
 380        if (at91_port && (pin < GPIO_PER_BANK))
 381                at91_set_port_value(at91_port, pin, value);
 382
 383        return 0;
 384}
 385
 386static int at91_get_port_value(struct at91_port *at91_port, int offset)
 387{
 388        u32 pdsr = 0, mask;
 389
 390        mask = 1 << offset;
 391        pdsr = readl(&at91_port->pdsr) & mask;
 392
 393        return pdsr != 0;
 394}
 395/*
 396 * read the pin's value (works even if it's not muxed as a gpio).
 397 */
 398int at91_get_pio_value(unsigned port, unsigned pin)
 399{
 400        struct at91_port *at91_port = at91_pio_get_port(port);
 401
 402        if (at91_port && (pin < GPIO_PER_BANK))
 403                return at91_get_port_value(at91_port, pin);
 404
 405        return 0;
 406}
 407
 408#ifndef CONFIG_DM_GPIO
 409/* Common GPIO API */
 410
 411int gpio_request(unsigned gpio, const char *label)
 412{
 413        return 0;
 414}
 415
 416int gpio_free(unsigned gpio)
 417{
 418        return 0;
 419}
 420
 421int gpio_direction_input(unsigned gpio)
 422{
 423        at91_set_pio_input(at91_gpio_to_port(gpio),
 424                           at91_gpio_to_pin(gpio), 0);
 425        return 0;
 426}
 427
 428int gpio_direction_output(unsigned gpio, int value)
 429{
 430        at91_set_pio_output(at91_gpio_to_port(gpio),
 431                            at91_gpio_to_pin(gpio), value);
 432        return 0;
 433}
 434
 435int gpio_get_value(unsigned gpio)
 436{
 437        return at91_get_pio_value(at91_gpio_to_port(gpio),
 438                                  at91_gpio_to_pin(gpio));
 439}
 440
 441int gpio_set_value(unsigned gpio, int value)
 442{
 443        at91_set_pio_value(at91_gpio_to_port(gpio),
 444                           at91_gpio_to_pin(gpio), value);
 445
 446        return 0;
 447}
 448#endif
 449
 450#ifdef CONFIG_DM_GPIO
 451
 452struct at91_port_priv {
 453        struct at91_port *regs;
 454};
 455
 456/* set GPIO pin 'gpio' as an input */
 457static int at91_gpio_direction_input(struct udevice *dev, unsigned offset)
 458{
 459        struct at91_port_priv *port = dev_get_priv(dev);
 460
 461        at91_set_port_input(port->regs, offset, 0);
 462
 463        return 0;
 464}
 465
 466/* set GPIO pin 'gpio' as an output, with polarity 'value' */
 467static int at91_gpio_direction_output(struct udevice *dev, unsigned offset,
 468                                       int value)
 469{
 470        struct at91_port_priv *port = dev_get_priv(dev);
 471
 472        at91_set_port_output(port->regs, offset, value);
 473
 474        return 0;
 475}
 476
 477/* read GPIO IN value of pin 'gpio' */
 478static int at91_gpio_get_value(struct udevice *dev, unsigned offset)
 479{
 480        struct at91_port_priv *port = dev_get_priv(dev);
 481
 482        return at91_get_port_value(port->regs, offset);
 483}
 484
 485/* write GPIO OUT value to pin 'gpio' */
 486static int at91_gpio_set_value(struct udevice *dev, unsigned offset,
 487                               int value)
 488{
 489        struct at91_port_priv *port = dev_get_priv(dev);
 490
 491        at91_set_port_value(port->regs, offset, value);
 492
 493        return 0;
 494}
 495
 496static int at91_gpio_get_function(struct udevice *dev, unsigned offset)
 497{
 498        struct at91_port_priv *port = dev_get_priv(dev);
 499
 500        /* GPIOF_FUNC is not implemented yet */
 501        if (at91_get_port_output(port->regs, offset))
 502                return GPIOF_OUTPUT;
 503        else
 504                return GPIOF_INPUT;
 505}
 506
 507static const struct dm_gpio_ops gpio_at91_ops = {
 508        .direction_input        = at91_gpio_direction_input,
 509        .direction_output       = at91_gpio_direction_output,
 510        .get_value              = at91_gpio_get_value,
 511        .set_value              = at91_gpio_set_value,
 512        .get_function           = at91_gpio_get_function,
 513};
 514
 515static int at91_gpio_probe(struct udevice *dev)
 516{
 517        struct at91_port_priv *port = dev_get_priv(dev);
 518        struct at91_port_platdata *plat = dev_get_platdata(dev);
 519        struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 520
 521        uc_priv->bank_name = plat->bank_name;
 522        uc_priv->gpio_count = GPIO_PER_BANK;
 523        port->regs = (struct at91_port *)plat->base_addr;
 524
 525        return 0;
 526}
 527
 528U_BOOT_DRIVER(gpio_at91) = {
 529        .name   = "gpio_at91",
 530        .id     = UCLASS_GPIO,
 531        .ops    = &gpio_at91_ops,
 532        .probe  = at91_gpio_probe,
 533        .priv_auto_alloc_size = sizeof(struct at91_port_priv),
 534};
 535#endif
 536