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