1308252adSMarek Vasut /* 2308252adSMarek Vasut * Copyright (c) 2009 Wind River Systems, Inc. 3308252adSMarek Vasut * Tom Rix <Tom.Rix@windriver.com> 4308252adSMarek Vasut * 5*bcd4d4ebSWolfgang Denk * SPDX-License-Identifier: GPL-2.0 6308252adSMarek Vasut * 7308252adSMarek Vasut * This work is derived from the linux 2.6.27 kernel source 8308252adSMarek Vasut * To fetch, use the kernel repository 9308252adSMarek Vasut * git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git 10308252adSMarek Vasut * Use the v2.6.27 tag. 11308252adSMarek Vasut * 12308252adSMarek Vasut * Below is the original's header including its copyright 13308252adSMarek Vasut * 14308252adSMarek Vasut * linux/arch/arm/plat-omap/gpio.c 15308252adSMarek Vasut * 16308252adSMarek Vasut * Support functions for OMAP GPIO 17308252adSMarek Vasut * 18308252adSMarek Vasut * Copyright (C) 2003-2005 Nokia Corporation 19308252adSMarek Vasut * Written by Juha Yrjölä <juha.yrjola@nokia.com> 20308252adSMarek Vasut */ 21308252adSMarek Vasut #include <common.h> 22308252adSMarek Vasut #include <asm/gpio.h> 23308252adSMarek Vasut #include <asm/io.h> 24308252adSMarek Vasut #include <asm/errno.h> 25308252adSMarek Vasut 26308252adSMarek Vasut #define OMAP_GPIO_DIR_OUT 0 27308252adSMarek Vasut #define OMAP_GPIO_DIR_IN 1 28308252adSMarek Vasut 29308252adSMarek Vasut static inline const struct gpio_bank *get_gpio_bank(int gpio) 30308252adSMarek Vasut { 31308252adSMarek Vasut return &omap_gpio_bank[gpio >> 5]; 32308252adSMarek Vasut } 33308252adSMarek Vasut 34308252adSMarek Vasut static inline int get_gpio_index(int gpio) 35308252adSMarek Vasut { 36308252adSMarek Vasut return gpio & 0x1f; 37308252adSMarek Vasut } 38308252adSMarek Vasut 39dcee1ab3SNikita Kiryanov int gpio_is_valid(int gpio) 40308252adSMarek Vasut { 4187bd05d7SAxel Lin return (gpio >= 0) && (gpio < OMAP_MAX_GPIO); 42308252adSMarek Vasut } 43308252adSMarek Vasut 44308252adSMarek Vasut static int check_gpio(int gpio) 45308252adSMarek Vasut { 46dcee1ab3SNikita Kiryanov if (!gpio_is_valid(gpio)) { 47308252adSMarek Vasut printf("ERROR : check_gpio: invalid GPIO %d\n", gpio); 48308252adSMarek Vasut return -1; 49308252adSMarek Vasut } 50308252adSMarek Vasut return 0; 51308252adSMarek Vasut } 52308252adSMarek Vasut 53308252adSMarek Vasut static void _set_gpio_direction(const struct gpio_bank *bank, int gpio, 54308252adSMarek Vasut int is_input) 55308252adSMarek Vasut { 56308252adSMarek Vasut void *reg = bank->base; 57308252adSMarek Vasut u32 l; 58308252adSMarek Vasut 59308252adSMarek Vasut switch (bank->method) { 60308252adSMarek Vasut case METHOD_GPIO_24XX: 61308252adSMarek Vasut reg += OMAP_GPIO_OE; 62308252adSMarek Vasut break; 63308252adSMarek Vasut default: 64308252adSMarek Vasut return; 65308252adSMarek Vasut } 66308252adSMarek Vasut l = __raw_readl(reg); 67308252adSMarek Vasut if (is_input) 68308252adSMarek Vasut l |= 1 << gpio; 69308252adSMarek Vasut else 70308252adSMarek Vasut l &= ~(1 << gpio); 71308252adSMarek Vasut __raw_writel(l, reg); 72308252adSMarek Vasut } 73308252adSMarek Vasut 74308252adSMarek Vasut /** 75308252adSMarek Vasut * Get the direction of the GPIO by reading the GPIO_OE register 76308252adSMarek Vasut * corresponding to the specified bank. 77308252adSMarek Vasut */ 78308252adSMarek Vasut static int _get_gpio_direction(const struct gpio_bank *bank, int gpio) 79308252adSMarek Vasut { 80308252adSMarek Vasut void *reg = bank->base; 81308252adSMarek Vasut u32 v; 82308252adSMarek Vasut 83308252adSMarek Vasut switch (bank->method) { 84308252adSMarek Vasut case METHOD_GPIO_24XX: 85308252adSMarek Vasut reg += OMAP_GPIO_OE; 86308252adSMarek Vasut break; 87308252adSMarek Vasut default: 88308252adSMarek Vasut return -1; 89308252adSMarek Vasut } 90308252adSMarek Vasut 91308252adSMarek Vasut v = __raw_readl(reg); 92308252adSMarek Vasut 93308252adSMarek Vasut if (v & (1 << gpio)) 94308252adSMarek Vasut return OMAP_GPIO_DIR_IN; 95308252adSMarek Vasut else 96308252adSMarek Vasut return OMAP_GPIO_DIR_OUT; 97308252adSMarek Vasut } 98308252adSMarek Vasut 99308252adSMarek Vasut static void _set_gpio_dataout(const struct gpio_bank *bank, int gpio, 100308252adSMarek Vasut int enable) 101308252adSMarek Vasut { 102308252adSMarek Vasut void *reg = bank->base; 103308252adSMarek Vasut u32 l = 0; 104308252adSMarek Vasut 105308252adSMarek Vasut switch (bank->method) { 106308252adSMarek Vasut case METHOD_GPIO_24XX: 107308252adSMarek Vasut if (enable) 108308252adSMarek Vasut reg += OMAP_GPIO_SETDATAOUT; 109308252adSMarek Vasut else 110308252adSMarek Vasut reg += OMAP_GPIO_CLEARDATAOUT; 111308252adSMarek Vasut l = 1 << gpio; 112308252adSMarek Vasut break; 113308252adSMarek Vasut default: 114308252adSMarek Vasut printf("omap3-gpio unknown bank method %s %d\n", 115308252adSMarek Vasut __FILE__, __LINE__); 116308252adSMarek Vasut return; 117308252adSMarek Vasut } 118308252adSMarek Vasut __raw_writel(l, reg); 119308252adSMarek Vasut } 120308252adSMarek Vasut 121308252adSMarek Vasut /** 122308252adSMarek Vasut * Set value of the specified gpio 123308252adSMarek Vasut */ 124308252adSMarek Vasut int gpio_set_value(unsigned gpio, int value) 125308252adSMarek Vasut { 126308252adSMarek Vasut const struct gpio_bank *bank; 127308252adSMarek Vasut 128308252adSMarek Vasut if (check_gpio(gpio) < 0) 129308252adSMarek Vasut return -1; 130308252adSMarek Vasut bank = get_gpio_bank(gpio); 131308252adSMarek Vasut _set_gpio_dataout(bank, get_gpio_index(gpio), value); 132308252adSMarek Vasut 133308252adSMarek Vasut return 0; 134308252adSMarek Vasut } 135308252adSMarek Vasut 136308252adSMarek Vasut /** 137308252adSMarek Vasut * Get value of the specified gpio 138308252adSMarek Vasut */ 139308252adSMarek Vasut int gpio_get_value(unsigned gpio) 140308252adSMarek Vasut { 141308252adSMarek Vasut const struct gpio_bank *bank; 142308252adSMarek Vasut void *reg; 143308252adSMarek Vasut int input; 144308252adSMarek Vasut 145308252adSMarek Vasut if (check_gpio(gpio) < 0) 146308252adSMarek Vasut return -1; 147308252adSMarek Vasut bank = get_gpio_bank(gpio); 148308252adSMarek Vasut reg = bank->base; 149308252adSMarek Vasut switch (bank->method) { 150308252adSMarek Vasut case METHOD_GPIO_24XX: 151308252adSMarek Vasut input = _get_gpio_direction(bank, get_gpio_index(gpio)); 152308252adSMarek Vasut switch (input) { 153308252adSMarek Vasut case OMAP_GPIO_DIR_IN: 154308252adSMarek Vasut reg += OMAP_GPIO_DATAIN; 155308252adSMarek Vasut break; 156308252adSMarek Vasut case OMAP_GPIO_DIR_OUT: 157308252adSMarek Vasut reg += OMAP_GPIO_DATAOUT; 158308252adSMarek Vasut break; 159308252adSMarek Vasut default: 160308252adSMarek Vasut return -1; 161308252adSMarek Vasut } 162308252adSMarek Vasut break; 163308252adSMarek Vasut default: 164308252adSMarek Vasut return -1; 165308252adSMarek Vasut } 166308252adSMarek Vasut return (__raw_readl(reg) 167308252adSMarek Vasut & (1 << get_gpio_index(gpio))) != 0; 168308252adSMarek Vasut } 169308252adSMarek Vasut 170308252adSMarek Vasut /** 171308252adSMarek Vasut * Set gpio direction as input 172308252adSMarek Vasut */ 173308252adSMarek Vasut int gpio_direction_input(unsigned gpio) 174308252adSMarek Vasut { 175308252adSMarek Vasut const struct gpio_bank *bank; 176308252adSMarek Vasut 177308252adSMarek Vasut if (check_gpio(gpio) < 0) 178308252adSMarek Vasut return -1; 179308252adSMarek Vasut 180308252adSMarek Vasut bank = get_gpio_bank(gpio); 181308252adSMarek Vasut _set_gpio_direction(bank, get_gpio_index(gpio), 1); 182308252adSMarek Vasut 183308252adSMarek Vasut return 0; 184308252adSMarek Vasut } 185308252adSMarek Vasut 186308252adSMarek Vasut /** 187308252adSMarek Vasut * Set gpio direction as output 188308252adSMarek Vasut */ 189308252adSMarek Vasut int gpio_direction_output(unsigned gpio, int value) 190308252adSMarek Vasut { 191308252adSMarek Vasut const struct gpio_bank *bank; 192308252adSMarek Vasut 193308252adSMarek Vasut if (check_gpio(gpio) < 0) 194308252adSMarek Vasut return -1; 195308252adSMarek Vasut 196308252adSMarek Vasut bank = get_gpio_bank(gpio); 197308252adSMarek Vasut _set_gpio_dataout(bank, get_gpio_index(gpio), value); 198308252adSMarek Vasut _set_gpio_direction(bank, get_gpio_index(gpio), 0); 199308252adSMarek Vasut 200308252adSMarek Vasut return 0; 201308252adSMarek Vasut } 202308252adSMarek Vasut 203308252adSMarek Vasut /** 204308252adSMarek Vasut * Request a gpio before using it. 205308252adSMarek Vasut * 206308252adSMarek Vasut * NOTE: Argument 'label' is unused. 207308252adSMarek Vasut */ 208308252adSMarek Vasut int gpio_request(unsigned gpio, const char *label) 209308252adSMarek Vasut { 210308252adSMarek Vasut if (check_gpio(gpio) < 0) 211308252adSMarek Vasut return -1; 212308252adSMarek Vasut 213308252adSMarek Vasut return 0; 214308252adSMarek Vasut } 215308252adSMarek Vasut 216308252adSMarek Vasut /** 217308252adSMarek Vasut * Reset and free the gpio after using it. 218308252adSMarek Vasut */ 219308252adSMarek Vasut int gpio_free(unsigned gpio) 220308252adSMarek Vasut { 221308252adSMarek Vasut return 0; 222308252adSMarek Vasut } 223