uboot/arch/powerpc/cpu/ppc4xx/gpio.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2007-2008
   3 * Stefan Roese, DENX Software Engineering, sr@denx.de.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24#include <common.h>
  25#include <asm/processor.h>
  26#include <asm/io.h>
  27#include <asm/gpio.h>
  28
  29#if defined(CONFIG_SYS_4xx_GPIO_TABLE)
  30gpio_param_s const gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CONFIG_SYS_4xx_GPIO_TABLE;
  31#endif
  32
  33#if defined(GPIO0_OSRL)
  34/* Only some 4xx variants support alternate funtions on the GPIO's */
  35void gpio_config(int pin, int in_out, int gpio_alt, int out_val)
  36{
  37        u32 mask;
  38        u32 mask2;
  39        u32 val;
  40        u32 offs = 0;
  41        u32 offs2 = 0;
  42        int pin2 = pin << 1;
  43
  44        if (pin >= GPIO_MAX) {
  45                offs = 0x100;
  46                pin -= GPIO_MAX;
  47        }
  48
  49        if (pin >= GPIO_MAX/2) {
  50                offs2 = 0x4;
  51                pin2 = (pin - GPIO_MAX/2) << 1;
  52        }
  53
  54        mask = 0x80000000 >> pin;
  55        mask2 = 0xc0000000 >> pin2;
  56
  57        /* first set TCR to 0 */
  58        out_be32((void *)GPIO0_TCR + offs, in_be32((void *)GPIO0_TCR + offs) & ~mask);
  59
  60        if (in_out == GPIO_OUT) {
  61                val = in_be32((void *)GPIO0_OSRL + offs + offs2) & ~mask2;
  62                switch (gpio_alt) {
  63                case GPIO_ALT1:
  64                        val |= GPIO_ALT1_SEL >> pin2;
  65                        break;
  66                case GPIO_ALT2:
  67                        val |= GPIO_ALT2_SEL >> pin2;
  68                        break;
  69                case GPIO_ALT3:
  70                        val |= GPIO_ALT3_SEL >> pin2;
  71                        break;
  72                }
  73                out_be32((void *)GPIO0_OSRL + offs + offs2, val);
  74
  75                /* setup requested output value */
  76                if (out_val == GPIO_OUT_0)
  77                        out_be32((void *)GPIO0_OR + offs,
  78                                 in_be32((void *)GPIO0_OR + offs) & ~mask);
  79                else if (out_val == GPIO_OUT_1)
  80                        out_be32((void *)GPIO0_OR + offs,
  81                                 in_be32((void *)GPIO0_OR + offs) | mask);
  82
  83                /* now configure TCR to drive output if selected */
  84                out_be32((void *)GPIO0_TCR + offs,
  85                         in_be32((void *)GPIO0_TCR + offs) | mask);
  86        } else {
  87                val = in_be32((void *)GPIO0_ISR1L + offs + offs2) & ~mask2;
  88                val |= GPIO_IN_SEL >> pin2;
  89                out_be32((void *)GPIO0_ISR1L + offs + offs2, val);
  90        }
  91}
  92#endif /* GPIO_OSRL */
  93
  94void gpio_write_bit(int pin, int val)
  95{
  96        u32 offs = 0;
  97
  98        if (pin >= GPIO_MAX) {
  99                offs = 0x100;
 100                pin -= GPIO_MAX;
 101        }
 102
 103        if (val)
 104                out_be32((void *)GPIO0_OR + offs,
 105                         in_be32((void *)GPIO0_OR + offs) | GPIO_VAL(pin));
 106        else
 107                out_be32((void *)GPIO0_OR + offs,
 108                         in_be32((void *)GPIO0_OR + offs) & ~GPIO_VAL(pin));
 109}
 110
 111int gpio_read_out_bit(int pin)
 112{
 113        u32 offs = 0;
 114
 115        if (pin >= GPIO_MAX) {
 116                offs = 0x100;
 117                pin -= GPIO_MAX;
 118        }
 119
 120        return (in_be32((void *)GPIO0_OR + offs) & GPIO_VAL(pin) ? 1 : 0);
 121}
 122
 123int gpio_read_in_bit(int pin)
 124{
 125        u32 offs = 0;
 126
 127        if (pin >= GPIO_MAX) {
 128                offs = 0x100;
 129                pin -= GPIO_MAX;
 130        }
 131
 132        return (in_be32((void *)GPIO0_IR + offs) & GPIO_VAL(pin) ? 1 : 0);
 133}
 134
 135#if defined(CONFIG_SYS_4xx_GPIO_TABLE)
 136void gpio_set_chip_configuration(void)
 137{
 138        unsigned char i=0, j=0, offs=0, gpio_core;
 139        unsigned long reg, core_add;
 140
 141        for (gpio_core=0; gpio_core<GPIO_GROUP_MAX; gpio_core++) {
 142                j = 0;
 143                offs = 0;
 144                /* GPIO config of the GPIOs 0 to 31 */
 145                for (i=0; i<GPIO_MAX; i++, j++) {
 146                        if (i == GPIO_MAX/2) {
 147                                offs = 4;
 148                                j = i-16;
 149                        }
 150
 151                        core_add = gpio_tab[gpio_core][i].add;
 152
 153                        if ((gpio_tab[gpio_core][i].in_out == GPIO_IN) ||
 154                            (gpio_tab[gpio_core][i].in_out == GPIO_BI)) {
 155
 156                                switch (gpio_tab[gpio_core][i].alt_nb) {
 157                                case GPIO_SEL:
 158                                        break;
 159
 160                                case GPIO_ALT1:
 161                                        reg = in_be32((void *)GPIO_IS1(core_add+offs))
 162                                                & ~(GPIO_MASK >> (j*2));
 163                                        reg = reg | (GPIO_IN_SEL >> (j*2));
 164                                        out_be32((void *)GPIO_IS1(core_add+offs), reg);
 165                                        break;
 166
 167                                case GPIO_ALT2:
 168                                        reg = in_be32((void *)GPIO_IS2(core_add+offs))
 169                                                & ~(GPIO_MASK >> (j*2));
 170                                        reg = reg | (GPIO_IN_SEL >> (j*2));
 171                                        out_be32((void *)GPIO_IS2(core_add+offs), reg);
 172                                        break;
 173
 174                                case GPIO_ALT3:
 175                                        reg = in_be32((void *)GPIO_IS3(core_add+offs))
 176                                                & ~(GPIO_MASK >> (j*2));
 177                                        reg = reg | (GPIO_IN_SEL >> (j*2));
 178                                        out_be32((void *)GPIO_IS3(core_add+offs), reg);
 179                                        break;
 180                                }
 181                        }
 182
 183                        if ((gpio_tab[gpio_core][i].in_out == GPIO_OUT) ||
 184                            (gpio_tab[gpio_core][i].in_out == GPIO_BI)) {
 185
 186                                u32 gpio_alt_sel = 0;
 187
 188                                switch (gpio_tab[gpio_core][i].alt_nb) {
 189                                case GPIO_SEL:
 190                                        /*
 191                                         * Setup output value
 192                                         * 1 -> high level
 193                                         * 0 -> low level
 194                                         * else -> don't touch
 195                                         */
 196                                        reg = in_be32((void *)GPIO_OR(core_add));
 197                                        if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1)
 198                                                reg |= (0x80000000 >> (i));
 199                                        else if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_0)
 200                                                reg &= ~(0x80000000 >> (i));
 201                                        out_be32((void *)GPIO_OR(core_add), reg);
 202
 203                                        reg = in_be32((void *)GPIO_TCR(core_add)) |
 204                                                (0x80000000 >> (i));
 205                                        out_be32((void *)GPIO_TCR(core_add), reg);
 206
 207                                        reg = in_be32((void *)GPIO_OS(core_add+offs))
 208                                                & ~(GPIO_MASK >> (j*2));
 209                                        out_be32((void *)GPIO_OS(core_add+offs), reg);
 210                                        reg = in_be32((void *)GPIO_TS(core_add+offs))
 211                                                & ~(GPIO_MASK >> (j*2));
 212                                        out_be32((void *)GPIO_TS(core_add+offs), reg);
 213                                        break;
 214
 215                                case GPIO_ALT1:
 216                                        gpio_alt_sel = GPIO_ALT1_SEL;
 217                                        break;
 218
 219                                case GPIO_ALT2:
 220                                        gpio_alt_sel = GPIO_ALT2_SEL;
 221                                        break;
 222
 223                                case GPIO_ALT3:
 224                                        gpio_alt_sel = GPIO_ALT3_SEL;
 225                                        break;
 226                                }
 227
 228                                if (0 != gpio_alt_sel) {
 229                                        reg = in_be32((void *)GPIO_OS(core_add+offs))
 230                                                & ~(GPIO_MASK >> (j*2));
 231                                        reg = reg | (gpio_alt_sel >> (j*2));
 232                                        out_be32((void *)GPIO_OS(core_add+offs), reg);
 233
 234                                        if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1) {
 235                                                reg = in_be32((void *)GPIO_TCR(core_add))
 236                                                        | (0x80000000 >> (i));
 237                                                out_be32((void *)GPIO_TCR(core_add), reg);
 238                                                reg = in_be32((void *)GPIO_TS(core_add+offs))
 239                                                        & ~(GPIO_MASK >> (j*2));
 240                                                out_be32((void *)GPIO_TS(core_add+offs), reg);
 241                                        } else {
 242                                                reg = in_be32((void *)GPIO_TCR(core_add))
 243                                                        & ~(0x80000000 >> (i));
 244                                                out_be32((void *)GPIO_TCR(core_add), reg);
 245                                                reg = in_be32((void *)GPIO_TS(core_add+offs))
 246                                                        & ~(GPIO_MASK >> (j*2));
 247                                                reg = reg | (gpio_alt_sel >> (j*2));
 248                                                out_be32((void *)GPIO_TS(core_add+offs), reg);
 249                                        }
 250                                }
 251                        }
 252                }
 253        }
 254}
 255#endif /* CONFIG_SYS_4xx_GPIO_TABLE */
 256