Signed-off-by: Florian Fainelli <florian@openwrt.org> SVN-Revision: 34564master
parent
78b235cfc3
commit
849662a8ec
@ -0,0 +1,123 @@ |
||||
/*
|
||||
* Infineon/ADMTek ADM8668 WildPass GPIO support |
||||
* |
||||
* Copyright (C) 2012 Florian Fainelli <florian@openwrt.org> |
||||
* |
||||
* Licensed under the terms of GPLv2. |
||||
* |
||||
*/ |
||||
#include <linux/kernel.h> |
||||
#include <linux/gpio.h> |
||||
#include <linux/io.h> |
||||
|
||||
#include <adm8668.h> |
||||
|
||||
#define GPIO_MASK 0x3f |
||||
|
||||
#define GPIO_IN_OFS 0 |
||||
#define GPIO_OUT_OFS 6 |
||||
#define GPIO_OE_OFS 12 |
||||
|
||||
struct adm8668_gpio_chip { |
||||
void __iomem *base; |
||||
struct gpio_chip chip; |
||||
}; |
||||
|
||||
static int adm8668_gpio_dir_out(struct gpio_chip *chip, |
||||
unsigned offset, int value) |
||||
{ |
||||
struct adm8668_gpio_chip *c = |
||||
container_of(chip, struct adm8668_gpio_chip, chip); |
||||
u32 mask; |
||||
|
||||
/* clear input, set output enable and output value */ |
||||
mask = __raw_readl(c->base); |
||||
mask &= ~(1 << offset); |
||||
mask |= (1 << (offset + GPIO_OE_OFS)); |
||||
if (value) |
||||
mask |= (1 << (offset + GPIO_OUT_OFS)); |
||||
else |
||||
mask &= ~(1 << (offset + GPIO_OUT_OFS)); |
||||
__raw_writel(mask, c->base); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int adm8668_gpio_dir_in(struct gpio_chip *chip, |
||||
unsigned offset) |
||||
{ |
||||
struct adm8668_gpio_chip *c = |
||||
container_of(chip, struct adm8668_gpio_chip, chip); |
||||
u32 mask; |
||||
|
||||
mask = __raw_readl(c->base); |
||||
mask &= ~(((1 << (offset + GPIO_OE_OFS)) | (1 << (offset + GPIO_OUT_OFS)))); |
||||
mask |= (1 << offset); |
||||
__raw_writel(mask, c->base); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static void adm8668_gpio_set(struct gpio_chip *chip, |
||||
unsigned offset, int value) |
||||
{ |
||||
struct adm8668_gpio_chip *c = |
||||
container_of(chip, struct adm8668_gpio_chip, chip); |
||||
u32 mask; |
||||
|
||||
mask = __raw_readl(c->base); |
||||
if (value) |
||||
mask |= (1 << (offset + GPIO_OUT_OFS)); |
||||
else |
||||
mask &= ~(1 << (offset + GPIO_OUT_OFS)); |
||||
__raw_writel(mask, c->base); |
||||
} |
||||
|
||||
static int adm8668_gpio_get(struct gpio_chip *chip, |
||||
unsigned offset) |
||||
{ |
||||
struct adm8668_gpio_chip *c = |
||||
container_of(chip, struct adm8668_gpio_chip, chip); |
||||
u32 value; |
||||
|
||||
value = __raw_readl(c->base) & GPIO_MASK; |
||||
|
||||
return value & (1 << offset); |
||||
} |
||||
|
||||
static struct adm8668_gpio_chip adm8668_gpio_cpu = { |
||||
.base = (void __iomem *)KSEG1ADDR(ADM8668_CONFIG_BASE + CRGPIO_REG), |
||||
.chip = { |
||||
.label = "adm8668-cpu-gpio", |
||||
.direction_output = adm8668_gpio_dir_out, |
||||
.direction_input = adm8668_gpio_dir_in, |
||||
.set = adm8668_gpio_set, |
||||
.get = adm8668_gpio_get, |
||||
.ngpio = 6, |
||||
}, |
||||
}; |
||||
|
||||
static struct adm8668_gpio_chip adm8668_gpio_wlan = { |
||||
.base = (void __iomem *)KSEG1ADDR(ADM8668_WLAN_BASE + GPIO_REG), |
||||
.chip = { |
||||
.label = "adm8668-wlan-gpio", |
||||
.direction_output = adm8668_gpio_dir_out, |
||||
.direction_input = adm8668_gpio_dir_in, |
||||
.set = adm8668_gpio_set, |
||||
.get = adm8668_gpio_get, |
||||
.ngpio = 6, |
||||
.base = 6, |
||||
}, |
||||
}; |
||||
|
||||
static int __init adm8668_gpio_init(void) |
||||
{ |
||||
int ret; |
||||
|
||||
ret = gpiochip_add(&adm8668_gpio_cpu.chip); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
return gpiochip_add(&adm8668_gpio_wlan.chip); |
||||
} |
||||
arch_initcall(adm8668_gpio_init); |
@ -0,0 +1,13 @@ |
||||
#ifndef __ADM8668_GPIO_H__ |
||||
#define __ADM8668_GPIO_H__ |
||||
|
||||
#define gpio_to_irq(gpio) -1 |
||||
|
||||
#define gpio_get_value __gpio_get_value |
||||
#define gpio_set_value __gpio_set_value |
||||
|
||||
#define gpio_cansleep __gpio_cansleep |
||||
|
||||
#include <asm-generic/gpio.h> |
||||
|
||||
#endif |
Loading…
Reference in new issue