1f517afd5SLaurence Withers /* 2f517afd5SLaurence Withers * GPIO driver for TI DaVinci DA8xx SOCs. 3f517afd5SLaurence Withers * 4f517afd5SLaurence Withers * (C) Copyright 2011 Guralp Systems Ltd. 5f517afd5SLaurence Withers * Laurence Withers <lwithers@guralp.com> 6f517afd5SLaurence Withers * 7f517afd5SLaurence Withers * This program is free software; you can redistribute it and/or 8f517afd5SLaurence Withers * modify it under the terms of the GNU General Public License as 9f517afd5SLaurence Withers * published by the Free Software Foundation; either version 2 of 10f517afd5SLaurence Withers * the License, or (at your option) any later version. 11f517afd5SLaurence Withers * 12f517afd5SLaurence Withers * This program is distributed in the hope that it will be useful, 13f517afd5SLaurence Withers * but WITHOUT ANY WARRANTY; without even the implied warranty of 14f517afd5SLaurence Withers * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15f517afd5SLaurence Withers * GNU General Public License for more details. 16f517afd5SLaurence Withers * 17f517afd5SLaurence Withers * You should have received a copy of the GNU General Public License 18f517afd5SLaurence Withers * along with this program; if not, write to the Free Software 19f517afd5SLaurence Withers * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20f517afd5SLaurence Withers * MA 02111-1307 USA 21f517afd5SLaurence Withers */ 22f517afd5SLaurence Withers 23f517afd5SLaurence Withers #include <common.h> 24f517afd5SLaurence Withers #include <asm/io.h> 25f517afd5SLaurence Withers #include <asm/gpio.h> 26f517afd5SLaurence Withers #include <asm/arch/hardware.h> 27f517afd5SLaurence Withers #include <asm/arch/davinci_misc.h> 28f517afd5SLaurence Withers 29f517afd5SLaurence Withers static struct gpio_registry { 30f517afd5SLaurence Withers int is_registered; 31f517afd5SLaurence Withers char name[GPIO_NAME_SIZE]; 32f517afd5SLaurence Withers } gpio_registry[MAX_NUM_GPIOS]; 33f517afd5SLaurence Withers 34f517afd5SLaurence Withers #define pinmux(x) (&davinci_syscfg_regs->pinmux[x]) 35f517afd5SLaurence Withers 36f517afd5SLaurence Withers static const struct pinmux_config gpio_pinmux[] = { 37f517afd5SLaurence Withers { pinmux(1), 8, 7 }, /* GP0[0] */ 38f517afd5SLaurence Withers { pinmux(1), 8, 6 }, 39f517afd5SLaurence Withers { pinmux(1), 8, 5 }, 40f517afd5SLaurence Withers { pinmux(1), 8, 4 }, 41f517afd5SLaurence Withers { pinmux(1), 8, 3 }, 42f517afd5SLaurence Withers { pinmux(1), 8, 2 }, 43f517afd5SLaurence Withers { pinmux(1), 8, 1 }, 44f517afd5SLaurence Withers { pinmux(1), 8, 0 }, 45f517afd5SLaurence Withers { pinmux(0), 8, 7 }, 46f517afd5SLaurence Withers { pinmux(0), 8, 6 }, 47f517afd5SLaurence Withers { pinmux(0), 8, 5 }, 48f517afd5SLaurence Withers { pinmux(0), 8, 4 }, 49f517afd5SLaurence Withers { pinmux(0), 8, 3 }, 50f517afd5SLaurence Withers { pinmux(0), 8, 2 }, 51f517afd5SLaurence Withers { pinmux(0), 8, 1 }, 52f517afd5SLaurence Withers { pinmux(0), 8, 0 }, 53f517afd5SLaurence Withers { pinmux(4), 8, 7 }, /* GP1[0] */ 54f517afd5SLaurence Withers { pinmux(4), 8, 6 }, 55f517afd5SLaurence Withers { pinmux(4), 8, 5 }, 56f517afd5SLaurence Withers { pinmux(4), 8, 4 }, 57f517afd5SLaurence Withers { pinmux(4), 8, 3 }, 58f517afd5SLaurence Withers { pinmux(4), 8, 2 }, 59f517afd5SLaurence Withers { pinmux(4), 4, 1 }, 60f517afd5SLaurence Withers { pinmux(4), 4, 0 }, 61f517afd5SLaurence Withers { pinmux(3), 4, 0 }, 62f517afd5SLaurence Withers { pinmux(2), 4, 6 }, 63f517afd5SLaurence Withers { pinmux(2), 4, 5 }, 64f517afd5SLaurence Withers { pinmux(2), 4, 4 }, 65f517afd5SLaurence Withers { pinmux(2), 4, 3 }, 66f517afd5SLaurence Withers { pinmux(2), 4, 2 }, 67f517afd5SLaurence Withers { pinmux(2), 4, 1 }, 68f517afd5SLaurence Withers { pinmux(2), 8, 0 }, 69f517afd5SLaurence Withers { pinmux(6), 8, 7 }, /* GP2[0] */ 70f517afd5SLaurence Withers { pinmux(6), 8, 6 }, 71f517afd5SLaurence Withers { pinmux(6), 8, 5 }, 72f517afd5SLaurence Withers { pinmux(6), 8, 4 }, 73f517afd5SLaurence Withers { pinmux(6), 8, 3 }, 74f517afd5SLaurence Withers { pinmux(6), 8, 2 }, 75f517afd5SLaurence Withers { pinmux(6), 8, 1 }, 76f517afd5SLaurence Withers { pinmux(6), 8, 0 }, 77f517afd5SLaurence Withers { pinmux(5), 8, 7 }, 78f517afd5SLaurence Withers { pinmux(5), 8, 6 }, 79f517afd5SLaurence Withers { pinmux(5), 8, 5 }, 80f517afd5SLaurence Withers { pinmux(5), 8, 4 }, 81f517afd5SLaurence Withers { pinmux(5), 8, 3 }, 82f517afd5SLaurence Withers { pinmux(5), 8, 2 }, 83f517afd5SLaurence Withers { pinmux(5), 8, 1 }, 84f517afd5SLaurence Withers { pinmux(5), 8, 0 }, 85f517afd5SLaurence Withers { pinmux(8), 8, 7 }, /* GP3[0] */ 86f517afd5SLaurence Withers { pinmux(8), 8, 6 }, 87f517afd5SLaurence Withers { pinmux(8), 8, 5 }, 88f517afd5SLaurence Withers { pinmux(8), 8, 4 }, 89f517afd5SLaurence Withers { pinmux(8), 8, 3 }, 90f517afd5SLaurence Withers { pinmux(8), 8, 2 }, 91f517afd5SLaurence Withers { pinmux(8), 8, 1 }, 92f517afd5SLaurence Withers { pinmux(8), 8, 0 }, 93f517afd5SLaurence Withers { pinmux(7), 8, 7 }, 94f517afd5SLaurence Withers { pinmux(7), 8, 6 }, 95f517afd5SLaurence Withers { pinmux(7), 8, 5 }, 96f517afd5SLaurence Withers { pinmux(7), 8, 4 }, 97f517afd5SLaurence Withers { pinmux(7), 8, 3 }, 98f517afd5SLaurence Withers { pinmux(7), 8, 2 }, 99f517afd5SLaurence Withers { pinmux(7), 8, 1 }, 100f517afd5SLaurence Withers { pinmux(7), 8, 0 }, 101f517afd5SLaurence Withers { pinmux(10), 8, 7 }, /* GP4[0] */ 102f517afd5SLaurence Withers { pinmux(10), 8, 6 }, 103f517afd5SLaurence Withers { pinmux(10), 8, 5 }, 104f517afd5SLaurence Withers { pinmux(10), 8, 4 }, 105f517afd5SLaurence Withers { pinmux(10), 8, 3 }, 106f517afd5SLaurence Withers { pinmux(10), 8, 2 }, 107f517afd5SLaurence Withers { pinmux(10), 8, 1 }, 108f517afd5SLaurence Withers { pinmux(10), 8, 0 }, 109f517afd5SLaurence Withers { pinmux(9), 8, 7 }, 110f517afd5SLaurence Withers { pinmux(9), 8, 6 }, 111f517afd5SLaurence Withers { pinmux(9), 8, 5 }, 112f517afd5SLaurence Withers { pinmux(9), 8, 4 }, 113f517afd5SLaurence Withers { pinmux(9), 8, 3 }, 114f517afd5SLaurence Withers { pinmux(9), 8, 2 }, 115f517afd5SLaurence Withers { pinmux(9), 8, 1 }, 116f517afd5SLaurence Withers { pinmux(9), 8, 0 }, 117f517afd5SLaurence Withers { pinmux(12), 8, 7 }, /* GP5[0] */ 118f517afd5SLaurence Withers { pinmux(12), 8, 6 }, 119f517afd5SLaurence Withers { pinmux(12), 8, 5 }, 120f517afd5SLaurence Withers { pinmux(12), 8, 4 }, 121f517afd5SLaurence Withers { pinmux(12), 8, 3 }, 122f517afd5SLaurence Withers { pinmux(12), 8, 2 }, 123f517afd5SLaurence Withers { pinmux(12), 8, 1 }, 124f517afd5SLaurence Withers { pinmux(12), 8, 0 }, 125f517afd5SLaurence Withers { pinmux(11), 8, 7 }, 126f517afd5SLaurence Withers { pinmux(11), 8, 6 }, 127f517afd5SLaurence Withers { pinmux(11), 8, 5 }, 128f517afd5SLaurence Withers { pinmux(11), 8, 4 }, 129f517afd5SLaurence Withers { pinmux(11), 8, 3 }, 130f517afd5SLaurence Withers { pinmux(11), 8, 2 }, 131f517afd5SLaurence Withers { pinmux(11), 8, 1 }, 132f517afd5SLaurence Withers { pinmux(11), 8, 0 }, 133f517afd5SLaurence Withers { pinmux(19), 8, 6 }, /* GP6[0] */ 134f517afd5SLaurence Withers { pinmux(19), 8, 5 }, 135f517afd5SLaurence Withers { pinmux(19), 8, 4 }, 136f517afd5SLaurence Withers { pinmux(19), 8, 3 }, 137f517afd5SLaurence Withers { pinmux(19), 8, 2 }, 138f517afd5SLaurence Withers { pinmux(16), 8, 1 }, 139f517afd5SLaurence Withers { pinmux(14), 8, 1 }, 140f517afd5SLaurence Withers { pinmux(14), 8, 0 }, 141f517afd5SLaurence Withers { pinmux(13), 8, 7 }, 142f517afd5SLaurence Withers { pinmux(13), 8, 6 }, 143f517afd5SLaurence Withers { pinmux(13), 8, 5 }, 144f517afd5SLaurence Withers { pinmux(13), 8, 4 }, 145f517afd5SLaurence Withers { pinmux(13), 8, 3 }, 146f517afd5SLaurence Withers { pinmux(13), 8, 2 }, 147f517afd5SLaurence Withers { pinmux(13), 8, 1 }, 148f517afd5SLaurence Withers { pinmux(13), 8, 0 }, 149f517afd5SLaurence Withers { pinmux(18), 8, 1 }, /* GP7[0] */ 150f517afd5SLaurence Withers { pinmux(18), 8, 0 }, 151f517afd5SLaurence Withers { pinmux(17), 8, 7 }, 152f517afd5SLaurence Withers { pinmux(17), 8, 6 }, 153f517afd5SLaurence Withers { pinmux(17), 8, 5 }, 154f517afd5SLaurence Withers { pinmux(17), 8, 4 }, 155f517afd5SLaurence Withers { pinmux(17), 8, 3 }, 156f517afd5SLaurence Withers { pinmux(17), 8, 2 }, 157f517afd5SLaurence Withers { pinmux(17), 8, 1 }, 158f517afd5SLaurence Withers { pinmux(17), 8, 0 }, 159f517afd5SLaurence Withers { pinmux(16), 8, 7 }, 160f517afd5SLaurence Withers { pinmux(16), 8, 6 }, 161f517afd5SLaurence Withers { pinmux(16), 8, 5 }, 162f517afd5SLaurence Withers { pinmux(16), 8, 4 }, 163f517afd5SLaurence Withers { pinmux(16), 8, 3 }, 164f517afd5SLaurence Withers { pinmux(16), 8, 2 }, 165f517afd5SLaurence Withers { pinmux(19), 8, 0 }, /* GP8[0] */ 166f517afd5SLaurence Withers { pinmux(3), 4, 7 }, 167f517afd5SLaurence Withers { pinmux(3), 4, 6 }, 168f517afd5SLaurence Withers { pinmux(3), 4, 5 }, 169f517afd5SLaurence Withers { pinmux(3), 4, 4 }, 170f517afd5SLaurence Withers { pinmux(3), 4, 3 }, 171f517afd5SLaurence Withers { pinmux(3), 4, 2 }, 172f517afd5SLaurence Withers { pinmux(2), 4, 7 }, 173f517afd5SLaurence Withers { pinmux(19), 8, 1 }, 174f517afd5SLaurence Withers { pinmux(19), 8, 0 }, 175f517afd5SLaurence Withers { pinmux(18), 8, 7 }, 176f517afd5SLaurence Withers { pinmux(18), 8, 6 }, 177f517afd5SLaurence Withers { pinmux(18), 8, 5 }, 178f517afd5SLaurence Withers { pinmux(18), 8, 4 }, 179f517afd5SLaurence Withers { pinmux(18), 8, 3 }, 180f517afd5SLaurence Withers { pinmux(18), 8, 2 }, 181f517afd5SLaurence Withers }; 182f517afd5SLaurence Withers 183*365d6070SJoe Hershberger int gpio_request(unsigned gpio, const char *label) 184f517afd5SLaurence Withers { 185*365d6070SJoe Hershberger if (gpio >= MAX_NUM_GPIOS) 186f517afd5SLaurence Withers return -1; 187f517afd5SLaurence Withers 188*365d6070SJoe Hershberger if (gpio_registry[gpio].is_registered) 189f517afd5SLaurence Withers return -1; 190f517afd5SLaurence Withers 191*365d6070SJoe Hershberger gpio_registry[gpio].is_registered = 1; 192*365d6070SJoe Hershberger strncpy(gpio_registry[gpio].name, label, GPIO_NAME_SIZE); 193*365d6070SJoe Hershberger gpio_registry[gpio].name[GPIO_NAME_SIZE - 1] = 0; 194f517afd5SLaurence Withers 195*365d6070SJoe Hershberger davinci_configure_pin_mux(&gpio_pinmux[gpio], 1); 196f517afd5SLaurence Withers 197f517afd5SLaurence Withers return 0; 198f517afd5SLaurence Withers } 199f517afd5SLaurence Withers 200*365d6070SJoe Hershberger int gpio_free(unsigned gpio) 201f517afd5SLaurence Withers { 202*365d6070SJoe Hershberger if (gpio >= MAX_NUM_GPIOS) 203*365d6070SJoe Hershberger return -1; 204*365d6070SJoe Hershberger 205*365d6070SJoe Hershberger if (!gpio_registry[gpio].is_registered) 206*365d6070SJoe Hershberger return -1; 207*365d6070SJoe Hershberger 208*365d6070SJoe Hershberger gpio_registry[gpio].is_registered = 0; 209*365d6070SJoe Hershberger gpio_registry[gpio].name[0] = '\0'; 210*365d6070SJoe Hershberger /* Do not configure as input or change pin mux here */ 211*365d6070SJoe Hershberger return 0; 212f517afd5SLaurence Withers } 213f517afd5SLaurence Withers 214*365d6070SJoe Hershberger int gpio_direction_input(unsigned gpio) 215f517afd5SLaurence Withers { 216f517afd5SLaurence Withers struct davinci_gpio *bank; 217f517afd5SLaurence Withers 218*365d6070SJoe Hershberger bank = GPIO_BANK(gpio); 219*365d6070SJoe Hershberger setbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); 220f517afd5SLaurence Withers return 0; 221f517afd5SLaurence Withers } 222f517afd5SLaurence Withers 223*365d6070SJoe Hershberger int gpio_direction_output(unsigned gpio, int value) 224f517afd5SLaurence Withers { 225f517afd5SLaurence Withers struct davinci_gpio *bank; 226f517afd5SLaurence Withers 227*365d6070SJoe Hershberger bank = GPIO_BANK(gpio); 228*365d6070SJoe Hershberger clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); 229*365d6070SJoe Hershberger gpio_set_value(gpio, value); 230f517afd5SLaurence Withers return 0; 231f517afd5SLaurence Withers } 232f517afd5SLaurence Withers 233*365d6070SJoe Hershberger int gpio_get_value(unsigned gpio) 234f517afd5SLaurence Withers { 235f517afd5SLaurence Withers struct davinci_gpio *bank; 236f517afd5SLaurence Withers unsigned int ip; 237f517afd5SLaurence Withers 238*365d6070SJoe Hershberger bank = GPIO_BANK(gpio); 239*365d6070SJoe Hershberger ip = in_le32(&bank->in_data) & (1U << GPIO_BIT(gpio)); 240f517afd5SLaurence Withers return ip ? 1 : 0; 241f517afd5SLaurence Withers } 242f517afd5SLaurence Withers 243*365d6070SJoe Hershberger int gpio_set_value(unsigned gpio, int value) 244f517afd5SLaurence Withers { 245f517afd5SLaurence Withers struct davinci_gpio *bank; 246f517afd5SLaurence Withers 247*365d6070SJoe Hershberger bank = GPIO_BANK(gpio); 248f517afd5SLaurence Withers 249f517afd5SLaurence Withers if (value) 250*365d6070SJoe Hershberger bank->set_data = 1U << GPIO_BIT(gpio); 251f517afd5SLaurence Withers else 252*365d6070SJoe Hershberger bank->clr_data = 1U << GPIO_BIT(gpio); 253*365d6070SJoe Hershberger 254*365d6070SJoe Hershberger return 0; 255f517afd5SLaurence Withers } 256f517afd5SLaurence Withers 257f517afd5SLaurence Withers void gpio_info(void) 258f517afd5SLaurence Withers { 259*365d6070SJoe Hershberger unsigned gpio, dir, val; 260f517afd5SLaurence Withers struct davinci_gpio *bank; 261f517afd5SLaurence Withers 262*365d6070SJoe Hershberger for (gpio = 0; gpio < MAX_NUM_GPIOS; ++gpio) { 263*365d6070SJoe Hershberger bank = GPIO_BANK(gpio); 264*365d6070SJoe Hershberger dir = in_le32(&bank->dir) & (1U << GPIO_BIT(gpio)); 265*365d6070SJoe Hershberger val = gpio_get_value(gpio); 266f517afd5SLaurence Withers 267f517afd5SLaurence Withers printf("% 4d: %s: %d [%c] %s\n", 268*365d6070SJoe Hershberger gpio, dir ? " in" : "out", val, 269*365d6070SJoe Hershberger gpio_registry[gpio].is_registered ? 'x' : ' ', 270*365d6070SJoe Hershberger gpio_registry[gpio].name); 271f517afd5SLaurence Withers } 272f517afd5SLaurence Withers } 273