diff options
4 files changed, 143 insertions, 2 deletions
diff --git a/target/linux/adm8668/config-3.3 b/target/linux/adm8668/config-3.3 index 169245d1c..e63f14053 100644 --- a/target/linux/adm8668/config-3.3 +++ b/target/linux/adm8668/config-3.3 @@ -2,6 +2,7 @@ CONFIG_ADM8668=y  CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y  CONFIG_ARCH_DISCARD_MEMBLOCK=y  CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y  CONFIG_ARCH_SUSPEND_POSSIBLE=y  CONFIG_ARM_AMBA=y  # CONFIG_ARM_SP805_WATCHDOG is not set @@ -31,8 +32,11 @@ CONFIG_GENERIC_ATOMIC64=y  CONFIG_GENERIC_CLOCKEVENTS=y  CONFIG_GENERIC_CLOCKEVENTS_BUILD=y  CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_GPIO=y  CONFIG_GENERIC_IRQ_SHOW=y  CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y  CONFIG_HARDWARE_WATCHPOINTS=y  CONFIG_HAS_DMA=y  CONFIG_HAS_IOMEM=y diff --git a/target/linux/adm8668/files/arch/mips/adm8668/gpio.c b/target/linux/adm8668/files/arch/mips/adm8668/gpio.c new file mode 100644 index 000000000..fb39f7f58 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/gpio.c @@ -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); diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/gpio.h b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/gpio.h new file mode 100644 index 000000000..b0473fc4b --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/gpio.h @@ -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 diff --git a/target/linux/adm8668/patches-3.3/001-adm8668_arch.patch b/target/linux/adm8668/patches-3.3/001-adm8668_arch.patch index 66be46c8d..1d52bcf97 100644 --- a/target/linux/adm8668/patches-3.3/001-adm8668_arch.patch +++ b/target/linux/adm8668/patches-3.3/001-adm8668_arch.patch @@ -10,7 +10,7 @@   include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms))  --- a/arch/mips/Kconfig  +++ b/arch/mips/Kconfig -@@ -105,6 +105,25 @@ config BCM47XX +@@ -105,6 +105,26 @@ config BCM47XX   	help   	 Support for BCM47XX based boards @@ -29,6 +29,7 @@  +	select DMA_NONCOHERENT  +	select SWAP_IO_SPACE  +	select SYS_HAS_EARLY_PRINTK ++	select ARCH_REQUIRE_GPIOLIB  +	help  +		ADM8668 board support by neutronscott  +		Scott Nicholas <neutronscott@scottn.us> @@ -36,7 +37,7 @@   config BCM63XX   	bool "Broadcom BCM63XX based boards"   	select CEVT_R4K -@@ -813,6 +832,7 @@ config NLM_XLP_BOARD +@@ -813,6 +833,7 @@ config NLM_XLP_BOARD   endchoice  | 
