183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 2f517afd5SLaurence Withers /* 3f517afd5SLaurence Withers * GPIO driver for TI DaVinci DA8xx SOCs. 4f517afd5SLaurence Withers * 5f517afd5SLaurence Withers * (C) Copyright 2011 Guralp Systems Ltd. 6f517afd5SLaurence Withers * Laurence Withers <lwithers@guralp.com> 7f517afd5SLaurence Withers */ 8f517afd5SLaurence Withers 9f517afd5SLaurence Withers #include <common.h> 108e51c0f2SAdam Ford #include <dm.h> 118e51c0f2SAdam Ford #include <fdtdec.h> 12f517afd5SLaurence Withers #include <asm/io.h> 13f517afd5SLaurence Withers #include <asm/gpio.h> 141eddf549SAdam Ford #include <dt-bindings/gpio/gpio.h> 15f517afd5SLaurence Withers 16*0f3cf2b3SKeerthy #include "da8xx_gpio.h" 17*0f3cf2b3SKeerthy 188e51c0f2SAdam Ford #ifndef CONFIG_DM_GPIO 19*0f3cf2b3SKeerthy #include <asm/arch/hardware.h> 20*0f3cf2b3SKeerthy #include <asm/arch/davinci_misc.h> 21*0f3cf2b3SKeerthy 22f517afd5SLaurence Withers static struct gpio_registry { 23f517afd5SLaurence Withers int is_registered; 24f517afd5SLaurence Withers char name[GPIO_NAME_SIZE]; 25f517afd5SLaurence Withers } gpio_registry[MAX_NUM_GPIOS]; 26f517afd5SLaurence Withers 2703414ac4SHolger Hans Peter Freyther #if defined(CONFIG_SOC_DA8XX) 28f517afd5SLaurence Withers #define pinmux(x) (&davinci_syscfg_regs->pinmux[x]) 29f517afd5SLaurence Withers 30b9f56698STomas Novotny #if defined(CONFIG_SOC_DA8XX) && !defined(CONFIG_SOC_DA850) 31b9f56698STomas Novotny static const struct pinmux_config gpio_pinmux[] = { 32b9f56698STomas Novotny { pinmux(13), 8, 6 }, /* GP0[0] */ 33b9f56698STomas Novotny { pinmux(13), 8, 7 }, 34b9f56698STomas Novotny { pinmux(14), 8, 0 }, 35b9f56698STomas Novotny { pinmux(14), 8, 1 }, 36b9f56698STomas Novotny { pinmux(14), 8, 2 }, 37b9f56698STomas Novotny { pinmux(14), 8, 3 }, 38b9f56698STomas Novotny { pinmux(14), 8, 4 }, 39b9f56698STomas Novotny { pinmux(14), 8, 5 }, 40b9f56698STomas Novotny { pinmux(14), 8, 6 }, 41b9f56698STomas Novotny { pinmux(14), 8, 7 }, 42b9f56698STomas Novotny { pinmux(15), 8, 0 }, 43b9f56698STomas Novotny { pinmux(15), 8, 1 }, 44b9f56698STomas Novotny { pinmux(15), 8, 2 }, 45b9f56698STomas Novotny { pinmux(15), 8, 3 }, 46b9f56698STomas Novotny { pinmux(15), 8, 4 }, 47b9f56698STomas Novotny { pinmux(15), 8, 5 }, 48b9f56698STomas Novotny { pinmux(15), 8, 6 }, /* GP1[0] */ 49b9f56698STomas Novotny { pinmux(15), 8, 7 }, 50b9f56698STomas Novotny { pinmux(16), 8, 0 }, 51b9f56698STomas Novotny { pinmux(16), 8, 1 }, 52b9f56698STomas Novotny { pinmux(16), 8, 2 }, 53b9f56698STomas Novotny { pinmux(16), 8, 3 }, 54b9f56698STomas Novotny { pinmux(16), 8, 4 }, 55b9f56698STomas Novotny { pinmux(16), 8, 5 }, 56b9f56698STomas Novotny { pinmux(16), 8, 6 }, 57b9f56698STomas Novotny { pinmux(16), 8, 7 }, 58b9f56698STomas Novotny { pinmux(17), 8, 0 }, 59b9f56698STomas Novotny { pinmux(17), 8, 1 }, 60b9f56698STomas Novotny { pinmux(17), 8, 2 }, 61b9f56698STomas Novotny { pinmux(17), 8, 3 }, 62b9f56698STomas Novotny { pinmux(17), 8, 4 }, 63b9f56698STomas Novotny { pinmux(17), 8, 5 }, 64b9f56698STomas Novotny { pinmux(17), 8, 6 }, /* GP2[0] */ 65b9f56698STomas Novotny { pinmux(17), 8, 7 }, 66b9f56698STomas Novotny { pinmux(18), 8, 0 }, 67b9f56698STomas Novotny { pinmux(18), 8, 1 }, 68b9f56698STomas Novotny { pinmux(18), 8, 2 }, 69b9f56698STomas Novotny { pinmux(18), 8, 3 }, 70b9f56698STomas Novotny { pinmux(18), 8, 4 }, 71b9f56698STomas Novotny { pinmux(18), 8, 5 }, 72b9f56698STomas Novotny { pinmux(18), 8, 6 }, 73b9f56698STomas Novotny { pinmux(18), 8, 7 }, 74b9f56698STomas Novotny { pinmux(19), 8, 0 }, 75b9f56698STomas Novotny { pinmux(9), 8, 2 }, 76b9f56698STomas Novotny { pinmux(9), 8, 3 }, 77b9f56698STomas Novotny { pinmux(9), 8, 4 }, 78b9f56698STomas Novotny { pinmux(9), 8, 5 }, 79b9f56698STomas Novotny { pinmux(9), 8, 6 }, 80b9f56698STomas Novotny { pinmux(10), 8, 1 }, /* GP3[0] */ 81b9f56698STomas Novotny { pinmux(10), 8, 2 }, 82b9f56698STomas Novotny { pinmux(10), 8, 3 }, 83b9f56698STomas Novotny { pinmux(10), 8, 4 }, 84b9f56698STomas Novotny { pinmux(10), 8, 5 }, 85b9f56698STomas Novotny { pinmux(10), 8, 6 }, 86b9f56698STomas Novotny { pinmux(10), 8, 7 }, 87b9f56698STomas Novotny { pinmux(11), 8, 0 }, 88b9f56698STomas Novotny { pinmux(11), 8, 1 }, 89b9f56698STomas Novotny { pinmux(11), 8, 2 }, 90b9f56698STomas Novotny { pinmux(11), 8, 3 }, 91b9f56698STomas Novotny { pinmux(11), 8, 4 }, 92b9f56698STomas Novotny { pinmux(9), 8, 7 }, 93b9f56698STomas Novotny { pinmux(2), 8, 6 }, 94b9f56698STomas Novotny { pinmux(11), 8, 5 }, 95b9f56698STomas Novotny { pinmux(11), 8, 6 }, 96b9f56698STomas Novotny { pinmux(12), 8, 4 }, /* GP4[0] */ 97b9f56698STomas Novotny { pinmux(12), 8, 5 }, 98b9f56698STomas Novotny { pinmux(12), 8, 6 }, 99b9f56698STomas Novotny { pinmux(12), 8, 7 }, 100b9f56698STomas Novotny { pinmux(13), 8, 0 }, 101b9f56698STomas Novotny { pinmux(13), 8, 1 }, 102b9f56698STomas Novotny { pinmux(13), 8, 2 }, 103b9f56698STomas Novotny { pinmux(13), 8, 3 }, 104b9f56698STomas Novotny { pinmux(13), 8, 4 }, 105b9f56698STomas Novotny { pinmux(13), 8, 5 }, 106b9f56698STomas Novotny { pinmux(11), 8, 7 }, 107b9f56698STomas Novotny { pinmux(12), 8, 0 }, 108b9f56698STomas Novotny { pinmux(12), 8, 1 }, 109b9f56698STomas Novotny { pinmux(12), 8, 2 }, 110b9f56698STomas Novotny { pinmux(12), 8, 3 }, 111b9f56698STomas Novotny { pinmux(9), 8, 1 }, 112b9f56698STomas Novotny { pinmux(7), 8, 3 }, /* GP5[0] */ 113b9f56698STomas Novotny { pinmux(7), 8, 4 }, 114b9f56698STomas Novotny { pinmux(7), 8, 5 }, 115b9f56698STomas Novotny { pinmux(7), 8, 6 }, 116b9f56698STomas Novotny { pinmux(7), 8, 7 }, 117b9f56698STomas Novotny { pinmux(8), 8, 0 }, 118b9f56698STomas Novotny { pinmux(8), 8, 1 }, 119b9f56698STomas Novotny { pinmux(8), 8, 2 }, 120b9f56698STomas Novotny { pinmux(8), 8, 3 }, 121b9f56698STomas Novotny { pinmux(8), 8, 4 }, 122b9f56698STomas Novotny { pinmux(8), 8, 5 }, 123b9f56698STomas Novotny { pinmux(8), 8, 6 }, 124b9f56698STomas Novotny { pinmux(8), 8, 7 }, 125b9f56698STomas Novotny { pinmux(9), 8, 0 }, 126b9f56698STomas Novotny { pinmux(7), 8, 1 }, 127b9f56698STomas Novotny { pinmux(7), 8, 2 }, 128b9f56698STomas Novotny { pinmux(5), 8, 1 }, /* GP6[0] */ 129b9f56698STomas Novotny { pinmux(5), 8, 2 }, 130b9f56698STomas Novotny { pinmux(5), 8, 3 }, 131b9f56698STomas Novotny { pinmux(5), 8, 4 }, 132b9f56698STomas Novotny { pinmux(5), 8, 5 }, 133b9f56698STomas Novotny { pinmux(5), 8, 6 }, 134b9f56698STomas Novotny { pinmux(5), 8, 7 }, 135b9f56698STomas Novotny { pinmux(6), 8, 0 }, 136b9f56698STomas Novotny { pinmux(6), 8, 1 }, 137b9f56698STomas Novotny { pinmux(6), 8, 2 }, 138b9f56698STomas Novotny { pinmux(6), 8, 3 }, 139b9f56698STomas Novotny { pinmux(6), 8, 4 }, 140b9f56698STomas Novotny { pinmux(6), 8, 5 }, 141b9f56698STomas Novotny { pinmux(6), 8, 6 }, 142b9f56698STomas Novotny { pinmux(6), 8, 7 }, 143b9f56698STomas Novotny { pinmux(7), 8, 0 }, 144b9f56698STomas Novotny { pinmux(1), 8, 0 }, /* GP7[0] */ 145b9f56698STomas Novotny { pinmux(1), 8, 1 }, 146b9f56698STomas Novotny { pinmux(1), 8, 2 }, 147b9f56698STomas Novotny { pinmux(1), 8, 3 }, 148b9f56698STomas Novotny { pinmux(1), 8, 4 }, 149b9f56698STomas Novotny { pinmux(1), 8, 5 }, 150b9f56698STomas Novotny { pinmux(1), 8, 6 }, 151b9f56698STomas Novotny { pinmux(1), 8, 7 }, 152b9f56698STomas Novotny { pinmux(2), 8, 0 }, 153b9f56698STomas Novotny { pinmux(2), 8, 1 }, 154b9f56698STomas Novotny { pinmux(2), 8, 2 }, 155b9f56698STomas Novotny { pinmux(2), 8, 3 }, 156b9f56698STomas Novotny { pinmux(2), 8, 4 }, 157b9f56698STomas Novotny { pinmux(2), 8, 5 }, 158b9f56698STomas Novotny { pinmux(0), 1, 0 }, 159b9f56698STomas Novotny { pinmux(0), 1, 1 }, 160b9f56698STomas Novotny }; 16176b40ab4STom Rini #else /* CONFIG_SOC_DA8XX && CONFIG_SOC_DA850 */ 162f517afd5SLaurence Withers static const struct pinmux_config gpio_pinmux[] = { 163f517afd5SLaurence Withers { pinmux(1), 8, 7 }, /* GP0[0] */ 164f517afd5SLaurence Withers { pinmux(1), 8, 6 }, 165f517afd5SLaurence Withers { pinmux(1), 8, 5 }, 166f517afd5SLaurence Withers { pinmux(1), 8, 4 }, 167f517afd5SLaurence Withers { pinmux(1), 8, 3 }, 168f517afd5SLaurence Withers { pinmux(1), 8, 2 }, 169f517afd5SLaurence Withers { pinmux(1), 8, 1 }, 170f517afd5SLaurence Withers { pinmux(1), 8, 0 }, 171f517afd5SLaurence Withers { pinmux(0), 8, 7 }, 172f517afd5SLaurence Withers { pinmux(0), 8, 6 }, 173f517afd5SLaurence Withers { pinmux(0), 8, 5 }, 174f517afd5SLaurence Withers { pinmux(0), 8, 4 }, 175f517afd5SLaurence Withers { pinmux(0), 8, 3 }, 176f517afd5SLaurence Withers { pinmux(0), 8, 2 }, 177f517afd5SLaurence Withers { pinmux(0), 8, 1 }, 178f517afd5SLaurence Withers { pinmux(0), 8, 0 }, 179f517afd5SLaurence Withers { pinmux(4), 8, 7 }, /* GP1[0] */ 180f517afd5SLaurence Withers { pinmux(4), 8, 6 }, 181f517afd5SLaurence Withers { pinmux(4), 8, 5 }, 182f517afd5SLaurence Withers { pinmux(4), 8, 4 }, 183f517afd5SLaurence Withers { pinmux(4), 8, 3 }, 184f517afd5SLaurence Withers { pinmux(4), 8, 2 }, 185f517afd5SLaurence Withers { pinmux(4), 4, 1 }, 186f517afd5SLaurence Withers { pinmux(4), 4, 0 }, 187f517afd5SLaurence Withers { pinmux(3), 4, 0 }, 188f517afd5SLaurence Withers { pinmux(2), 4, 6 }, 189f517afd5SLaurence Withers { pinmux(2), 4, 5 }, 190f517afd5SLaurence Withers { pinmux(2), 4, 4 }, 191f517afd5SLaurence Withers { pinmux(2), 4, 3 }, 192f517afd5SLaurence Withers { pinmux(2), 4, 2 }, 193f517afd5SLaurence Withers { pinmux(2), 4, 1 }, 194f517afd5SLaurence Withers { pinmux(2), 8, 0 }, 195f517afd5SLaurence Withers { pinmux(6), 8, 7 }, /* GP2[0] */ 196f517afd5SLaurence Withers { pinmux(6), 8, 6 }, 197f517afd5SLaurence Withers { pinmux(6), 8, 5 }, 198f517afd5SLaurence Withers { pinmux(6), 8, 4 }, 199f517afd5SLaurence Withers { pinmux(6), 8, 3 }, 200f517afd5SLaurence Withers { pinmux(6), 8, 2 }, 201f517afd5SLaurence Withers { pinmux(6), 8, 1 }, 202f517afd5SLaurence Withers { pinmux(6), 8, 0 }, 203f517afd5SLaurence Withers { pinmux(5), 8, 7 }, 204f517afd5SLaurence Withers { pinmux(5), 8, 6 }, 205f517afd5SLaurence Withers { pinmux(5), 8, 5 }, 206f517afd5SLaurence Withers { pinmux(5), 8, 4 }, 207f517afd5SLaurence Withers { pinmux(5), 8, 3 }, 208f517afd5SLaurence Withers { pinmux(5), 8, 2 }, 209f517afd5SLaurence Withers { pinmux(5), 8, 1 }, 210f517afd5SLaurence Withers { pinmux(5), 8, 0 }, 211f517afd5SLaurence Withers { pinmux(8), 8, 7 }, /* GP3[0] */ 212f517afd5SLaurence Withers { pinmux(8), 8, 6 }, 213f517afd5SLaurence Withers { pinmux(8), 8, 5 }, 214f517afd5SLaurence Withers { pinmux(8), 8, 4 }, 215f517afd5SLaurence Withers { pinmux(8), 8, 3 }, 216f517afd5SLaurence Withers { pinmux(8), 8, 2 }, 217f517afd5SLaurence Withers { pinmux(8), 8, 1 }, 218f517afd5SLaurence Withers { pinmux(8), 8, 0 }, 219f517afd5SLaurence Withers { pinmux(7), 8, 7 }, 220f517afd5SLaurence Withers { pinmux(7), 8, 6 }, 221f517afd5SLaurence Withers { pinmux(7), 8, 5 }, 222f517afd5SLaurence Withers { pinmux(7), 8, 4 }, 223f517afd5SLaurence Withers { pinmux(7), 8, 3 }, 224f517afd5SLaurence Withers { pinmux(7), 8, 2 }, 225f517afd5SLaurence Withers { pinmux(7), 8, 1 }, 226f517afd5SLaurence Withers { pinmux(7), 8, 0 }, 227f517afd5SLaurence Withers { pinmux(10), 8, 7 }, /* GP4[0] */ 228f517afd5SLaurence Withers { pinmux(10), 8, 6 }, 229f517afd5SLaurence Withers { pinmux(10), 8, 5 }, 230f517afd5SLaurence Withers { pinmux(10), 8, 4 }, 231f517afd5SLaurence Withers { pinmux(10), 8, 3 }, 232f517afd5SLaurence Withers { pinmux(10), 8, 2 }, 233f517afd5SLaurence Withers { pinmux(10), 8, 1 }, 234f517afd5SLaurence Withers { pinmux(10), 8, 0 }, 235f517afd5SLaurence Withers { pinmux(9), 8, 7 }, 236f517afd5SLaurence Withers { pinmux(9), 8, 6 }, 237f517afd5SLaurence Withers { pinmux(9), 8, 5 }, 238f517afd5SLaurence Withers { pinmux(9), 8, 4 }, 239f517afd5SLaurence Withers { pinmux(9), 8, 3 }, 240f517afd5SLaurence Withers { pinmux(9), 8, 2 }, 241f517afd5SLaurence Withers { pinmux(9), 8, 1 }, 242f517afd5SLaurence Withers { pinmux(9), 8, 0 }, 243f517afd5SLaurence Withers { pinmux(12), 8, 7 }, /* GP5[0] */ 244f517afd5SLaurence Withers { pinmux(12), 8, 6 }, 245f517afd5SLaurence Withers { pinmux(12), 8, 5 }, 246f517afd5SLaurence Withers { pinmux(12), 8, 4 }, 247f517afd5SLaurence Withers { pinmux(12), 8, 3 }, 248f517afd5SLaurence Withers { pinmux(12), 8, 2 }, 249f517afd5SLaurence Withers { pinmux(12), 8, 1 }, 250f517afd5SLaurence Withers { pinmux(12), 8, 0 }, 251f517afd5SLaurence Withers { pinmux(11), 8, 7 }, 252f517afd5SLaurence Withers { pinmux(11), 8, 6 }, 253f517afd5SLaurence Withers { pinmux(11), 8, 5 }, 254f517afd5SLaurence Withers { pinmux(11), 8, 4 }, 255f517afd5SLaurence Withers { pinmux(11), 8, 3 }, 256f517afd5SLaurence Withers { pinmux(11), 8, 2 }, 257f517afd5SLaurence Withers { pinmux(11), 8, 1 }, 258f517afd5SLaurence Withers { pinmux(11), 8, 0 }, 259f517afd5SLaurence Withers { pinmux(19), 8, 6 }, /* GP6[0] */ 260f517afd5SLaurence Withers { pinmux(19), 8, 5 }, 261f517afd5SLaurence Withers { pinmux(19), 8, 4 }, 262f517afd5SLaurence Withers { pinmux(19), 8, 3 }, 263f517afd5SLaurence Withers { pinmux(19), 8, 2 }, 264f517afd5SLaurence Withers { pinmux(16), 8, 1 }, 265f517afd5SLaurence Withers { pinmux(14), 8, 1 }, 266f517afd5SLaurence Withers { pinmux(14), 8, 0 }, 267f517afd5SLaurence Withers { pinmux(13), 8, 7 }, 268f517afd5SLaurence Withers { pinmux(13), 8, 6 }, 269f517afd5SLaurence Withers { pinmux(13), 8, 5 }, 270f517afd5SLaurence Withers { pinmux(13), 8, 4 }, 271f517afd5SLaurence Withers { pinmux(13), 8, 3 }, 272f517afd5SLaurence Withers { pinmux(13), 8, 2 }, 273f517afd5SLaurence Withers { pinmux(13), 8, 1 }, 274f517afd5SLaurence Withers { pinmux(13), 8, 0 }, 275f517afd5SLaurence Withers { pinmux(18), 8, 1 }, /* GP7[0] */ 276f517afd5SLaurence Withers { pinmux(18), 8, 0 }, 277f517afd5SLaurence Withers { pinmux(17), 8, 7 }, 278f517afd5SLaurence Withers { pinmux(17), 8, 6 }, 279f517afd5SLaurence Withers { pinmux(17), 8, 5 }, 280f517afd5SLaurence Withers { pinmux(17), 8, 4 }, 281f517afd5SLaurence Withers { pinmux(17), 8, 3 }, 282f517afd5SLaurence Withers { pinmux(17), 8, 2 }, 283f517afd5SLaurence Withers { pinmux(17), 8, 1 }, 284f517afd5SLaurence Withers { pinmux(17), 8, 0 }, 285f517afd5SLaurence Withers { pinmux(16), 8, 7 }, 286f517afd5SLaurence Withers { pinmux(16), 8, 6 }, 287f517afd5SLaurence Withers { pinmux(16), 8, 5 }, 288f517afd5SLaurence Withers { pinmux(16), 8, 4 }, 289f517afd5SLaurence Withers { pinmux(16), 8, 3 }, 290f517afd5SLaurence Withers { pinmux(16), 8, 2 }, 291f517afd5SLaurence Withers { pinmux(19), 8, 0 }, /* GP8[0] */ 292f517afd5SLaurence Withers { pinmux(3), 4, 7 }, 293f517afd5SLaurence Withers { pinmux(3), 4, 6 }, 294f517afd5SLaurence Withers { pinmux(3), 4, 5 }, 295f517afd5SLaurence Withers { pinmux(3), 4, 4 }, 296f517afd5SLaurence Withers { pinmux(3), 4, 3 }, 297f517afd5SLaurence Withers { pinmux(3), 4, 2 }, 298f517afd5SLaurence Withers { pinmux(2), 4, 7 }, 299f517afd5SLaurence Withers { pinmux(19), 8, 1 }, 300f517afd5SLaurence Withers { pinmux(19), 8, 0 }, 301f517afd5SLaurence Withers { pinmux(18), 8, 7 }, 302f517afd5SLaurence Withers { pinmux(18), 8, 6 }, 303f517afd5SLaurence Withers { pinmux(18), 8, 5 }, 304f517afd5SLaurence Withers { pinmux(18), 8, 4 }, 305f517afd5SLaurence Withers { pinmux(18), 8, 3 }, 306f517afd5SLaurence Withers { pinmux(18), 8, 2 }, 307f517afd5SLaurence Withers }; 30876b40ab4STom Rini #endif /* CONFIG_SOC_DA8XX && !CONFIG_SOC_DA850 */ 30976b40ab4STom Rini #else /* !CONFIG_SOC_DA8XX */ 31003414ac4SHolger Hans Peter Freyther #define davinci_configure_pin_mux(a, b) 31176b40ab4STom Rini #endif /* CONFIG_SOC_DA8XX */ 312f517afd5SLaurence Withers 3138e51c0f2SAdam Ford int gpio_request(unsigned int gpio, const char *label) 314f517afd5SLaurence Withers { 315365d6070SJoe Hershberger if (gpio >= MAX_NUM_GPIOS) 316f517afd5SLaurence Withers return -1; 317f517afd5SLaurence Withers 318365d6070SJoe Hershberger if (gpio_registry[gpio].is_registered) 319f517afd5SLaurence Withers return -1; 320f517afd5SLaurence Withers 321365d6070SJoe Hershberger gpio_registry[gpio].is_registered = 1; 322365d6070SJoe Hershberger strncpy(gpio_registry[gpio].name, label, GPIO_NAME_SIZE); 323365d6070SJoe Hershberger gpio_registry[gpio].name[GPIO_NAME_SIZE - 1] = 0; 324f517afd5SLaurence Withers 325365d6070SJoe Hershberger davinci_configure_pin_mux(&gpio_pinmux[gpio], 1); 326f517afd5SLaurence Withers 327f517afd5SLaurence Withers return 0; 328f517afd5SLaurence Withers } 329f517afd5SLaurence Withers 3308e51c0f2SAdam Ford int gpio_free(unsigned int gpio) 331f517afd5SLaurence Withers { 332365d6070SJoe Hershberger if (gpio >= MAX_NUM_GPIOS) 333365d6070SJoe Hershberger return -1; 334365d6070SJoe Hershberger 335365d6070SJoe Hershberger if (!gpio_registry[gpio].is_registered) 336365d6070SJoe Hershberger return -1; 337365d6070SJoe Hershberger 338365d6070SJoe Hershberger gpio_registry[gpio].is_registered = 0; 339365d6070SJoe Hershberger gpio_registry[gpio].name[0] = '\0'; 340365d6070SJoe Hershberger /* Do not configure as input or change pin mux here */ 341365d6070SJoe Hershberger return 0; 342f517afd5SLaurence Withers } 3438e51c0f2SAdam Ford #endif 344f517afd5SLaurence Withers 3458e51c0f2SAdam Ford static int _gpio_direction_output(struct davinci_gpio *bank, unsigned int gpio, int value) 346f517afd5SLaurence Withers { 347365d6070SJoe Hershberger clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); 348365d6070SJoe Hershberger gpio_set_value(gpio, value); 349f517afd5SLaurence Withers return 0; 350f517afd5SLaurence Withers } 351f517afd5SLaurence Withers 3528e51c0f2SAdam Ford static int _gpio_direction_input(struct davinci_gpio *bank, unsigned int gpio) 353f517afd5SLaurence Withers { 3548e51c0f2SAdam Ford setbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); 3558e51c0f2SAdam Ford return 0; 3568e51c0f2SAdam Ford } 357f517afd5SLaurence Withers 3588e51c0f2SAdam Ford static int _gpio_get_value(struct davinci_gpio *bank, unsigned int gpio) 3598e51c0f2SAdam Ford { 3608e51c0f2SAdam Ford unsigned int ip; 361365d6070SJoe Hershberger ip = in_le32(&bank->in_data) & (1U << GPIO_BIT(gpio)); 362f517afd5SLaurence Withers return ip ? 1 : 0; 363f517afd5SLaurence Withers } 364f517afd5SLaurence Withers 3658e51c0f2SAdam Ford static int _gpio_set_value(struct davinci_gpio *bank, unsigned int gpio, int value) 366f517afd5SLaurence Withers { 367f517afd5SLaurence Withers if (value) 368365d6070SJoe Hershberger bank->set_data = 1U << GPIO_BIT(gpio); 369f517afd5SLaurence Withers else 370365d6070SJoe Hershberger bank->clr_data = 1U << GPIO_BIT(gpio); 371365d6070SJoe Hershberger 372365d6070SJoe Hershberger return 0; 373f517afd5SLaurence Withers } 374f517afd5SLaurence Withers 3758e51c0f2SAdam Ford static int _gpio_get_dir(struct davinci_gpio *bank, unsigned int gpio) 3768e51c0f2SAdam Ford { 3778e51c0f2SAdam Ford return in_le32(&bank->dir) & (1U << GPIO_BIT(gpio)); 3788e51c0f2SAdam Ford } 3798e51c0f2SAdam Ford 3808e51c0f2SAdam Ford #ifndef CONFIG_DM_GPIO 3818e51c0f2SAdam Ford 382f517afd5SLaurence Withers void gpio_info(void) 383f517afd5SLaurence Withers { 3848e51c0f2SAdam Ford unsigned int gpio, dir, val; 385f517afd5SLaurence Withers struct davinci_gpio *bank; 386f517afd5SLaurence Withers 387365d6070SJoe Hershberger for (gpio = 0; gpio < MAX_NUM_GPIOS; ++gpio) { 388365d6070SJoe Hershberger bank = GPIO_BANK(gpio); 3898e51c0f2SAdam Ford dir = _gpio_get_dir(bank, gpio); 390365d6070SJoe Hershberger val = gpio_get_value(gpio); 391f517afd5SLaurence Withers 392f517afd5SLaurence Withers printf("% 4d: %s: %d [%c] %s\n", 393365d6070SJoe Hershberger gpio, dir ? " in" : "out", val, 394365d6070SJoe Hershberger gpio_registry[gpio].is_registered ? 'x' : ' ', 395365d6070SJoe Hershberger gpio_registry[gpio].name); 396f517afd5SLaurence Withers } 397f517afd5SLaurence Withers } 3988e51c0f2SAdam Ford 3998e51c0f2SAdam Ford int gpio_direction_input(unsigned int gpio) 4008e51c0f2SAdam Ford { 4018e51c0f2SAdam Ford struct davinci_gpio *bank; 4028e51c0f2SAdam Ford 4038e51c0f2SAdam Ford bank = GPIO_BANK(gpio); 4048e51c0f2SAdam Ford return _gpio_direction_input(bank, gpio); 4058e51c0f2SAdam Ford } 4068e51c0f2SAdam Ford 4078e51c0f2SAdam Ford int gpio_direction_output(unsigned int gpio, int value) 4088e51c0f2SAdam Ford { 4098e51c0f2SAdam Ford struct davinci_gpio *bank; 4108e51c0f2SAdam Ford 4118e51c0f2SAdam Ford bank = GPIO_BANK(gpio); 4128e51c0f2SAdam Ford return _gpio_direction_output(bank, gpio, value); 4138e51c0f2SAdam Ford } 4148e51c0f2SAdam Ford 4158e51c0f2SAdam Ford int gpio_get_value(unsigned int gpio) 4168e51c0f2SAdam Ford { 4178e51c0f2SAdam Ford struct davinci_gpio *bank; 4188e51c0f2SAdam Ford 4198e51c0f2SAdam Ford bank = GPIO_BANK(gpio); 4208e51c0f2SAdam Ford return _gpio_get_value(bank, gpio); 4218e51c0f2SAdam Ford } 4228e51c0f2SAdam Ford 4238e51c0f2SAdam Ford int gpio_set_value(unsigned int gpio, int value) 4248e51c0f2SAdam Ford { 4258e51c0f2SAdam Ford struct davinci_gpio *bank; 4268e51c0f2SAdam Ford 4278e51c0f2SAdam Ford bank = GPIO_BANK(gpio); 4288e51c0f2SAdam Ford return _gpio_set_value(bank, gpio, value); 4298e51c0f2SAdam Ford } 4308e51c0f2SAdam Ford 4318e51c0f2SAdam Ford #else /* CONFIG_DM_GPIO */ 4328e51c0f2SAdam Ford 4338e51c0f2SAdam Ford static struct davinci_gpio *davinci_get_gpio_bank(struct udevice *dev, unsigned int offset) 4348e51c0f2SAdam Ford { 4358e51c0f2SAdam Ford struct davinci_gpio_bank *bank = dev_get_priv(dev); 4361eddf549SAdam Ford unsigned int addr; 4378e51c0f2SAdam Ford 4381eddf549SAdam Ford /* 4391eddf549SAdam Ford * The device tree is not broken into banks but the infrastructure is 4408e51c0f2SAdam Ford * expecting it this way, so we'll first include the 0x10 offset, then 4418e51c0f2SAdam Ford * calculate the bank manually based on the offset. 4421eddf549SAdam Ford * Casting 'addr' as Unsigned long is needed to make the math work. 4438e51c0f2SAdam Ford */ 4441eddf549SAdam Ford addr = ((unsigned long)(struct davinci_gpio *)bank->base) + 4451eddf549SAdam Ford 0x10 + (0x28 * (offset >> 5)); 4461eddf549SAdam Ford return (struct davinci_gpio *)addr; 4478e51c0f2SAdam Ford } 4488e51c0f2SAdam Ford 4498e51c0f2SAdam Ford static int davinci_gpio_direction_input(struct udevice *dev, unsigned int offset) 4508e51c0f2SAdam Ford { 4518e51c0f2SAdam Ford struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); 4528e51c0f2SAdam Ford 4531eddf549SAdam Ford /* 4541eddf549SAdam Ford * Fetch the address based on GPIO, but only pass the masked low 32-bits 4551eddf549SAdam Ford */ 4561eddf549SAdam Ford _gpio_direction_input(base, (offset & 0x1f)); 4578e51c0f2SAdam Ford return 0; 4588e51c0f2SAdam Ford } 4598e51c0f2SAdam Ford 4608e51c0f2SAdam Ford static int davinci_gpio_direction_output(struct udevice *dev, unsigned int offset, 4618e51c0f2SAdam Ford int value) 4628e51c0f2SAdam Ford { 4638e51c0f2SAdam Ford struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); 4648e51c0f2SAdam Ford 4651eddf549SAdam Ford _gpio_direction_output(base, (offset & 0x1f), value); 4668e51c0f2SAdam Ford return 0; 4678e51c0f2SAdam Ford } 4688e51c0f2SAdam Ford 4698e51c0f2SAdam Ford static int davinci_gpio_get_value(struct udevice *dev, unsigned int offset) 4708e51c0f2SAdam Ford { 4718e51c0f2SAdam Ford struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); 4728e51c0f2SAdam Ford 4731eddf549SAdam Ford return _gpio_get_value(base, (offset & 0x1f)); 4748e51c0f2SAdam Ford } 4758e51c0f2SAdam Ford 4768e51c0f2SAdam Ford static int davinci_gpio_set_value(struct udevice *dev, unsigned int offset, 4778e51c0f2SAdam Ford int value) 4788e51c0f2SAdam Ford { 4798e51c0f2SAdam Ford struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); 4808e51c0f2SAdam Ford 4811eddf549SAdam Ford _gpio_set_value(base, (offset & 0x1f), value); 4828e51c0f2SAdam Ford 4838e51c0f2SAdam Ford return 0; 4848e51c0f2SAdam Ford } 4858e51c0f2SAdam Ford 4868e51c0f2SAdam Ford static int davinci_gpio_get_function(struct udevice *dev, unsigned int offset) 4878e51c0f2SAdam Ford { 4888e51c0f2SAdam Ford unsigned int dir; 4898e51c0f2SAdam Ford struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); 4908e51c0f2SAdam Ford 4918e51c0f2SAdam Ford dir = _gpio_get_dir(base, offset); 4928e51c0f2SAdam Ford 4938e51c0f2SAdam Ford if (dir) 4948e51c0f2SAdam Ford return GPIOF_INPUT; 4958e51c0f2SAdam Ford 4968e51c0f2SAdam Ford return GPIOF_OUTPUT; 4978e51c0f2SAdam Ford } 4988e51c0f2SAdam Ford 4999440b3d3SAdam Ford static int davinci_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, 5009440b3d3SAdam Ford struct ofnode_phandle_args *args) 5019440b3d3SAdam Ford { 5029440b3d3SAdam Ford desc->offset = args->args[0]; 5039440b3d3SAdam Ford 5049440b3d3SAdam Ford if (args->args[1] & GPIO_ACTIVE_LOW) 5059440b3d3SAdam Ford desc->flags = GPIOD_ACTIVE_LOW; 5069440b3d3SAdam Ford else 5079440b3d3SAdam Ford desc->flags = 0; 5089440b3d3SAdam Ford return 0; 5099440b3d3SAdam Ford } 5109440b3d3SAdam Ford 5118e51c0f2SAdam Ford static const struct dm_gpio_ops gpio_davinci_ops = { 5128e51c0f2SAdam Ford .direction_input = davinci_gpio_direction_input, 5138e51c0f2SAdam Ford .direction_output = davinci_gpio_direction_output, 5148e51c0f2SAdam Ford .get_value = davinci_gpio_get_value, 5158e51c0f2SAdam Ford .set_value = davinci_gpio_set_value, 5168e51c0f2SAdam Ford .get_function = davinci_gpio_get_function, 5179440b3d3SAdam Ford .xlate = davinci_gpio_xlate, 5188e51c0f2SAdam Ford }; 5198e51c0f2SAdam Ford 5208e51c0f2SAdam Ford static int davinci_gpio_probe(struct udevice *dev) 5218e51c0f2SAdam Ford { 5228e51c0f2SAdam Ford struct davinci_gpio_bank *bank = dev_get_priv(dev); 5238e51c0f2SAdam Ford struct davinci_gpio_platdata *plat = dev_get_platdata(dev); 5248e51c0f2SAdam Ford struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 5258e51c0f2SAdam Ford const void *fdt = gd->fdt_blob; 5268e51c0f2SAdam Ford int node = dev_of_offset(dev); 5278e51c0f2SAdam Ford 5288e51c0f2SAdam Ford uc_priv->bank_name = plat->port_name; 5298e51c0f2SAdam Ford uc_priv->gpio_count = fdtdec_get_int(fdt, node, "ti,ngpio", -1); 5308e51c0f2SAdam Ford bank->base = (struct davinci_gpio *)plat->base; 5318e51c0f2SAdam Ford return 0; 5328e51c0f2SAdam Ford } 5338e51c0f2SAdam Ford 5348e51c0f2SAdam Ford static const struct udevice_id davinci_gpio_ids[] = { 5358e51c0f2SAdam Ford { .compatible = "ti,dm6441-gpio" }, 536401d74cbSKeerthy { .compatible = "ti,k2g-gpio" }, 5378e51c0f2SAdam Ford { } 5388e51c0f2SAdam Ford }; 5398e51c0f2SAdam Ford 5408e51c0f2SAdam Ford static int davinci_gpio_ofdata_to_platdata(struct udevice *dev) 5418e51c0f2SAdam Ford { 5428e51c0f2SAdam Ford struct davinci_gpio_platdata *plat = dev_get_platdata(dev); 5438e51c0f2SAdam Ford fdt_addr_t addr; 5448e51c0f2SAdam Ford 5458e51c0f2SAdam Ford addr = devfdt_get_addr(dev); 5468e51c0f2SAdam Ford if (addr == FDT_ADDR_T_NONE) 5478e51c0f2SAdam Ford return -EINVAL; 5488e51c0f2SAdam Ford 5498e51c0f2SAdam Ford plat->base = addr; 5508e51c0f2SAdam Ford return 0; 5518e51c0f2SAdam Ford } 5528e51c0f2SAdam Ford 5538e51c0f2SAdam Ford U_BOOT_DRIVER(gpio_davinci) = { 5548e51c0f2SAdam Ford .name = "gpio_davinci", 5558e51c0f2SAdam Ford .id = UCLASS_GPIO, 5568e51c0f2SAdam Ford .ops = &gpio_davinci_ops, 5578e51c0f2SAdam Ford .ofdata_to_platdata = of_match_ptr(davinci_gpio_ofdata_to_platdata), 5588e51c0f2SAdam Ford .of_match = davinci_gpio_ids, 5598e51c0f2SAdam Ford .bind = dm_scan_fdt_dev, 5608e51c0f2SAdam Ford .platdata_auto_alloc_size = sizeof(struct davinci_gpio_platdata), 5618e51c0f2SAdam Ford .probe = davinci_gpio_probe, 5628e51c0f2SAdam Ford .priv_auto_alloc_size = sizeof(struct davinci_gpio_bank), 5638e51c0f2SAdam Ford }; 5648e51c0f2SAdam Ford 5658e51c0f2SAdam Ford #endif 566