2010-08-04 09:59:08 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2009 Wind River Systems, Inc.
|
|
|
|
* Tom Rix <Tom.Rix@windriver.com>
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 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ä <juha.yrjola@nokia.com>
|
|
|
|
*
|
|
|
|
* 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 <common.h>
|
2011-09-22 17:02:57 +00:00
|
|
|
#include <io.h>
|
2010-08-04 09:59:08 +00:00
|
|
|
#include <errno.h>
|
2012-09-24 08:59:36 +00:00
|
|
|
#include <gpio.h>
|
|
|
|
#include <init.h>
|
2011-03-17 14:52:46 +00:00
|
|
|
|
|
|
|
#define OMAP_GPIO_OE 0x0034
|
|
|
|
#define OMAP_GPIO_DATAIN 0x0038
|
|
|
|
#define OMAP_GPIO_DATAOUT 0x003c
|
|
|
|
#define OMAP_GPIO_CLEARDATAOUT 0x0090
|
|
|
|
#define OMAP_GPIO_SETDATAOUT 0x0094
|
|
|
|
|
2012-09-24 08:59:36 +00:00
|
|
|
struct omap_gpio_chip {
|
|
|
|
void __iomem *base;
|
|
|
|
struct gpio_chip chip;
|
2011-03-18 07:26:13 +00:00
|
|
|
};
|
2010-08-04 09:59:08 +00:00
|
|
|
|
2012-09-24 08:59:36 +00:00
|
|
|
static inline int omap_get_gpio_index(int gpio)
|
2010-08-04 09:59:08 +00:00
|
|
|
{
|
|
|
|
return gpio & 0x1f;
|
|
|
|
}
|
|
|
|
|
2012-09-24 08:59:36 +00:00
|
|
|
static void omap_gpio_set_value(struct gpio_chip *chip,
|
|
|
|
unsigned gpio, int value)
|
2010-08-04 09:59:08 +00:00
|
|
|
{
|
2012-09-24 08:59:36 +00:00
|
|
|
struct omap_gpio_chip *omapgpio =
|
|
|
|
container_of(chip, struct omap_gpio_chip, chip);
|
|
|
|
void __iomem *base = omapgpio->base;
|
2010-08-04 09:59:08 +00:00
|
|
|
u32 l = 0;
|
|
|
|
|
2011-03-17 14:52:46 +00:00
|
|
|
if (value)
|
2012-09-24 08:59:36 +00:00
|
|
|
base += OMAP_GPIO_SETDATAOUT;
|
2011-03-17 14:52:46 +00:00
|
|
|
else
|
2012-09-24 08:59:36 +00:00
|
|
|
base += OMAP_GPIO_CLEARDATAOUT;
|
|
|
|
|
|
|
|
l = 1 << omap_get_gpio_index(gpio);
|
2011-03-17 14:52:46 +00:00
|
|
|
|
2012-09-24 08:59:36 +00:00
|
|
|
writel(l, base);
|
2010-08-04 09:59:08 +00:00
|
|
|
}
|
|
|
|
|
2012-09-24 08:59:36 +00:00
|
|
|
static int omap_gpio_direction_input(struct gpio_chip *chip,
|
|
|
|
unsigned gpio)
|
2010-08-04 09:59:08 +00:00
|
|
|
{
|
2012-09-24 08:59:36 +00:00
|
|
|
struct omap_gpio_chip *omapgpio =
|
|
|
|
container_of(chip, struct omap_gpio_chip, chip);
|
|
|
|
void __iomem *base = omapgpio->base;
|
2010-08-04 09:59:08 +00:00
|
|
|
u32 val;
|
|
|
|
|
2012-09-24 08:59:36 +00:00
|
|
|
base += OMAP_GPIO_OE;
|
2010-08-04 09:59:08 +00:00
|
|
|
|
2012-09-24 08:59:36 +00:00
|
|
|
val = readl(base);
|
|
|
|
val |= 1 << omap_get_gpio_index(gpio);
|
|
|
|
writel(val, base);
|
2010-08-04 09:59:08 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-09-24 08:59:36 +00:00
|
|
|
static int omap_gpio_direction_output(struct gpio_chip *chip,
|
|
|
|
unsigned gpio, int value)
|
2010-08-04 09:59:08 +00:00
|
|
|
{
|
2012-09-24 08:59:36 +00:00
|
|
|
struct omap_gpio_chip *omapgpio =
|
|
|
|
container_of(chip, struct omap_gpio_chip, chip);
|
|
|
|
void __iomem *base = omapgpio->base;
|
2010-08-04 09:59:08 +00:00
|
|
|
u32 val;
|
|
|
|
|
2012-09-24 08:59:36 +00:00
|
|
|
omap_gpio_set_value(chip, gpio, value);
|
2010-08-04 09:59:08 +00:00
|
|
|
|
2012-09-24 08:59:36 +00:00
|
|
|
base += OMAP_GPIO_OE;
|
2010-08-04 09:59:08 +00:00
|
|
|
|
2012-09-24 08:59:36 +00:00
|
|
|
val = readl(base);
|
|
|
|
val &= ~(1 << omap_get_gpio_index(gpio));
|
|
|
|
writel(val, base);
|
2010-08-04 09:59:08 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-09-24 08:59:36 +00:00
|
|
|
static int omap_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
|
|
|
|
{
|
|
|
|
struct omap_gpio_chip *omapgpio =
|
|
|
|
container_of(chip, struct omap_gpio_chip, chip);
|
|
|
|
void __iomem *base = omapgpio->base;
|
|
|
|
|
|
|
|
base += OMAP_GPIO_DATAIN;
|
|
|
|
|
|
|
|
return (readl(base) & (1 << omap_get_gpio_index(gpio))) != 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct gpio_ops omap_gpio_ops = {
|
|
|
|
.direction_input = omap_gpio_direction_input,
|
|
|
|
.direction_output = omap_gpio_direction_output,
|
|
|
|
.get = omap_gpio_get_value,
|
|
|
|
.set = omap_gpio_set_value,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int omap_gpio_probe(struct device_d *dev)
|
2010-08-04 09:59:08 +00:00
|
|
|
{
|
2012-09-24 08:59:36 +00:00
|
|
|
struct omap_gpio_chip *omapgpio;
|
|
|
|
|
|
|
|
omapgpio = xzalloc(sizeof(*omapgpio));
|
|
|
|
omapgpio->base = dev_request_mem_region(dev, 0);
|
|
|
|
omapgpio->chip.ops = &omap_gpio_ops;
|
2012-10-09 09:53:24 +00:00
|
|
|
omapgpio->chip.base = dev->id * 32;
|
2012-09-24 08:59:36 +00:00
|
|
|
omapgpio->chip.ngpio = 32;
|
|
|
|
omapgpio->chip.dev = dev;
|
|
|
|
gpiochip_add(&omapgpio->chip);
|
2010-08-04 09:59:08 +00:00
|
|
|
|
2012-09-28 12:57:01 +00:00
|
|
|
dev_dbg(dev, "probed gpiochip%d with base %d\n",
|
2012-09-24 08:59:36 +00:00
|
|
|
dev->id, omapgpio->chip.base);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2011-03-17 14:52:46 +00:00
|
|
|
|
2012-09-24 08:59:36 +00:00
|
|
|
static struct driver_d omap_gpio_driver = {
|
|
|
|
.name = "omap-gpio",
|
|
|
|
.probe = omap_gpio_probe,
|
|
|
|
};
|
2011-03-17 14:52:46 +00:00
|
|
|
|
2012-09-24 08:59:36 +00:00
|
|
|
static int omap_gpio_add(void)
|
|
|
|
{
|
2012-09-19 19:22:17 +00:00
|
|
|
return platform_driver_register(&omap_gpio_driver);
|
2010-08-04 09:59:08 +00:00
|
|
|
}
|
2012-09-24 08:59:36 +00:00
|
|
|
coredevice_initcall(omap_gpio_add);
|