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 34*03414ac4SHolger Hans Peter Freyther #if defined(CONFIG_SOC_DA8XX) 35f517afd5SLaurence Withers #define pinmux(x) (&davinci_syscfg_regs->pinmux[x]) 36f517afd5SLaurence Withers 37f517afd5SLaurence Withers static const struct pinmux_config gpio_pinmux[] = { 38f517afd5SLaurence Withers { pinmux(1), 8, 7 }, /* GP0[0] */ 39f517afd5SLaurence Withers { pinmux(1), 8, 6 }, 40f517afd5SLaurence Withers { pinmux(1), 8, 5 }, 41f517afd5SLaurence Withers { pinmux(1), 8, 4 }, 42f517afd5SLaurence Withers { pinmux(1), 8, 3 }, 43f517afd5SLaurence Withers { pinmux(1), 8, 2 }, 44f517afd5SLaurence Withers { pinmux(1), 8, 1 }, 45f517afd5SLaurence Withers { pinmux(1), 8, 0 }, 46f517afd5SLaurence Withers { pinmux(0), 8, 7 }, 47f517afd5SLaurence Withers { pinmux(0), 8, 6 }, 48f517afd5SLaurence Withers { pinmux(0), 8, 5 }, 49f517afd5SLaurence Withers { pinmux(0), 8, 4 }, 50f517afd5SLaurence Withers { pinmux(0), 8, 3 }, 51f517afd5SLaurence Withers { pinmux(0), 8, 2 }, 52f517afd5SLaurence Withers { pinmux(0), 8, 1 }, 53f517afd5SLaurence Withers { pinmux(0), 8, 0 }, 54f517afd5SLaurence Withers { pinmux(4), 8, 7 }, /* GP1[0] */ 55f517afd5SLaurence Withers { pinmux(4), 8, 6 }, 56f517afd5SLaurence Withers { pinmux(4), 8, 5 }, 57f517afd5SLaurence Withers { pinmux(4), 8, 4 }, 58f517afd5SLaurence Withers { pinmux(4), 8, 3 }, 59f517afd5SLaurence Withers { pinmux(4), 8, 2 }, 60f517afd5SLaurence Withers { pinmux(4), 4, 1 }, 61f517afd5SLaurence Withers { pinmux(4), 4, 0 }, 62f517afd5SLaurence Withers { pinmux(3), 4, 0 }, 63f517afd5SLaurence Withers { pinmux(2), 4, 6 }, 64f517afd5SLaurence Withers { pinmux(2), 4, 5 }, 65f517afd5SLaurence Withers { pinmux(2), 4, 4 }, 66f517afd5SLaurence Withers { pinmux(2), 4, 3 }, 67f517afd5SLaurence Withers { pinmux(2), 4, 2 }, 68f517afd5SLaurence Withers { pinmux(2), 4, 1 }, 69f517afd5SLaurence Withers { pinmux(2), 8, 0 }, 70f517afd5SLaurence Withers { pinmux(6), 8, 7 }, /* GP2[0] */ 71f517afd5SLaurence Withers { pinmux(6), 8, 6 }, 72f517afd5SLaurence Withers { pinmux(6), 8, 5 }, 73f517afd5SLaurence Withers { pinmux(6), 8, 4 }, 74f517afd5SLaurence Withers { pinmux(6), 8, 3 }, 75f517afd5SLaurence Withers { pinmux(6), 8, 2 }, 76f517afd5SLaurence Withers { pinmux(6), 8, 1 }, 77f517afd5SLaurence Withers { pinmux(6), 8, 0 }, 78f517afd5SLaurence Withers { pinmux(5), 8, 7 }, 79f517afd5SLaurence Withers { pinmux(5), 8, 6 }, 80f517afd5SLaurence Withers { pinmux(5), 8, 5 }, 81f517afd5SLaurence Withers { pinmux(5), 8, 4 }, 82f517afd5SLaurence Withers { pinmux(5), 8, 3 }, 83f517afd5SLaurence Withers { pinmux(5), 8, 2 }, 84f517afd5SLaurence Withers { pinmux(5), 8, 1 }, 85f517afd5SLaurence Withers { pinmux(5), 8, 0 }, 86f517afd5SLaurence Withers { pinmux(8), 8, 7 }, /* GP3[0] */ 87f517afd5SLaurence Withers { pinmux(8), 8, 6 }, 88f517afd5SLaurence Withers { pinmux(8), 8, 5 }, 89f517afd5SLaurence Withers { pinmux(8), 8, 4 }, 90f517afd5SLaurence Withers { pinmux(8), 8, 3 }, 91f517afd5SLaurence Withers { pinmux(8), 8, 2 }, 92f517afd5SLaurence Withers { pinmux(8), 8, 1 }, 93f517afd5SLaurence Withers { pinmux(8), 8, 0 }, 94f517afd5SLaurence Withers { pinmux(7), 8, 7 }, 95f517afd5SLaurence Withers { pinmux(7), 8, 6 }, 96f517afd5SLaurence Withers { pinmux(7), 8, 5 }, 97f517afd5SLaurence Withers { pinmux(7), 8, 4 }, 98f517afd5SLaurence Withers { pinmux(7), 8, 3 }, 99f517afd5SLaurence Withers { pinmux(7), 8, 2 }, 100f517afd5SLaurence Withers { pinmux(7), 8, 1 }, 101f517afd5SLaurence Withers { pinmux(7), 8, 0 }, 102f517afd5SLaurence Withers { pinmux(10), 8, 7 }, /* GP4[0] */ 103f517afd5SLaurence Withers { pinmux(10), 8, 6 }, 104f517afd5SLaurence Withers { pinmux(10), 8, 5 }, 105f517afd5SLaurence Withers { pinmux(10), 8, 4 }, 106f517afd5SLaurence Withers { pinmux(10), 8, 3 }, 107f517afd5SLaurence Withers { pinmux(10), 8, 2 }, 108f517afd5SLaurence Withers { pinmux(10), 8, 1 }, 109f517afd5SLaurence Withers { pinmux(10), 8, 0 }, 110f517afd5SLaurence Withers { pinmux(9), 8, 7 }, 111f517afd5SLaurence Withers { pinmux(9), 8, 6 }, 112f517afd5SLaurence Withers { pinmux(9), 8, 5 }, 113f517afd5SLaurence Withers { pinmux(9), 8, 4 }, 114f517afd5SLaurence Withers { pinmux(9), 8, 3 }, 115f517afd5SLaurence Withers { pinmux(9), 8, 2 }, 116f517afd5SLaurence Withers { pinmux(9), 8, 1 }, 117f517afd5SLaurence Withers { pinmux(9), 8, 0 }, 118f517afd5SLaurence Withers { pinmux(12), 8, 7 }, /* GP5[0] */ 119f517afd5SLaurence Withers { pinmux(12), 8, 6 }, 120f517afd5SLaurence Withers { pinmux(12), 8, 5 }, 121f517afd5SLaurence Withers { pinmux(12), 8, 4 }, 122f517afd5SLaurence Withers { pinmux(12), 8, 3 }, 123f517afd5SLaurence Withers { pinmux(12), 8, 2 }, 124f517afd5SLaurence Withers { pinmux(12), 8, 1 }, 125f517afd5SLaurence Withers { pinmux(12), 8, 0 }, 126f517afd5SLaurence Withers { pinmux(11), 8, 7 }, 127f517afd5SLaurence Withers { pinmux(11), 8, 6 }, 128f517afd5SLaurence Withers { pinmux(11), 8, 5 }, 129f517afd5SLaurence Withers { pinmux(11), 8, 4 }, 130f517afd5SLaurence Withers { pinmux(11), 8, 3 }, 131f517afd5SLaurence Withers { pinmux(11), 8, 2 }, 132f517afd5SLaurence Withers { pinmux(11), 8, 1 }, 133f517afd5SLaurence Withers { pinmux(11), 8, 0 }, 134f517afd5SLaurence Withers { pinmux(19), 8, 6 }, /* GP6[0] */ 135f517afd5SLaurence Withers { pinmux(19), 8, 5 }, 136f517afd5SLaurence Withers { pinmux(19), 8, 4 }, 137f517afd5SLaurence Withers { pinmux(19), 8, 3 }, 138f517afd5SLaurence Withers { pinmux(19), 8, 2 }, 139f517afd5SLaurence Withers { pinmux(16), 8, 1 }, 140f517afd5SLaurence Withers { pinmux(14), 8, 1 }, 141f517afd5SLaurence Withers { pinmux(14), 8, 0 }, 142f517afd5SLaurence Withers { pinmux(13), 8, 7 }, 143f517afd5SLaurence Withers { pinmux(13), 8, 6 }, 144f517afd5SLaurence Withers { pinmux(13), 8, 5 }, 145f517afd5SLaurence Withers { pinmux(13), 8, 4 }, 146f517afd5SLaurence Withers { pinmux(13), 8, 3 }, 147f517afd5SLaurence Withers { pinmux(13), 8, 2 }, 148f517afd5SLaurence Withers { pinmux(13), 8, 1 }, 149f517afd5SLaurence Withers { pinmux(13), 8, 0 }, 150f517afd5SLaurence Withers { pinmux(18), 8, 1 }, /* GP7[0] */ 151f517afd5SLaurence Withers { pinmux(18), 8, 0 }, 152f517afd5SLaurence Withers { pinmux(17), 8, 7 }, 153f517afd5SLaurence Withers { pinmux(17), 8, 6 }, 154f517afd5SLaurence Withers { pinmux(17), 8, 5 }, 155f517afd5SLaurence Withers { pinmux(17), 8, 4 }, 156f517afd5SLaurence Withers { pinmux(17), 8, 3 }, 157f517afd5SLaurence Withers { pinmux(17), 8, 2 }, 158f517afd5SLaurence Withers { pinmux(17), 8, 1 }, 159f517afd5SLaurence Withers { pinmux(17), 8, 0 }, 160f517afd5SLaurence Withers { pinmux(16), 8, 7 }, 161f517afd5SLaurence Withers { pinmux(16), 8, 6 }, 162f517afd5SLaurence Withers { pinmux(16), 8, 5 }, 163f517afd5SLaurence Withers { pinmux(16), 8, 4 }, 164f517afd5SLaurence Withers { pinmux(16), 8, 3 }, 165f517afd5SLaurence Withers { pinmux(16), 8, 2 }, 166f517afd5SLaurence Withers { pinmux(19), 8, 0 }, /* GP8[0] */ 167f517afd5SLaurence Withers { pinmux(3), 4, 7 }, 168f517afd5SLaurence Withers { pinmux(3), 4, 6 }, 169f517afd5SLaurence Withers { pinmux(3), 4, 5 }, 170f517afd5SLaurence Withers { pinmux(3), 4, 4 }, 171f517afd5SLaurence Withers { pinmux(3), 4, 3 }, 172f517afd5SLaurence Withers { pinmux(3), 4, 2 }, 173f517afd5SLaurence Withers { pinmux(2), 4, 7 }, 174f517afd5SLaurence Withers { pinmux(19), 8, 1 }, 175f517afd5SLaurence Withers { pinmux(19), 8, 0 }, 176f517afd5SLaurence Withers { pinmux(18), 8, 7 }, 177f517afd5SLaurence Withers { pinmux(18), 8, 6 }, 178f517afd5SLaurence Withers { pinmux(18), 8, 5 }, 179f517afd5SLaurence Withers { pinmux(18), 8, 4 }, 180f517afd5SLaurence Withers { pinmux(18), 8, 3 }, 181f517afd5SLaurence Withers { pinmux(18), 8, 2 }, 182f517afd5SLaurence Withers }; 183*03414ac4SHolger Hans Peter Freyther #else 184*03414ac4SHolger Hans Peter Freyther #define davinci_configure_pin_mux(a, b) 185*03414ac4SHolger Hans Peter Freyther #endif 186f517afd5SLaurence Withers 187365d6070SJoe Hershberger int gpio_request(unsigned gpio, const char *label) 188f517afd5SLaurence Withers { 189365d6070SJoe Hershberger if (gpio >= MAX_NUM_GPIOS) 190f517afd5SLaurence Withers return -1; 191f517afd5SLaurence Withers 192365d6070SJoe Hershberger if (gpio_registry[gpio].is_registered) 193f517afd5SLaurence Withers return -1; 194f517afd5SLaurence Withers 195365d6070SJoe Hershberger gpio_registry[gpio].is_registered = 1; 196365d6070SJoe Hershberger strncpy(gpio_registry[gpio].name, label, GPIO_NAME_SIZE); 197365d6070SJoe Hershberger gpio_registry[gpio].name[GPIO_NAME_SIZE - 1] = 0; 198f517afd5SLaurence Withers 199365d6070SJoe Hershberger davinci_configure_pin_mux(&gpio_pinmux[gpio], 1); 200f517afd5SLaurence Withers 201f517afd5SLaurence Withers return 0; 202f517afd5SLaurence Withers } 203f517afd5SLaurence Withers 204365d6070SJoe Hershberger int gpio_free(unsigned gpio) 205f517afd5SLaurence Withers { 206365d6070SJoe Hershberger if (gpio >= MAX_NUM_GPIOS) 207365d6070SJoe Hershberger return -1; 208365d6070SJoe Hershberger 209365d6070SJoe Hershberger if (!gpio_registry[gpio].is_registered) 210365d6070SJoe Hershberger return -1; 211365d6070SJoe Hershberger 212365d6070SJoe Hershberger gpio_registry[gpio].is_registered = 0; 213365d6070SJoe Hershberger gpio_registry[gpio].name[0] = '\0'; 214365d6070SJoe Hershberger /* Do not configure as input or change pin mux here */ 215365d6070SJoe Hershberger return 0; 216f517afd5SLaurence Withers } 217f517afd5SLaurence Withers 218365d6070SJoe Hershberger int gpio_direction_input(unsigned gpio) 219f517afd5SLaurence Withers { 220f517afd5SLaurence Withers struct davinci_gpio *bank; 221f517afd5SLaurence Withers 222365d6070SJoe Hershberger bank = GPIO_BANK(gpio); 223365d6070SJoe Hershberger setbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); 224f517afd5SLaurence Withers return 0; 225f517afd5SLaurence Withers } 226f517afd5SLaurence Withers 227365d6070SJoe Hershberger int gpio_direction_output(unsigned gpio, int value) 228f517afd5SLaurence Withers { 229f517afd5SLaurence Withers struct davinci_gpio *bank; 230f517afd5SLaurence Withers 231365d6070SJoe Hershberger bank = GPIO_BANK(gpio); 232365d6070SJoe Hershberger clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); 233365d6070SJoe Hershberger gpio_set_value(gpio, value); 234f517afd5SLaurence Withers return 0; 235f517afd5SLaurence Withers } 236f517afd5SLaurence Withers 237365d6070SJoe Hershberger int gpio_get_value(unsigned gpio) 238f517afd5SLaurence Withers { 239f517afd5SLaurence Withers struct davinci_gpio *bank; 240f517afd5SLaurence Withers unsigned int ip; 241f517afd5SLaurence Withers 242365d6070SJoe Hershberger bank = GPIO_BANK(gpio); 243365d6070SJoe Hershberger ip = in_le32(&bank->in_data) & (1U << GPIO_BIT(gpio)); 244f517afd5SLaurence Withers return ip ? 1 : 0; 245f517afd5SLaurence Withers } 246f517afd5SLaurence Withers 247365d6070SJoe Hershberger int gpio_set_value(unsigned gpio, int value) 248f517afd5SLaurence Withers { 249f517afd5SLaurence Withers struct davinci_gpio *bank; 250f517afd5SLaurence Withers 251365d6070SJoe Hershberger bank = GPIO_BANK(gpio); 252f517afd5SLaurence Withers 253f517afd5SLaurence Withers if (value) 254365d6070SJoe Hershberger bank->set_data = 1U << GPIO_BIT(gpio); 255f517afd5SLaurence Withers else 256365d6070SJoe Hershberger bank->clr_data = 1U << GPIO_BIT(gpio); 257365d6070SJoe Hershberger 258365d6070SJoe Hershberger return 0; 259f517afd5SLaurence Withers } 260f517afd5SLaurence Withers 261f517afd5SLaurence Withers void gpio_info(void) 262f517afd5SLaurence Withers { 263365d6070SJoe Hershberger unsigned gpio, dir, val; 264f517afd5SLaurence Withers struct davinci_gpio *bank; 265f517afd5SLaurence Withers 266365d6070SJoe Hershberger for (gpio = 0; gpio < MAX_NUM_GPIOS; ++gpio) { 267365d6070SJoe Hershberger bank = GPIO_BANK(gpio); 268365d6070SJoe Hershberger dir = in_le32(&bank->dir) & (1U << GPIO_BIT(gpio)); 269365d6070SJoe Hershberger val = gpio_get_value(gpio); 270f517afd5SLaurence Withers 271f517afd5SLaurence Withers printf("% 4d: %s: %d [%c] %s\n", 272365d6070SJoe Hershberger gpio, dir ? " in" : "out", val, 273365d6070SJoe Hershberger gpio_registry[gpio].is_registered ? 'x' : ' ', 274365d6070SJoe Hershberger gpio_registry[gpio].name); 275f517afd5SLaurence Withers } 276f517afd5SLaurence Withers } 277