uboot/arch/blackfin/cpu/gpio.c
<<
>>
Prefs
   1/*
   2 * GPIO Abstraction Layer
   3 *
   4 * Copyright 2006-2010 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2 or later
   7 */
   8
   9#include <common.h>
  10#include <asm/errno.h>
  11#include <asm/gpio.h>
  12#include <asm/portmux.h>
  13
  14#if ANOMALY_05000311 || ANOMALY_05000323
  15enum {
  16        AWA_data = SYSCR,
  17        AWA_data_clear = SYSCR,
  18        AWA_data_set = SYSCR,
  19        AWA_toggle = SYSCR,
  20        AWA_maska = UART_SCR,
  21        AWA_maska_clear = UART_SCR,
  22        AWA_maska_set = UART_SCR,
  23        AWA_maska_toggle = UART_SCR,
  24        AWA_maskb = UART_GCTL,
  25        AWA_maskb_clear = UART_GCTL,
  26        AWA_maskb_set = UART_GCTL,
  27        AWA_maskb_toggle = UART_GCTL,
  28        AWA_dir = SPORT1_STAT,
  29        AWA_polar = SPORT1_STAT,
  30        AWA_edge = SPORT1_STAT,
  31        AWA_both = SPORT1_STAT,
  32#if ANOMALY_05000311
  33        AWA_inen = TIMER_ENABLE,
  34#elif ANOMALY_05000323
  35        AWA_inen = DMA1_1_CONFIG,
  36#endif
  37};
  38        /* Anomaly Workaround */
  39#define AWA_DUMMY_READ(name) bfin_read16(AWA_ ## name)
  40#else
  41#define AWA_DUMMY_READ(...)  do { } while (0)
  42#endif
  43
  44static struct gpio_port_t * const gpio_array[] = {
  45#if defined(BF533_FAMILY)
  46        (struct gpio_port_t *) FIO_FLAG_D,
  47#elif defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) \
  48        || defined(BF538_FAMILY) || defined(CONFIG_BF50x)
  49        (struct gpio_port_t *) PORTFIO,
  50# if !defined(BF538_FAMILY)
  51        (struct gpio_port_t *) PORTGIO,
  52        (struct gpio_port_t *) PORTHIO,
  53# endif
  54#elif defined(BF561_FAMILY)
  55        (struct gpio_port_t *) FIO0_FLAG_D,
  56        (struct gpio_port_t *) FIO1_FLAG_D,
  57        (struct gpio_port_t *) FIO2_FLAG_D,
  58#elif defined(CONFIG_BF54x)
  59        (struct gpio_port_t *)PORTA_FER,
  60        (struct gpio_port_t *)PORTB_FER,
  61        (struct gpio_port_t *)PORTC_FER,
  62        (struct gpio_port_t *)PORTD_FER,
  63        (struct gpio_port_t *)PORTE_FER,
  64        (struct gpio_port_t *)PORTF_FER,
  65        (struct gpio_port_t *)PORTG_FER,
  66        (struct gpio_port_t *)PORTH_FER,
  67        (struct gpio_port_t *)PORTI_FER,
  68        (struct gpio_port_t *)PORTJ_FER,
  69#else
  70# error no gpio arrays defined
  71#endif
  72};
  73
  74#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) || \
  75    defined(CONFIG_BF50x)
  76static unsigned short * const port_fer[] = {
  77        (unsigned short *) PORTF_FER,
  78        (unsigned short *) PORTG_FER,
  79        (unsigned short *) PORTH_FER,
  80};
  81
  82# if !defined(BF537_FAMILY)
  83static unsigned short * const port_mux[] = {
  84        (unsigned short *) PORTF_MUX,
  85        (unsigned short *) PORTG_MUX,
  86        (unsigned short *) PORTH_MUX,
  87};
  88
  89static const
  90u8 pmux_offset[][16] = {
  91#  if defined(CONFIG_BF52x)
  92        { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */
  93        { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */
  94        { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */
  95#  elif defined(CONFIG_BF51x)
  96        { 0, 2, 2, 2, 2, 2, 2, 4, 6, 6, 6, 8, 8, 8, 8, 10 }, /* PORTF */
  97        { 0, 0, 0, 2, 4, 6, 6, 6, 8, 10, 10, 12, 14, 14, 14, 14 }, /* PORTG */
  98        { 0, 0, 0, 0, 2, 2, 4, 6, 10, 10, 10, 10, 10, 10, 10, 10 }, /* PORTH */
  99#  endif
 100};
 101# endif
 102
 103#elif defined(BF538_FAMILY)
 104static unsigned short * const port_fer[] = {
 105        (unsigned short *) PORTCIO_FER,
 106        (unsigned short *) PORTDIO_FER,
 107        (unsigned short *) PORTEIO_FER,
 108};
 109#endif
 110
 111#ifdef CONFIG_BFIN_GPIO_TRACK
 112#define RESOURCE_LABEL_SIZE     16
 113
 114static struct str_ident {
 115        char name[RESOURCE_LABEL_SIZE];
 116} str_ident[MAX_RESOURCES];
 117
 118static void gpio_error(unsigned gpio)
 119{
 120        printf("bfin-gpio: GPIO %d wasn't requested!\n", gpio);
 121}
 122
 123static void set_label(unsigned short ident, const char *label)
 124{
 125        if (label) {
 126                strncpy(str_ident[ident].name, label,
 127                         RESOURCE_LABEL_SIZE);
 128                str_ident[ident].name[RESOURCE_LABEL_SIZE - 1] = 0;
 129        }
 130}
 131
 132static char *get_label(unsigned short ident)
 133{
 134        return (*str_ident[ident].name ? str_ident[ident].name : "UNKNOWN");
 135}
 136
 137static int cmp_label(unsigned short ident, const char *label)
 138{
 139        if (label == NULL)
 140                printf("bfin-gpio: please provide none-null label\n");
 141
 142        if (label)
 143                return strcmp(str_ident[ident].name, label);
 144        else
 145                return -EINVAL;
 146}
 147
 148#define map_entry(m, i)      reserved_##m##_map[gpio_bank(i)]
 149#define is_reserved(m, i, e) (map_entry(m, i) & gpio_bit(i))
 150#define reserve(m, i)        (map_entry(m, i) |= gpio_bit(i))
 151#define unreserve(m, i)      (map_entry(m, i) &= ~gpio_bit(i))
 152#define DECLARE_RESERVED_MAP(m, c) static unsigned short reserved_##m##_map[c]
 153#else
 154#define is_reserved(m, i, e) (!(e))
 155#define reserve(m, i)
 156#define unreserve(m, i)
 157#define DECLARE_RESERVED_MAP(m, c)
 158#define gpio_error(gpio)
 159#define set_label(...)
 160#define get_label(...) ""
 161#define cmp_label(...) 1
 162#endif
 163
 164DECLARE_RESERVED_MAP(gpio, GPIO_BANK_NUM);
 165DECLARE_RESERVED_MAP(peri, gpio_bank(MAX_RESOURCES));
 166
 167inline int check_gpio(unsigned gpio)
 168{
 169#if defined(CONFIG_BF54x)
 170        if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
 171            || gpio == GPIO_PH14 || gpio == GPIO_PH15
 172            || gpio == GPIO_PJ14 || gpio == GPIO_PJ15)
 173                return -EINVAL;
 174#endif
 175        if (gpio >= MAX_BLACKFIN_GPIOS)
 176                return -EINVAL;
 177        return 0;
 178}
 179
 180static void port_setup(unsigned gpio, unsigned short usage)
 181{
 182#if defined(BF538_FAMILY)
 183        /*
 184         * BF538/9 Port C,D and E are special.
 185         * Inverted PORT_FER polarity on CDE and no PORF_FER on F
 186         * Regular PORT F GPIOs are handled here, CDE are exclusively
 187         * managed by GPIOLIB
 188         */
 189
 190        if (gpio < MAX_BLACKFIN_GPIOS || gpio >= MAX_RESOURCES)
 191                return;
 192
 193        gpio -= MAX_BLACKFIN_GPIOS;
 194
 195        if (usage == GPIO_USAGE)
 196                *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
 197        else
 198                *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
 199        SSYNC();
 200        return;
 201#endif
 202
 203        if (check_gpio(gpio))
 204                return;
 205
 206#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) || \
 207    defined(CONFIG_BF50x)
 208        if (usage == GPIO_USAGE)
 209                *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
 210        else
 211                *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
 212        SSYNC();
 213#elif defined(CONFIG_BF54x)
 214        if (usage == GPIO_USAGE)
 215                gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
 216        else
 217                gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
 218        SSYNC();
 219#endif
 220}
 221
 222#ifdef BF537_FAMILY
 223static struct {
 224        unsigned short res;
 225        unsigned short offset;
 226} port_mux_lut[] = {
 227        {.res = P_PPI0_D13, .offset = 11},
 228        {.res = P_PPI0_D14, .offset = 11},
 229        {.res = P_PPI0_D15, .offset = 11},
 230        {.res = P_SPORT1_TFS, .offset = 11},
 231        {.res = P_SPORT1_TSCLK, .offset = 11},
 232        {.res = P_SPORT1_DTPRI, .offset = 11},
 233        {.res = P_PPI0_D10, .offset = 10},
 234        {.res = P_PPI0_D11, .offset = 10},
 235        {.res = P_PPI0_D12, .offset = 10},
 236        {.res = P_SPORT1_RSCLK, .offset = 10},
 237        {.res = P_SPORT1_RFS, .offset = 10},
 238        {.res = P_SPORT1_DRPRI, .offset = 10},
 239        {.res = P_PPI0_D8, .offset = 9},
 240        {.res = P_PPI0_D9, .offset = 9},
 241        {.res = P_SPORT1_DRSEC, .offset = 9},
 242        {.res = P_SPORT1_DTSEC, .offset = 9},
 243        {.res = P_TMR2, .offset = 8},
 244        {.res = P_PPI0_FS3, .offset = 8},
 245        {.res = P_TMR3, .offset = 7},
 246        {.res = P_SPI0_SSEL4, .offset = 7},
 247        {.res = P_TMR4, .offset = 6},
 248        {.res = P_SPI0_SSEL5, .offset = 6},
 249        {.res = P_TMR5, .offset = 5},
 250        {.res = P_SPI0_SSEL6, .offset = 5},
 251        {.res = P_UART1_RX, .offset = 4},
 252        {.res = P_UART1_TX, .offset = 4},
 253        {.res = P_TMR6, .offset = 4},
 254        {.res = P_TMR7, .offset = 4},
 255        {.res = P_UART0_RX, .offset = 3},
 256        {.res = P_UART0_TX, .offset = 3},
 257        {.res = P_DMAR0, .offset = 3},
 258        {.res = P_DMAR1, .offset = 3},
 259        {.res = P_SPORT0_DTSEC, .offset = 1},
 260        {.res = P_SPORT0_DRSEC, .offset = 1},
 261        {.res = P_CAN0_RX, .offset = 1},
 262        {.res = P_CAN0_TX, .offset = 1},
 263        {.res = P_SPI0_SSEL7, .offset = 1},
 264        {.res = P_SPORT0_TFS, .offset = 0},
 265        {.res = P_SPORT0_DTPRI, .offset = 0},
 266        {.res = P_SPI0_SSEL2, .offset = 0},
 267        {.res = P_SPI0_SSEL3, .offset = 0},
 268};
 269
 270static void portmux_setup(unsigned short per)
 271{
 272        u16 y, offset, muxreg;
 273        u16 function = P_FUNCT2MUX(per);
 274
 275        for (y = 0; y < ARRAY_SIZE(port_mux_lut); y++) {
 276                if (port_mux_lut[y].res == per) {
 277
 278                        /* SET PORTMUX REG */
 279
 280                        offset = port_mux_lut[y].offset;
 281                        muxreg = bfin_read_PORT_MUX();
 282
 283                        if (offset != 1)
 284                                muxreg &= ~(1 << offset);
 285                        else
 286                                muxreg &= ~(3 << 1);
 287
 288                        muxreg |= (function << offset);
 289                        bfin_write_PORT_MUX(muxreg);
 290                }
 291        }
 292}
 293#elif defined(CONFIG_BF54x)
 294inline void portmux_setup(unsigned short per)
 295{
 296        u32 pmux;
 297        u16 ident = P_IDENT(per);
 298        u16 function = P_FUNCT2MUX(per);
 299
 300        pmux = gpio_array[gpio_bank(ident)]->port_mux;
 301
 302        pmux &= ~(0x3 << (2 * gpio_sub_n(ident)));
 303        pmux |= (function & 0x3) << (2 * gpio_sub_n(ident));
 304
 305        gpio_array[gpio_bank(ident)]->port_mux = pmux;
 306}
 307
 308inline u16 get_portmux(unsigned short per)
 309{
 310        u32 pmux;
 311        u16 ident = P_IDENT(per);
 312
 313        pmux = gpio_array[gpio_bank(ident)]->port_mux;
 314
 315        return (pmux >> (2 * gpio_sub_n(ident)) & 0x3);
 316}
 317#elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
 318inline void portmux_setup(unsigned short per)
 319{
 320        u16 pmux, ident = P_IDENT(per), function = P_FUNCT2MUX(per);
 321        u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)];
 322
 323        pmux = *port_mux[gpio_bank(ident)];
 324        pmux &= ~(3 << offset);
 325        pmux |= (function & 3) << offset;
 326        *port_mux[gpio_bank(ident)] = pmux;
 327        SSYNC();
 328}
 329#else
 330# define portmux_setup(...)  do { } while (0)
 331#endif
 332
 333#ifndef CONFIG_BF54x
 334/***********************************************************
 335*
 336* FUNCTIONS: Blackfin General Purpose Ports Access Functions
 337*
 338* INPUTS/OUTPUTS:
 339* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
 340*
 341*
 342* DESCRIPTION: These functions abstract direct register access
 343*              to Blackfin processor General Purpose
 344*              Ports Regsiters
 345*
 346* CAUTION: These functions do not belong to the GPIO Driver API
 347*************************************************************
 348* MODIFICATION HISTORY :
 349**************************************************************/
 350
 351/* Set a specific bit */
 352
 353#define SET_GPIO(name) \
 354void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
 355{ \
 356        unsigned long flags; \
 357        local_irq_save(flags); \
 358        if (arg) \
 359                gpio_array[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
 360        else \
 361                gpio_array[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \
 362        AWA_DUMMY_READ(name); \
 363        local_irq_restore(flags); \
 364}
 365
 366SET_GPIO(dir)   /* set_gpio_dir() */
 367SET_GPIO(inen)  /* set_gpio_inen() */
 368SET_GPIO(polar) /* set_gpio_polar() */
 369SET_GPIO(edge)  /* set_gpio_edge() */
 370SET_GPIO(both)  /* set_gpio_both() */
 371
 372
 373#define SET_GPIO_SC(name) \
 374void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
 375{ \
 376        unsigned long flags; \
 377        if (ANOMALY_05000311 || ANOMALY_05000323) \
 378                local_irq_save(flags); \
 379        if (arg) \
 380                gpio_array[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
 381        else \
 382                gpio_array[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
 383        if (ANOMALY_05000311 || ANOMALY_05000323) { \
 384                AWA_DUMMY_READ(name); \
 385                local_irq_restore(flags); \
 386        } \
 387}
 388
 389SET_GPIO_SC(maska)
 390SET_GPIO_SC(maskb)
 391SET_GPIO_SC(data)
 392
 393void set_gpio_toggle(unsigned gpio)
 394{
 395        unsigned long flags;
 396        if (ANOMALY_05000311 || ANOMALY_05000323)
 397                local_irq_save(flags);
 398        gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
 399        if (ANOMALY_05000311 || ANOMALY_05000323) {
 400                AWA_DUMMY_READ(toggle);
 401                local_irq_restore(flags);
 402        }
 403}
 404
 405/* Set current PORT date (16-bit word) */
 406
 407#define SET_GPIO_P(name) \
 408void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \
 409{ \
 410        unsigned long flags; \
 411        if (ANOMALY_05000311 || ANOMALY_05000323) \
 412                local_irq_save(flags); \
 413        gpio_array[gpio_bank(gpio)]->name = arg; \
 414        if (ANOMALY_05000311 || ANOMALY_05000323) { \
 415                AWA_DUMMY_READ(name); \
 416                local_irq_restore(flags); \
 417        } \
 418}
 419
 420SET_GPIO_P(data)
 421SET_GPIO_P(dir)
 422SET_GPIO_P(inen)
 423SET_GPIO_P(polar)
 424SET_GPIO_P(edge)
 425SET_GPIO_P(both)
 426SET_GPIO_P(maska)
 427SET_GPIO_P(maskb)
 428
 429/* Get a specific bit */
 430#define GET_GPIO(name) \
 431unsigned short get_gpio_ ## name(unsigned gpio) \
 432{ \
 433        unsigned long flags; \
 434        unsigned short ret; \
 435        if (ANOMALY_05000311 || ANOMALY_05000323) \
 436                local_irq_save(flags); \
 437        ret = 0x01 & (gpio_array[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \
 438        if (ANOMALY_05000311 || ANOMALY_05000323) { \
 439                AWA_DUMMY_READ(name); \
 440                local_irq_restore(flags); \
 441        } \
 442        return ret; \
 443}
 444
 445GET_GPIO(data)
 446GET_GPIO(dir)
 447GET_GPIO(inen)
 448GET_GPIO(polar)
 449GET_GPIO(edge)
 450GET_GPIO(both)
 451GET_GPIO(maska)
 452GET_GPIO(maskb)
 453
 454/* Get current PORT date (16-bit word) */
 455
 456#define GET_GPIO_P(name) \
 457unsigned short get_gpiop_ ## name(unsigned gpio) \
 458{ \
 459        unsigned long flags; \
 460        unsigned short ret; \
 461        if (ANOMALY_05000311 || ANOMALY_05000323) \
 462                local_irq_save(flags); \
 463        ret = (gpio_array[gpio_bank(gpio)]->name); \
 464        if (ANOMALY_05000311 || ANOMALY_05000323) { \
 465                AWA_DUMMY_READ(name); \
 466                local_irq_restore(flags); \
 467        } \
 468        return ret; \
 469}
 470
 471GET_GPIO_P(data)
 472GET_GPIO_P(dir)
 473GET_GPIO_P(inen)
 474GET_GPIO_P(polar)
 475GET_GPIO_P(edge)
 476GET_GPIO_P(both)
 477GET_GPIO_P(maska)
 478GET_GPIO_P(maskb)
 479
 480#else /* CONFIG_BF54x */
 481
 482unsigned short get_gpio_dir(unsigned gpio)
 483{
 484        return (0x01 & (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio)));
 485}
 486
 487#endif /* CONFIG_BF54x */
 488
 489/***********************************************************
 490*
 491* FUNCTIONS:    Blackfin Peripheral Resource Allocation
 492*               and PortMux Setup
 493*
 494* INPUTS/OUTPUTS:
 495* per   Peripheral Identifier
 496* label String
 497*
 498* DESCRIPTION: Blackfin Peripheral Resource Allocation and Setup API
 499*
 500* CAUTION:
 501*************************************************************
 502* MODIFICATION HISTORY :
 503**************************************************************/
 504
 505int peripheral_request(unsigned short per, const char *label)
 506{
 507        unsigned short ident = P_IDENT(per);
 508
 509        /*
 510         * Don't cares are pins with only one dedicated function
 511         */
 512
 513        if (per & P_DONTCARE)
 514                return 0;
 515
 516        if (!(per & P_DEFINED))
 517                return -ENODEV;
 518
 519        BUG_ON(ident >= MAX_RESOURCES);
 520
 521        /* If a pin can be muxed as either GPIO or peripheral, make
 522         * sure it is not already a GPIO pin when we request it.
 523         */
 524        if (unlikely(!check_gpio(ident) && is_reserved(gpio, ident, 1))) {
 525                printf("%s: Peripheral %d is already reserved as GPIO by %s !\n",
 526                       __func__, ident, get_label(ident));
 527                return -EBUSY;
 528        }
 529
 530        if (unlikely(is_reserved(peri, ident, 1))) {
 531
 532                /*
 533                 * Pin functions like AMC address strobes my
 534                 * be requested and used by several drivers
 535                 */
 536
 537#ifdef CONFIG_BF54x
 538                if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) {
 539#else
 540                if (!(per & P_MAYSHARE)) {
 541#endif
 542                        /*
 543                         * Allow that the identical pin function can
 544                         * be requested from the same driver twice
 545                         */
 546
 547                        if (cmp_label(ident, label) == 0)
 548                                goto anyway;
 549
 550                        printf("%s: Peripheral %d function %d is already reserved by %s !\n",
 551                               __func__, ident, P_FUNCT2MUX(per), get_label(ident));
 552                        return -EBUSY;
 553                }
 554        }
 555
 556 anyway:
 557        reserve(peri, ident);
 558
 559        portmux_setup(per);
 560        port_setup(ident, PERIPHERAL_USAGE);
 561
 562        set_label(ident, label);
 563
 564        return 0;
 565}
 566
 567int peripheral_request_list(const unsigned short per[], const char *label)
 568{
 569        u16 cnt;
 570        int ret;
 571
 572        for (cnt = 0; per[cnt] != 0; cnt++) {
 573
 574                ret = peripheral_request(per[cnt], label);
 575
 576                if (ret < 0) {
 577                        for ( ; cnt > 0; cnt--)
 578                                peripheral_free(per[cnt - 1]);
 579
 580                        return ret;
 581                }
 582        }
 583
 584        return 0;
 585}
 586
 587void peripheral_free(unsigned short per)
 588{
 589        unsigned short ident = P_IDENT(per);
 590
 591        if (per & P_DONTCARE)
 592                return;
 593
 594        if (!(per & P_DEFINED))
 595                return;
 596
 597        if (unlikely(!is_reserved(peri, ident, 0)))
 598                return;
 599
 600        if (!(per & P_MAYSHARE))
 601                port_setup(ident, GPIO_USAGE);
 602
 603        unreserve(peri, ident);
 604
 605        set_label(ident, "free");
 606}
 607
 608void peripheral_free_list(const unsigned short per[])
 609{
 610        u16 cnt;
 611        for (cnt = 0; per[cnt] != 0; cnt++)
 612                peripheral_free(per[cnt]);
 613}
 614
 615/***********************************************************
 616*
 617* FUNCTIONS: Blackfin GPIO Driver
 618*
 619* INPUTS/OUTPUTS:
 620* gpio  PIO Number between 0 and MAX_BLACKFIN_GPIOS
 621* label String
 622*
 623* DESCRIPTION: Blackfin GPIO Driver API
 624*
 625* CAUTION:
 626*************************************************************
 627* MODIFICATION HISTORY :
 628**************************************************************/
 629
 630int bfin_gpio_request(unsigned gpio, const char *label)
 631{
 632        if (check_gpio(gpio) < 0)
 633                return -EINVAL;
 634
 635        /*
 636         * Allow that the identical GPIO can
 637         * be requested from the same driver twice
 638         * Do nothing and return -
 639         */
 640
 641        if (cmp_label(gpio, label) == 0)
 642                return 0;
 643
 644        if (unlikely(is_reserved(gpio, gpio, 1))) {
 645                printf("bfin-gpio: GPIO %d is already reserved by %s !\n",
 646                       gpio, get_label(gpio));
 647                return -EBUSY;
 648        }
 649        if (unlikely(is_reserved(peri, gpio, 1))) {
 650                printf("bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
 651                       gpio, get_label(gpio));
 652                return -EBUSY;
 653        }
 654#ifndef CONFIG_BF54x
 655        else {  /* Reset POLAR setting when acquiring a gpio for the first time */
 656                set_gpio_polar(gpio, 0);
 657        }
 658#endif
 659
 660        reserve(gpio, gpio);
 661        set_label(gpio, label);
 662
 663        port_setup(gpio, GPIO_USAGE);
 664
 665        return 0;
 666}
 667
 668#ifdef CONFIG_BFIN_GPIO_TRACK
 669void bfin_gpio_free(unsigned gpio)
 670{
 671        if (check_gpio(gpio) < 0)
 672                return;
 673
 674        if (unlikely(!is_reserved(gpio, gpio, 0))) {
 675                gpio_error(gpio);
 676                return;
 677        }
 678
 679        unreserve(gpio, gpio);
 680
 681        set_label(gpio, "free");
 682}
 683#endif
 684
 685#ifdef BFIN_SPECIAL_GPIO_BANKS
 686DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES));
 687
 688int bfin_special_gpio_request(unsigned gpio, const char *label)
 689{
 690        /*
 691         * Allow that the identical GPIO can
 692         * be requested from the same driver twice
 693         * Do nothing and return -
 694         */
 695
 696        if (cmp_label(gpio, label) == 0)
 697                return 0;
 698
 699        if (unlikely(is_reserved(special_gpio, gpio, 1))) {
 700                printf("bfin-gpio: GPIO %d is already reserved by %s !\n",
 701                       gpio, get_label(gpio));
 702                return -EBUSY;
 703        }
 704        if (unlikely(is_reserved(peri, gpio, 1))) {
 705                printf("bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
 706                       gpio, get_label(gpio));
 707
 708                return -EBUSY;
 709        }
 710
 711        reserve(special_gpio, gpio);
 712        reserve(peri, gpio);
 713
 714        set_label(gpio, label);
 715        port_setup(gpio, GPIO_USAGE);
 716
 717        return 0;
 718}
 719
 720void bfin_special_gpio_free(unsigned gpio)
 721{
 722        if (unlikely(!is_reserved(special_gpio, gpio, 0))) {
 723                gpio_error(gpio);
 724                return;
 725        }
 726
 727        reserve(special_gpio, gpio);
 728        reserve(peri, gpio);
 729        set_label(gpio, "free");
 730}
 731#endif
 732
 733static inline void __bfin_gpio_direction_input(unsigned gpio)
 734{
 735#ifdef CONFIG_BF54x
 736        gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio);
 737#else
 738        gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
 739#endif
 740        gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
 741}
 742
 743int bfin_gpio_direction_input(unsigned gpio)
 744{
 745        unsigned long flags;
 746
 747        if (!is_reserved(gpio, gpio, 0)) {
 748                gpio_error(gpio);
 749                return -EINVAL;
 750        }
 751
 752        local_irq_save(flags);
 753        __bfin_gpio_direction_input(gpio);
 754        AWA_DUMMY_READ(inen);
 755        local_irq_restore(flags);
 756
 757        return 0;
 758}
 759
 760void bfin_gpio_toggle_value(unsigned gpio)
 761{
 762#ifdef CONFIG_BF54x
 763        gpio_set_value(gpio, !gpio_get_value(gpio));
 764#else
 765        gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
 766#endif
 767}
 768
 769void bfin_gpio_set_value(unsigned gpio, int arg)
 770{
 771        if (arg)
 772                gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
 773        else
 774                gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
 775}
 776
 777int bfin_gpio_direction_output(unsigned gpio, int value)
 778{
 779        unsigned long flags;
 780
 781        if (!is_reserved(gpio, gpio, 0)) {
 782                gpio_error(gpio);
 783                return -EINVAL;
 784        }
 785
 786        local_irq_save(flags);
 787
 788        gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
 789        gpio_set_value(gpio, value);
 790#ifdef CONFIG_BF54x
 791        gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio);
 792#else
 793        gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
 794#endif
 795
 796        AWA_DUMMY_READ(dir);
 797        local_irq_restore(flags);
 798
 799        return 0;
 800}
 801
 802int bfin_gpio_get_value(unsigned gpio)
 803{
 804#ifdef CONFIG_BF54x
 805        return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)));
 806#else
 807        unsigned long flags;
 808
 809        if (unlikely(get_gpio_edge(gpio))) {
 810                int ret;
 811                local_irq_save(flags);
 812                set_gpio_edge(gpio, 0);
 813                ret = get_gpio_data(gpio);
 814                set_gpio_edge(gpio, 1);
 815                local_irq_restore(flags);
 816                return ret;
 817        } else
 818                return get_gpio_data(gpio);
 819#endif
 820}
 821
 822/* If we are booting from SPI and our board lacks a strong enough pull up,
 823 * the core can reset and execute the bootrom faster than the resistor can
 824 * pull the signal logically high.  To work around this (common) error in
 825 * board design, we explicitly set the pin back to GPIO mode, force /CS
 826 * high, and wait for the electrons to do their thing.
 827 *
 828 * This function only makes sense to be called from reset code, but it
 829 * lives here as we need to force all the GPIO states w/out going through
 830 * BUG() checks and such.
 831 */
 832void bfin_reset_boot_spi_cs(unsigned short pin)
 833{
 834        unsigned short gpio = P_IDENT(pin);
 835        port_setup(gpio, GPIO_USAGE);
 836        gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
 837        AWA_DUMMY_READ(data_set);
 838        udelay(1);
 839}
 840
 841#ifdef CONFIG_BFIN_GPIO_TRACK
 842void bfin_gpio_labels(void)
 843{
 844        int c, gpio;
 845
 846        for (c = 0; c < MAX_RESOURCES; c++) {
 847                gpio = is_reserved(gpio, c, 1);
 848                if (!check_gpio(c) && gpio)
 849                        printf("GPIO_%d:\t%s\tGPIO %s\n", c,
 850                                get_label(c),
 851                                get_gpio_dir(c) ? "OUTPUT" : "INPUT");
 852                else if (is_reserved(peri, c, 1))
 853                        printf("GPIO_%d:\t%s\tPeripheral\n", c, get_label(c));
 854                else
 855                        continue;
 856        }
 857}
 858#endif
 859