diff options
Diffstat (limited to 'target/linux/brcm2708/patches-3.18/0002-Add-bcm2708_gpio-driver.patch')
-rw-r--r-- | target/linux/brcm2708/patches-3.18/0002-Add-bcm2708_gpio-driver.patch | 591 |
1 files changed, 0 insertions, 591 deletions
diff --git a/target/linux/brcm2708/patches-3.18/0002-Add-bcm2708_gpio-driver.patch b/target/linux/brcm2708/patches-3.18/0002-Add-bcm2708_gpio-driver.patch deleted file mode 100644 index cc29843ea0..0000000000 --- a/target/linux/brcm2708/patches-3.18/0002-Add-bcm2708_gpio-driver.patch +++ /dev/null @@ -1,591 +0,0 @@ -From 4f339b429583965a8eb7c23474414d0730db1215 Mon Sep 17 00:00:00 2001 -From: popcornmix <popcornmix@gmail.com> -Date: Wed, 8 Oct 2014 18:50:05 +0100 -Subject: [PATCH 002/114] Add bcm2708_gpio driver - -Signed-off-by: popcornmix <popcornmix@gmail.com> - -bcm2708: Add extension to configure internal pulls - -The bcm2708 gpio controller supports internal pulls to be used as pull-up, -pull-down or being entirely disabled. As it can be useful for a driver to -change the pull configuration from it's default pull-down state, add an -extension which allows configuring the pull per gpio. - -Signed-off-by: Julian Scheel <julian@jusst.de> - -bcm2708-gpio: Revert the use of pinctrl_request_gpio - -In non-DT systems, pinctrl_request_gpio always fails causing -"requests probe deferral" messages. In DT systems, it isn't useful -because the reference counting is independent of the normal pinctrl -pin reservations. - -gpio: Only clear the currently occurring interrupt. Avoids losing interrupts - -See: linux #760 - -bcm2708_gpio: Avoid calling irq_unmask for all interrupts - -When setting up the interrupts, specify that the handle_simple_irq -handler should be used. This leaves interrupt acknowledgement to -the caller, and prevents irq_unmask from being called for all -interrupts. - -Issue: linux #760 ---- - arch/arm/mach-bcm2708/Kconfig | 8 + - arch/arm/mach-bcm2708/Makefile | 1 + - arch/arm/mach-bcm2708/bcm2708.c | 28 ++ - arch/arm/mach-bcm2708/bcm2708_gpio.c | 426 ++++++++++++++++++++++++++++++ - arch/arm/mach-bcm2708/include/mach/gpio.h | 17 ++ - include/linux/platform_data/bcm2708.h | 23 ++ - 6 files changed, 503 insertions(+) - create mode 100644 arch/arm/mach-bcm2708/bcm2708_gpio.c - create mode 100644 arch/arm/mach-bcm2708/include/mach/gpio.h - create mode 100644 include/linux/platform_data/bcm2708.h - ---- a/arch/arm/mach-bcm2708/Kconfig -+++ b/arch/arm/mach-bcm2708/Kconfig -@@ -9,6 +9,14 @@ config MACH_BCM2708 - help - Include support for the Broadcom(R) BCM2708 platform. - -+config BCM2708_GPIO -+ bool "BCM2708 gpio support" -+ depends on MACH_BCM2708 -+ select ARCH_REQUIRE_GPIOLIB -+ default y -+ help -+ Include support for the Broadcom(R) BCM2708 gpio. -+ - config BCM2708_VCMEM - bool "Videocore Memory" - depends on MACH_BCM2708 ---- a/arch/arm/mach-bcm2708/Makefile -+++ b/arch/arm/mach-bcm2708/Makefile -@@ -3,4 +3,5 @@ - # - - obj-$(CONFIG_MACH_BCM2708) += clock.o bcm2708.o armctrl.o vcio.o power.o dma.o -+obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -331,6 +331,31 @@ static struct platform_device bcm2708_vc - }, - }; - -+#ifdef CONFIG_BCM2708_GPIO -+#define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" -+ -+static struct resource bcm2708_gpio_resources[] = { -+ [0] = { /* general purpose I/O */ -+ .start = GPIO_BASE, -+ .end = GPIO_BASE + SZ_4K - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; -+ -+static u64 gpio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); -+ -+static struct platform_device bcm2708_gpio_device = { -+ .name = BCM_GPIO_DRIVER_NAME, -+ .id = -1, /* only one VideoCore I/O area */ -+ .resource = bcm2708_gpio_resources, -+ .num_resources = ARRAY_SIZE(bcm2708_gpio_resources), -+ .dev = { -+ .dma_mask = &gpio_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), -+ }, -+}; -+#endif -+ - static struct resource bcm2708_systemtimer_resources[] = { - [0] = { /* system timer access */ - .start = ST_BASE, -@@ -473,6 +498,9 @@ void __init bcm2708_init(void) - - bcm_register_device(&bcm2708_dmaman_device); - bcm_register_device(&bcm2708_vcio_device); -+#ifdef CONFIG_BCM2708_GPIO -+ bcm_register_device(&bcm2708_gpio_device); -+#endif - bcm_register_device(&bcm2708_systemtimer_device); - bcm_register_device(&bcm2708_fb_device); - bcm_register_device(&bcm2708_usb_device); ---- /dev/null -+++ b/arch/arm/mach-bcm2708/bcm2708_gpio.c -@@ -0,0 +1,426 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/bcm2708_gpio.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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 <linux/spinlock.h> -+#include <linux/module.h> -+#include <linux/delay.h> -+#include <linux/list.h> -+#include <linux/io.h> -+#include <linux/irq.h> -+#include <linux/interrupt.h> -+#include <linux/slab.h> -+#include <mach/gpio.h> -+#include <linux/gpio.h> -+#include <linux/platform_device.h> -+#include <mach/platform.h> -+#include <linux/pinctrl/consumer.h> -+ -+#include <linux/platform_data/bcm2708.h> -+ -+#define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" -+#define DRIVER_NAME BCM_GPIO_DRIVER_NAME -+#define BCM_GPIO_USE_IRQ 1 -+ -+#define GPIOFSEL(x) (0x00+(x)*4) -+#define GPIOSET(x) (0x1c+(x)*4) -+#define GPIOCLR(x) (0x28+(x)*4) -+#define GPIOLEV(x) (0x34+(x)*4) -+#define GPIOEDS(x) (0x40+(x)*4) -+#define GPIOREN(x) (0x4c+(x)*4) -+#define GPIOFEN(x) (0x58+(x)*4) -+#define GPIOHEN(x) (0x64+(x)*4) -+#define GPIOLEN(x) (0x70+(x)*4) -+#define GPIOAREN(x) (0x7c+(x)*4) -+#define GPIOAFEN(x) (0x88+(x)*4) -+#define GPIOUD(x) (0x94+(x)*4) -+#define GPIOUDCLK(x) (0x98+(x)*4) -+ -+#define GPIO_BANKS 2 -+ -+enum { GPIO_FSEL_INPUT, GPIO_FSEL_OUTPUT, -+ GPIO_FSEL_ALT5, GPIO_FSEL_ALT_4, -+ GPIO_FSEL_ALT0, GPIO_FSEL_ALT1, -+ GPIO_FSEL_ALT2, GPIO_FSEL_ALT3, -+}; -+ -+ /* Each of the two spinlocks protects a different set of hardware -+ * regiters and data structurs. This decouples the code of the IRQ from -+ * the GPIO code. This also makes the case of a GPIO routine call from -+ * the IRQ code simpler. -+ */ -+static DEFINE_SPINLOCK(lock); /* GPIO registers */ -+ -+struct bcm2708_gpio { -+ struct list_head list; -+ void __iomem *base; -+ struct gpio_chip gc; -+ unsigned long rising[(BCM2708_NR_GPIOS + 31) / 32]; -+ unsigned long falling[(BCM2708_NR_GPIOS + 31) / 32]; -+ unsigned long high[(BCM2708_NR_GPIOS + 31) / 32]; -+ unsigned long low[(BCM2708_NR_GPIOS + 31) / 32]; -+}; -+ -+static int bcm2708_set_function(struct gpio_chip *gc, unsigned offset, -+ int function) -+{ -+ struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc); -+ unsigned long flags; -+ unsigned gpiodir; -+ unsigned gpio_bank = offset / 10; -+ unsigned gpio_field_offset = (offset - 10 * gpio_bank) * 3; -+ -+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_set_function %p (%d,%d)\n", gc, offset, function); -+ if (offset >= BCM2708_NR_GPIOS) -+ return -EINVAL; -+ -+ spin_lock_irqsave(&lock, flags); -+ -+ gpiodir = readl(gpio->base + GPIOFSEL(gpio_bank)); -+ gpiodir &= ~(7 << gpio_field_offset); -+ gpiodir |= function << gpio_field_offset; -+ writel(gpiodir, gpio->base + GPIOFSEL(gpio_bank)); -+ spin_unlock_irqrestore(&lock, flags); -+ gpiodir = readl(gpio->base + GPIOFSEL(gpio_bank)); -+ -+ return 0; -+} -+ -+static int bcm2708_gpio_dir_in(struct gpio_chip *gc, unsigned offset) -+{ -+ return bcm2708_set_function(gc, offset, GPIO_FSEL_INPUT); -+} -+ -+static void bcm2708_gpio_set(struct gpio_chip *gc, unsigned offset, int value); -+static int bcm2708_gpio_dir_out(struct gpio_chip *gc, unsigned offset, -+ int value) -+{ -+ int ret; -+ ret = bcm2708_set_function(gc, offset, GPIO_FSEL_OUTPUT); -+ if (ret >= 0) -+ bcm2708_gpio_set(gc, offset, value); -+ return ret; -+} -+ -+static int bcm2708_gpio_get(struct gpio_chip *gc, unsigned offset) -+{ -+ struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc); -+ unsigned gpio_bank = offset / 32; -+ unsigned gpio_field_offset = (offset - 32 * gpio_bank); -+ unsigned lev; -+ -+ if (offset >= BCM2708_NR_GPIOS) -+ return 0; -+ lev = readl(gpio->base + GPIOLEV(gpio_bank)); -+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_get %p (%d)=%d\n", gc, offset, 0x1 & (lev>>gpio_field_offset)); -+ return 0x1 & (lev >> gpio_field_offset); -+} -+ -+static void bcm2708_gpio_set(struct gpio_chip *gc, unsigned offset, int value) -+{ -+ struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc); -+ unsigned gpio_bank = offset / 32; -+ unsigned gpio_field_offset = (offset - 32 * gpio_bank); -+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_set %p (%d=%d)\n", gc, offset, value); -+ if (offset >= BCM2708_NR_GPIOS) -+ return; -+ if (value) -+ writel(1 << gpio_field_offset, gpio->base + GPIOSET(gpio_bank)); -+ else -+ writel(1 << gpio_field_offset, gpio->base + GPIOCLR(gpio_bank)); -+} -+ -+/********************** -+ * extension to configure pullups -+ */ -+int bcm2708_gpio_setpull(struct gpio_chip *gc, unsigned offset, -+ bcm2708_gpio_pull_t value) -+{ -+ struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc); -+ unsigned gpio_bank = offset / 32; -+ unsigned gpio_field_offset = (offset - 32 * gpio_bank); -+ -+ if (offset >= BCM2708_NR_GPIOS) -+ return -EINVAL; -+ -+ switch (value) { -+ case BCM2708_PULL_UP: -+ writel(2, gpio->base + GPIOUD(0)); -+ break; -+ case BCM2708_PULL_DOWN: -+ writel(1, gpio->base + GPIOUD(0)); -+ break; -+ case BCM2708_PULL_OFF: -+ writel(0, gpio->base + GPIOUD(0)); -+ break; -+ } -+ -+ udelay(5); -+ writel(1 << gpio_field_offset, gpio->base + GPIOUDCLK(gpio_bank)); -+ udelay(5); -+ writel(0, gpio->base + GPIOUD(0)); -+ writel(0 << gpio_field_offset, gpio->base + GPIOUDCLK(gpio_bank)); -+ -+ return 0; -+} -+EXPORT_SYMBOL(bcm2708_gpio_setpull); -+ -+/************************************************************************************************************************* -+ * bcm2708 GPIO IRQ -+ */ -+ -+#if BCM_GPIO_USE_IRQ -+ -+static int bcm2708_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) -+{ -+ return gpio_to_irq(gpio); -+} -+ -+static int bcm2708_gpio_irq_set_type(struct irq_data *d, unsigned type) -+{ -+ unsigned irq = d->irq; -+ struct bcm2708_gpio *gpio = irq_get_chip_data(irq); -+ unsigned gn = irq_to_gpio(irq); -+ unsigned gb = gn / 32; -+ unsigned go = gn % 32; -+ -+ gpio->rising[gb] &= ~(1 << go); -+ gpio->falling[gb] &= ~(1 << go); -+ gpio->high[gb] &= ~(1 << go); -+ gpio->low[gb] &= ~(1 << go); -+ -+ if (type & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) -+ return -EINVAL; -+ -+ if (type & IRQ_TYPE_EDGE_RISING) -+ gpio->rising[gb] |= (1 << go); -+ if (type & IRQ_TYPE_EDGE_FALLING) -+ gpio->falling[gb] |= (1 << go); -+ if (type & IRQ_TYPE_LEVEL_HIGH) -+ gpio->high[gb] |= (1 << go); -+ if (type & IRQ_TYPE_LEVEL_LOW) -+ gpio->low[gb] |= (1 << go); -+ return 0; -+} -+ -+static void bcm2708_gpio_irq_mask(struct irq_data *d) -+{ -+ unsigned irq = d->irq; -+ struct bcm2708_gpio *gpio = irq_get_chip_data(irq); -+ unsigned gn = irq_to_gpio(irq); -+ unsigned gb = gn / 32; -+ unsigned long rising = readl(gpio->base + GPIOREN(gb)); -+ unsigned long falling = readl(gpio->base + GPIOFEN(gb)); -+ unsigned long high = readl(gpio->base + GPIOHEN(gb)); -+ unsigned long low = readl(gpio->base + GPIOLEN(gb)); -+ -+ gn = gn % 32; -+ -+ writel(rising & ~(1 << gn), gpio->base + GPIOREN(gb)); -+ writel(falling & ~(1 << gn), gpio->base + GPIOFEN(gb)); -+ writel(high & ~(1 << gn), gpio->base + GPIOHEN(gb)); -+ writel(low & ~(1 << gn), gpio->base + GPIOLEN(gb)); -+} -+ -+static void bcm2708_gpio_irq_unmask(struct irq_data *d) -+{ -+ unsigned irq = d->irq; -+ struct bcm2708_gpio *gpio = irq_get_chip_data(irq); -+ unsigned gn = irq_to_gpio(irq); -+ unsigned gb = gn / 32; -+ unsigned go = gn % 32; -+ unsigned long rising = readl(gpio->base + GPIOREN(gb)); -+ unsigned long falling = readl(gpio->base + GPIOFEN(gb)); -+ unsigned long high = readl(gpio->base + GPIOHEN(gb)); -+ unsigned long low = readl(gpio->base + GPIOLEN(gb)); -+ -+ if (gpio->rising[gb] & (1 << go)) { -+ writel(rising | (1 << go), gpio->base + GPIOREN(gb)); -+ } else { -+ writel(rising & ~(1 << go), gpio->base + GPIOREN(gb)); -+ } -+ -+ if (gpio->falling[gb] & (1 << go)) { -+ writel(falling | (1 << go), gpio->base + GPIOFEN(gb)); -+ } else { -+ writel(falling & ~(1 << go), gpio->base + GPIOFEN(gb)); -+ } -+ -+ if (gpio->high[gb] & (1 << go)) { -+ writel(high | (1 << go), gpio->base + GPIOHEN(gb)); -+ } else { -+ writel(high & ~(1 << go), gpio->base + GPIOHEN(gb)); -+ } -+ -+ if (gpio->low[gb] & (1 << go)) { -+ writel(low | (1 << go), gpio->base + GPIOLEN(gb)); -+ } else { -+ writel(low & ~(1 << go), gpio->base + GPIOLEN(gb)); -+ } -+} -+ -+static struct irq_chip bcm2708_irqchip = { -+ .name = "GPIO", -+ .irq_enable = bcm2708_gpio_irq_unmask, -+ .irq_disable = bcm2708_gpio_irq_mask, -+ .irq_unmask = bcm2708_gpio_irq_unmask, -+ .irq_mask = bcm2708_gpio_irq_mask, -+ .irq_set_type = bcm2708_gpio_irq_set_type, -+}; -+ -+static irqreturn_t bcm2708_gpio_interrupt(int irq, void *dev_id) -+{ -+ unsigned long edsr; -+ unsigned bank; -+ int i; -+ unsigned gpio; -+ unsigned level_bits; -+ struct bcm2708_gpio *gpio_data = dev_id; -+ -+ for (bank = 0; bank < GPIO_BANKS; bank++) { -+ edsr = readl(__io_address(GPIO_BASE) + GPIOEDS(bank)); -+ level_bits = gpio_data->high[bank] | gpio_data->low[bank]; -+ -+ for_each_set_bit(i, &edsr, 32) { -+ gpio = i + bank * 32; -+ /* ack edge triggered IRQs immediately */ -+ if (!(level_bits & (1<<i))) -+ writel(1<<i, -+ __io_address(GPIO_BASE) + GPIOEDS(bank)); -+ generic_handle_irq(gpio_to_irq(gpio)); -+ /* ack level triggered IRQ after handling them */ -+ if (level_bits & (1<<i)) -+ writel(1<<i, -+ __io_address(GPIO_BASE) + GPIOEDS(bank)); -+ } -+ } -+ return IRQ_HANDLED; -+} -+ -+static struct irqaction bcm2708_gpio_irq = { -+ .name = "BCM2708 GPIO catchall handler", -+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, -+ .handler = bcm2708_gpio_interrupt, -+}; -+ -+static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb) -+{ -+ unsigned irq; -+ -+ ucb->gc.to_irq = bcm2708_gpio_to_irq; -+ -+ for (irq = GPIO_IRQ_START; irq < (GPIO_IRQ_START + GPIO_IRQS); irq++) { -+ irq_set_chip_data(irq, ucb); -+ irq_set_chip_and_handler(irq, &bcm2708_irqchip, -+ handle_simple_irq); -+ set_irq_flags(irq, IRQF_VALID); -+ } -+ -+ bcm2708_gpio_irq.dev_id = ucb; -+ setup_irq(IRQ_GPIO3, &bcm2708_gpio_irq); -+} -+ -+#else -+ -+static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb) -+{ -+} -+ -+#endif /* #if BCM_GPIO_USE_IRQ ***************************************************************************************************************** */ -+ -+static int bcm2708_gpio_probe(struct platform_device *dev) -+{ -+ struct bcm2708_gpio *ucb; -+ struct resource *res; -+ int bank; -+ int err = 0; -+ -+ printk(KERN_INFO DRIVER_NAME ": bcm2708_gpio_probe %p\n", dev); -+ -+ ucb = kzalloc(sizeof(*ucb), GFP_KERNEL); -+ if (NULL == ucb) { -+ printk(KERN_ERR DRIVER_NAME ": failed to allocate " -+ "mailbox memory\n"); -+ err = -ENOMEM; -+ goto err; -+ } -+ -+ res = platform_get_resource(dev, IORESOURCE_MEM, 0); -+ -+ platform_set_drvdata(dev, ucb); -+ ucb->base = __io_address(GPIO_BASE); -+ -+ ucb->gc.label = "bcm2708_gpio"; -+ ucb->gc.base = 0; -+ ucb->gc.ngpio = BCM2708_NR_GPIOS; -+ ucb->gc.owner = THIS_MODULE; -+ -+ ucb->gc.direction_input = bcm2708_gpio_dir_in; -+ ucb->gc.direction_output = bcm2708_gpio_dir_out; -+ ucb->gc.get = bcm2708_gpio_get; -+ ucb->gc.set = bcm2708_gpio_set; -+ ucb->gc.can_sleep = 0; -+ -+ for (bank = 0; bank < GPIO_BANKS; bank++) { -+ writel(0, ucb->base + GPIOREN(bank)); -+ writel(0, ucb->base + GPIOFEN(bank)); -+ writel(0, ucb->base + GPIOHEN(bank)); -+ writel(0, ucb->base + GPIOLEN(bank)); -+ writel(0, ucb->base + GPIOAREN(bank)); -+ writel(0, ucb->base + GPIOAFEN(bank)); -+ writel(~0, ucb->base + GPIOEDS(bank)); -+ } -+ -+ bcm2708_gpio_irq_init(ucb); -+ -+ err = gpiochip_add(&ucb->gc); -+ -+err: -+ return err; -+ -+} -+ -+static int bcm2708_gpio_remove(struct platform_device *dev) -+{ -+ int err = 0; -+ struct bcm2708_gpio *ucb = platform_get_drvdata(dev); -+ -+ printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_remove %p\n", dev); -+ -+ gpiochip_remove(&ucb->gc); -+ -+ platform_set_drvdata(dev, NULL); -+ kfree(ucb); -+ -+ return err; -+} -+ -+static struct platform_driver bcm2708_gpio_driver = { -+ .probe = bcm2708_gpio_probe, -+ .remove = bcm2708_gpio_remove, -+ .driver = { -+ .name = "bcm2708_gpio"}, -+}; -+ -+static int __init bcm2708_gpio_init(void) -+{ -+ return platform_driver_register(&bcm2708_gpio_driver); -+} -+ -+static void __exit bcm2708_gpio_exit(void) -+{ -+ platform_driver_unregister(&bcm2708_gpio_driver); -+} -+ -+module_init(bcm2708_gpio_init); -+module_exit(bcm2708_gpio_exit); -+ -+MODULE_DESCRIPTION("Broadcom BCM2708 GPIO driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/arch/arm/mach-bcm2708/include/mach/gpio.h -@@ -0,0 +1,17 @@ -+/* -+ * arch/arm/mach-bcm2708/include/mach/gpio.h -+ * -+ * This file is licensed under the terms of the GNU General Public -+ * License version 2. This program is licensed "as is" without any -+ * warranty of any kind, whether express or implied. -+ */ -+ -+#ifndef __ASM_ARCH_GPIO_H -+#define __ASM_ARCH_GPIO_H -+ -+#define BCM2708_NR_GPIOS 54 // number of gpio lines -+ -+#define gpio_to_irq(x) ((x) + GPIO_IRQ_START) -+#define irq_to_gpio(x) ((x) - GPIO_IRQ_START) -+ -+#endif ---- /dev/null -+++ b/include/linux/platform_data/bcm2708.h -@@ -0,0 +1,23 @@ -+/* -+ * include/linux/platform_data/bcm2708.h -+ * -+ * 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. -+ * -+ * (C) 2014 Julian Scheel <julian@jusst.de> -+ * -+ */ -+#ifndef __BCM2708_H_ -+#define __BCM2708_H_ -+ -+typedef enum { -+ BCM2708_PULL_OFF, -+ BCM2708_PULL_UP, -+ BCM2708_PULL_DOWN -+} bcm2708_gpio_pull_t; -+ -+extern int bcm2708_gpio_setpull(struct gpio_chip *gc, unsigned offset, -+ bcm2708_gpio_pull_t value); -+ -+#endif |