/* * Copyright (c) 2009 Wind River Systems, Inc. * Tom Rix * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * This work is derived from the linux 2.6.27 kernel source * To fetch, use the kernel repository * git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git * Use the v2.6.27 tag. * * Below is the original's header including its copyright * * linux/arch/arm/plat-omap/gpio.c * * Support functions for OMAP GPIO * * Copyright (C) 2003-2005 Nokia Corporation * Written by Juha Yrjölä * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include static struct gpio_bank gpio_bank_34xx[6] = { { (void *)OMAP34XX_GPIO1_BASE, METHOD_GPIO_24XX }, { (void *)OMAP34XX_GPIO2_BASE, METHOD_GPIO_24XX }, { (void *)OMAP34XX_GPIO3_BASE, METHOD_GPIO_24XX }, { (void *)OMAP34XX_GPIO4_BASE, METHOD_GPIO_24XX }, { (void *)OMAP34XX_GPIO5_BASE, METHOD_GPIO_24XX }, { (void *)OMAP34XX_GPIO6_BASE, METHOD_GPIO_24XX }, }; static struct gpio_bank *gpio_bank = &gpio_bank_34xx[0]; static inline struct gpio_bank *get_gpio_bank(int gpio) { return &gpio_bank[gpio >> 5]; } static inline int get_gpio_index(int gpio) { return gpio & 0x1f; } static inline int gpio_valid(int gpio) { if (gpio < 0) return -1; if (gpio < 192) return 0; return -1; } static int check_gpio(int gpio) { if (gpio_valid(gpio) < 0) { printf("ERROR : check_gpio: invalid GPIO %d\n", gpio); return -1; } return 0; } void gpio_set_value(unsigned gpio, int value) { struct gpio_bank *bank; void *reg; u32 l = 0; if (check_gpio(gpio) < 0) return; bank = get_gpio_bank(gpio); reg = bank->base; switch (bank->method) { case METHOD_GPIO_24XX: if (value) reg += OMAP24XX_GPIO_SETDATAOUT; else reg += OMAP24XX_GPIO_CLEARDATAOUT; l = 1 << get_gpio_index(gpio); break; default: printf("omap3-gpio unknown bank method %s %d\n", __FILE__, __LINE__); return; } __raw_writel(l, reg); } int gpio_direction_input(unsigned gpio) { struct gpio_bank *bank; void *reg; u32 val; if (check_gpio(gpio) < 0) return -EINVAL; bank = get_gpio_bank(gpio); reg = bank->base; switch (bank->method) { case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_OE; break; default: return -EINVAL; } val = __raw_readl(reg); val |= 1 << get_gpio_index(gpio); __raw_writel(val, reg); return 0; } int gpio_direction_output(unsigned gpio, int value) { struct gpio_bank *bank; void *reg; u32 val; if (check_gpio(gpio) < 0) return -EINVAL; bank = get_gpio_bank(gpio); reg = bank->base; gpio_set_value(gpio, value); switch (bank->method) { case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_OE; break; default: return -EINVAL; } val = __raw_readl(reg); val &= ~(1 << get_gpio_index(gpio)); __raw_writel(val, reg); return 0; } int gpio_get_value(unsigned gpio) { struct gpio_bank *bank; void *reg; if (check_gpio(gpio) < 0) return -EINVAL; bank = get_gpio_bank(gpio); reg = bank->base; switch (bank->method) { case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_DATAIN; break; default: return -EINVAL; } return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; } static void _reset_gpio(int gpio) { gpio_direction_input(gpio); } int omap_request_gpio(int gpio) { if (check_gpio(gpio) < 0) return -EINVAL; return 0; } void omap_free_gpio(int gpio) { struct gpio_bank *bank; if (check_gpio(gpio) < 0) return; bank = get_gpio_bank(gpio); _reset_gpio(gpio); }