9
0
Fork 0

Merge branch 'for-next/gpio' into for-next/bcm2835

This commit is contained in:
Sascha Hauer 2012-10-21 10:48:14 +02:00
commit 6f13282949
14 changed files with 211 additions and 81 deletions

View File

@ -88,6 +88,7 @@ config ARCH_S3C64xx
config ARCH_VERSATILE
bool "ARM Versatile boards (ARM926EJ-S)"
select CPU_ARM926T
select GPIOLIB
config ARCH_TEGRA
bool "Nvidia Tegra-based boards"

View File

@ -32,6 +32,7 @@ CONFIG_CMD_RESET=y
CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
@ -43,6 +44,7 @@ CONFIG_NET_NETCONSOLE=y
CONFIG_NET_RESOLV=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_DRIVER_NET_SMC91111=y
CONFIG_GPIO_PL061=y
CONFIG_FS_CRAMFS=y
CONFIG_SHA1=y
CONFIG_SHA256=y

View File

@ -1,26 +1 @@
/*
* Copyright (C) 2010 Matthias Kaehlcke <matthias@kaehlcke.net>
*
* 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.
*
*
*/
#ifndef __ASM_ARCH_GPIO_H
#define __ASM_ARCH_GPIO_H
void gpio_set_value(unsigned gpio, int value);
int gpio_get_value(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);
int gpio_direction_input(unsigned gpio);
#endif /* __ASM_ARCH_GPIO_H */
#include <asm-generic/gpio.h>

View File

@ -1,11 +1,8 @@
#ifndef __ASM_ARCH_GPIO_H
#define __ASM_ARCH_GPIO_H
#include <asm-generic/gpio.h>
void imx_gpio_mode(int gpio_mode);
void gpio_set_value(unsigned gpio, int value);
int gpio_get_value(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);
int gpio_direction_input(unsigned gpio);
#endif /* __ASM_ARCH_GPIO_H */

View File

@ -25,10 +25,8 @@
# include <mach/iomux-imx28.h>
#endif
#include <asm-generic/gpio.h>
void imx_gpio_mode(uint32_t);
void gpio_set_value(unsigned, int);
int gpio_direction_input(unsigned);
int gpio_direction_output(unsigned, int);
int gpio_get_value(unsigned);
#endif /* __ASM_MACH_GPIO_H */

View File

@ -1,42 +1 @@
/*
* 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.
*/
#ifndef _GPIO_H
#define _GPIO_H
void gpio_set_value(unsigned gpio, int value);
int gpio_get_value(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);
int gpio_direction_input(unsigned gpio);
#endif /* _GPIO_H_ */
#include <asm-generic/gpio.h>

View File

@ -23,10 +23,8 @@
# include <mach/iomux-s5pcxx.h>
#endif
void gpio_set_value(unsigned, int);
int gpio_direction_input(unsigned);
int gpio_direction_output(unsigned, int);
int gpio_get_value(unsigned);
#include <asm-generic/gpio.h>
void s3c_gpio_mode(unsigned);
#endif /* __ASM_MACH_GPIO_H */

View File

@ -196,3 +196,13 @@ void __noreturn reset_cpu (unsigned long ignored)
while(1);
}
EXPORT_SYMBOL(reset_cpu);
static int versatile_init(void)
{
amba_apb_device_add(NULL, "pl061_gpio", 0, 0x101e4000, 4096, NULL, 0);
amba_apb_device_add(NULL, "pl061_gpio", 1, 0x101e5000, 4096, NULL, 0);
amba_apb_device_add(NULL, "pl061_gpio", 2, 0x101e6000, 4096, NULL, 0);
amba_apb_device_add(NULL, "pl061_gpio", 3, 0x101e7000, 4096, NULL, 0);
return 0;
}
coredevice_initcall(versatile_init);

View File

@ -0,0 +1 @@
#include <asm-generic/gpio.h>

View File

@ -1,10 +1,17 @@
config GPIOLIB
bool
select GENERIC_GPIO
if GPIOLIB
menu "GPIO "
config GPIO_PL061
bool "PrimeCell PL061 GPIO support"
depends on ARM_AMBA
help
Say yes here to support the PrimeCell PL061 GPIO device
config GPIO_STMPE
depends on I2C_STMPE
bool "STMPE GPIO Expander"

View File

@ -1,2 +1,4 @@
obj-$(CONFIG_GPIOLIB) += gpio.o
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o

158
drivers/gpio/gpio-pl061.c Normal file
View File

@ -0,0 +1,158 @@
/*
* Copyright (C) 2008, 2009 Provigent Ltd.
*
* 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.
*
* Driver for the ARM PrimeCell(tm) General Purpose Input/Output (PL061)
*
* Data sheet: ARM DDI 0190B, September 2000
*/
#include <common.h>
#include <malloc.h>
#include <errno.h>
#include <io.h>
#include <gpio.h>
#include <init.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl061.h>
#define GPIODIR 0x400
#define GPIOIS 0x404
#define GPIOIBE 0x408
#define GPIOIEV 0x40C
#define GPIOIE 0x410
#define GPIORIS 0x414
#define GPIOMIS 0x418
#define GPIOIC 0x41C
#define PL061_GPIO_NR 8
struct pl061_gpio {
void __iomem *base;
struct gpio_chip gc;
};
static int pl061_direction_input(struct gpio_chip *gc, unsigned offset)
{
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
unsigned char gpiodir;
if (offset >= gc->ngpio)
return -EINVAL;
gpiodir = readb(chip->base + GPIODIR);
gpiodir &= ~(1 << offset);
writeb(gpiodir, chip->base + GPIODIR);
return 0;
}
static int pl061_direction_output(struct gpio_chip *gc, unsigned offset,
int value)
{
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
unsigned char gpiodir;
if (offset >= gc->ngpio)
return -EINVAL;
writeb(!!value << offset, chip->base + (1 << (offset + 2)));
gpiodir = readb(chip->base + GPIODIR);
gpiodir |= 1 << offset;
writeb(gpiodir, chip->base + GPIODIR);
/*
* gpio value is set again, because pl061 doesn't allow to set value of
* a gpio pin before configuring it in OUT mode.
*/
writeb(!!value << offset, chip->base + (1 << (offset + 2)));
return 0;
}
static int pl061_get_value(struct gpio_chip *gc, unsigned offset)
{
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
return !!readb(chip->base + (1 << (offset + 2)));
}
static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value)
{
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
writeb(!!value << offset, chip->base + (1 << (offset + 2)));
}
static struct gpio_ops pl061_gpio_ops = {
.direction_input = pl061_direction_input,
.direction_output = pl061_direction_output,
.get = pl061_get_value,
.set = pl061_set_value,
};
static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
{
struct pl061_platform_data *pdata;
struct pl061_gpio *chip;
int ret;
chip = xzalloc(sizeof(*chip));
pdata = dev->dev.platform_data;
if (pdata) {
chip->gc.base = pdata->gpio_base;
} else {
chip->gc.base = -1;
}
chip->base = amba_get_mem_region(dev);
chip->gc.ops = &pl061_gpio_ops;
chip->gc.ngpio = PL061_GPIO_NR;
chip->gc.dev = &dev->dev;
ret = gpiochip_add(&chip->gc);
if (ret) {
dev_err(&dev->dev, "couldn't add gpiochip, ret = %d\n", ret);
goto free_mem;
}
writeb(0, chip->base + GPIOIE); /* disable irqs */
return 0;
free_mem:
kfree(chip);
return ret;
}
static struct amba_id pl061_ids[] = {
{
.id = 0x00041061,
.mask = 0x000fffff,
},
{ 0, 0 },
};
static struct amba_driver pl061_gpio_driver = {
.drv = {
.name = "pl061_gpio",
},
.id_table = pl061_ids,
.probe = pl061_probe,
};
static int __init pl061_gpio_init(void)
{
return amba_driver_register(&pl061_gpio_driver);
}
coredevice_initcall(pl061_gpio_init);
MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
MODULE_DESCRIPTION("PL061 GPIO driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,10 @@
#ifndef __ASM_GENERIC_GPIO_H
#define __ASM_GENERIC_GPIO_H
void gpio_set_value(unsigned gpio, int value);
int gpio_get_value(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);
int gpio_direction_input(unsigned gpio);
#endif /* __ASM_GENERIC_GPIO_H */

View File

@ -0,0 +1,12 @@
#ifndef __AMBA_PL061_H__
#define __AMBA_PL061_H__
#include <linux/types.h>
/* platform data for the PL061 GPIO driver */
struct pl061_platform_data {
/* number of the first GPIO */
unsigned gpio_base;
};
#endif /* __AMBA_PL061_H__ */