Merge branch 'gpio/next' of git://git.secretlab.ca/git/linux-2.6
* 'gpio/next' of git://git.secretlab.ca/git/linux-2.6: gpio/pch_gpio: Support new device ML7223 gpio: make gpio_{request,free}_array gpio array parameter const GPIO: OMAP: move to drivers/gpio GPIO: OMAP: move register offset defines into <plat/gpio.h> gpio: Convert gpio_is_valid to return bool gpio: Move the s5pc100 GPIO to drivers/gpio gpio: Move the s5pv210 GPIO to drivers/gpio gpio: Move the exynos4 GPIO to drivers/gpio gpio: Move to Samsung common GPIO library to drivers/gpio gpio/nomadik: add function to read GPIO pull down status gpio/nomadik: show all pins in debug gpio: move Nomadik GPIO driver to drivers/gpio gpio: move U300 GPIO driver to drivers/gpio langwell_gpio: add runtime pm support gpio/pca953x: Add support for pca9574 and pca9575 devices gpio/cs5535: Show explicit dependency between gpio_cs5535 and mfd_cs5535
This commit is contained in:
commit
04830fccdc
27 changed files with 472 additions and 195 deletions
|
@ -13,7 +13,7 @@ obj- :=
|
|||
# Core support for EXYNOS4 system
|
||||
|
||||
obj-$(CONFIG_CPU_EXYNOS4210) += cpu.o init.o clock.o irq-combiner.o
|
||||
obj-$(CONFIG_CPU_EXYNOS4210) += setup-i2c0.o gpiolib.o irq-eint.o dma.o
|
||||
obj-$(CONFIG_CPU_EXYNOS4210) += setup-i2c0.o irq-eint.o dma.o
|
||||
obj-$(CONFIG_PM) += pm.o sleep.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
|
||||
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||
|
|
|
@ -6,7 +6,6 @@ config MACH_NOMADIK_8815NHK
|
|||
bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
|
||||
select NOMADIK_8815
|
||||
select HAS_MTU
|
||||
select NOMADIK_GPIO
|
||||
|
||||
endmenu
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ obj- :=
|
|||
|
||||
# Core support for S5PC100 system
|
||||
|
||||
obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o gpiolib.o
|
||||
obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o
|
||||
obj-$(CONFIG_CPU_S5PC100) += setup-i2c0.o
|
||||
obj-$(CONFIG_CPU_S5PC100) += dma.o
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ obj- :=
|
|||
|
||||
# Core support for S5PV210 system
|
||||
|
||||
obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o
|
||||
obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o
|
||||
obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o
|
||||
obj-$(CONFIG_S5PV210_PM) += pm.o sleep.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Makefile for the linux kernel, U300 machine.
|
||||
#
|
||||
|
||||
obj-y := core.o clock.o timer.o gpio.o padmux.o
|
||||
obj-y := core.o clock.o timer.o padmux.o
|
||||
obj-m :=
|
||||
obj-n :=
|
||||
obj- :=
|
||||
|
|
|
@ -5,7 +5,6 @@ config UX500_SOC_COMMON
|
|||
default y
|
||||
select ARM_GIC
|
||||
select HAS_MTU
|
||||
select NOMADIK_GPIO
|
||||
select ARM_ERRATA_753970
|
||||
|
||||
menu "Ux500 SoC"
|
||||
|
|
|
@ -21,9 +21,4 @@ config HAS_MTU
|
|||
to multiple interrupt generating programmable
|
||||
32-bit free running decrementing counters.
|
||||
|
||||
config NOMADIK_GPIO
|
||||
bool
|
||||
help
|
||||
Support for the Nomadik GPIO controller.
|
||||
|
||||
endif
|
||||
|
|
|
@ -3,4 +3,3 @@
|
|||
# Licensed under GPLv2
|
||||
|
||||
obj-$(CONFIG_HAS_MTU) += timer.o
|
||||
obj-$(CONFIG_NOMADIK_GPIO) += gpio.o
|
||||
|
|
|
@ -78,6 +78,8 @@ extern int nmk_gpio_get_mode(int gpio);
|
|||
extern void nmk_gpio_wakeups_suspend(void);
|
||||
extern void nmk_gpio_wakeups_resume(void);
|
||||
|
||||
extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up);
|
||||
|
||||
/*
|
||||
* Platform data to register a block: only the initial gpio/irq number.
|
||||
*/
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
|
||||
# Common support
|
||||
obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \
|
||||
obj-y := common.o sram.o clock.o devices.o dma.o mux.o \
|
||||
usb.o fb.o io.o counter_32k.o
|
||||
obj-m :=
|
||||
obj-n :=
|
||||
|
|
|
@ -52,6 +52,109 @@
|
|||
|
||||
#define OMAP34XX_NR_GPIOS 6
|
||||
|
||||
/*
|
||||
* OMAP1510 GPIO registers
|
||||
*/
|
||||
#define OMAP1510_GPIO_DATA_INPUT 0x00
|
||||
#define OMAP1510_GPIO_DATA_OUTPUT 0x04
|
||||
#define OMAP1510_GPIO_DIR_CONTROL 0x08
|
||||
#define OMAP1510_GPIO_INT_CONTROL 0x0c
|
||||
#define OMAP1510_GPIO_INT_MASK 0x10
|
||||
#define OMAP1510_GPIO_INT_STATUS 0x14
|
||||
#define OMAP1510_GPIO_PIN_CONTROL 0x18
|
||||
|
||||
#define OMAP1510_IH_GPIO_BASE 64
|
||||
|
||||
/*
|
||||
* OMAP1610 specific GPIO registers
|
||||
*/
|
||||
#define OMAP1610_GPIO_REVISION 0x0000
|
||||
#define OMAP1610_GPIO_SYSCONFIG 0x0010
|
||||
#define OMAP1610_GPIO_SYSSTATUS 0x0014
|
||||
#define OMAP1610_GPIO_IRQSTATUS1 0x0018
|
||||
#define OMAP1610_GPIO_IRQENABLE1 0x001c
|
||||
#define OMAP1610_GPIO_WAKEUPENABLE 0x0028
|
||||
#define OMAP1610_GPIO_DATAIN 0x002c
|
||||
#define OMAP1610_GPIO_DATAOUT 0x0030
|
||||
#define OMAP1610_GPIO_DIRECTION 0x0034
|
||||
#define OMAP1610_GPIO_EDGE_CTRL1 0x0038
|
||||
#define OMAP1610_GPIO_EDGE_CTRL2 0x003c
|
||||
#define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c
|
||||
#define OMAP1610_GPIO_CLEAR_WAKEUPENA 0x00a8
|
||||
#define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0
|
||||
#define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc
|
||||
#define OMAP1610_GPIO_SET_WAKEUPENA 0x00e8
|
||||
#define OMAP1610_GPIO_SET_DATAOUT 0x00f0
|
||||
|
||||
/*
|
||||
* OMAP7XX specific GPIO registers
|
||||
*/
|
||||
#define OMAP7XX_GPIO_DATA_INPUT 0x00
|
||||
#define OMAP7XX_GPIO_DATA_OUTPUT 0x04
|
||||
#define OMAP7XX_GPIO_DIR_CONTROL 0x08
|
||||
#define OMAP7XX_GPIO_INT_CONTROL 0x0c
|
||||
#define OMAP7XX_GPIO_INT_MASK 0x10
|
||||
#define OMAP7XX_GPIO_INT_STATUS 0x14
|
||||
|
||||
/*
|
||||
* omap2+ specific GPIO registers
|
||||
*/
|
||||
#define OMAP24XX_GPIO_REVISION 0x0000
|
||||
#define OMAP24XX_GPIO_IRQSTATUS1 0x0018
|
||||
#define OMAP24XX_GPIO_IRQSTATUS2 0x0028
|
||||
#define OMAP24XX_GPIO_IRQENABLE2 0x002c
|
||||
#define OMAP24XX_GPIO_IRQENABLE1 0x001c
|
||||
#define OMAP24XX_GPIO_WAKE_EN 0x0020
|
||||
#define OMAP24XX_GPIO_CTRL 0x0030
|
||||
#define OMAP24XX_GPIO_OE 0x0034
|
||||
#define OMAP24XX_GPIO_DATAIN 0x0038
|
||||
#define OMAP24XX_GPIO_DATAOUT 0x003c
|
||||
#define OMAP24XX_GPIO_LEVELDETECT0 0x0040
|
||||
#define OMAP24XX_GPIO_LEVELDETECT1 0x0044
|
||||
#define OMAP24XX_GPIO_RISINGDETECT 0x0048
|
||||
#define OMAP24XX_GPIO_FALLINGDETECT 0x004c
|
||||
#define OMAP24XX_GPIO_DEBOUNCE_EN 0x0050
|
||||
#define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0054
|
||||
#define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060
|
||||
#define OMAP24XX_GPIO_SETIRQENABLE1 0x0064
|
||||
#define OMAP24XX_GPIO_CLEARWKUENA 0x0080
|
||||
#define OMAP24XX_GPIO_SETWKUENA 0x0084
|
||||
#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090
|
||||
#define OMAP24XX_GPIO_SETDATAOUT 0x0094
|
||||
|
||||
#define OMAP4_GPIO_REVISION 0x0000
|
||||
#define OMAP4_GPIO_EOI 0x0020
|
||||
#define OMAP4_GPIO_IRQSTATUSRAW0 0x0024
|
||||
#define OMAP4_GPIO_IRQSTATUSRAW1 0x0028
|
||||
#define OMAP4_GPIO_IRQSTATUS0 0x002c
|
||||
#define OMAP4_GPIO_IRQSTATUS1 0x0030
|
||||
#define OMAP4_GPIO_IRQSTATUSSET0 0x0034
|
||||
#define OMAP4_GPIO_IRQSTATUSSET1 0x0038
|
||||
#define OMAP4_GPIO_IRQSTATUSCLR0 0x003c
|
||||
#define OMAP4_GPIO_IRQSTATUSCLR1 0x0040
|
||||
#define OMAP4_GPIO_IRQWAKEN0 0x0044
|
||||
#define OMAP4_GPIO_IRQWAKEN1 0x0048
|
||||
#define OMAP4_GPIO_IRQENABLE1 0x011c
|
||||
#define OMAP4_GPIO_WAKE_EN 0x0120
|
||||
#define OMAP4_GPIO_IRQSTATUS2 0x0128
|
||||
#define OMAP4_GPIO_IRQENABLE2 0x012c
|
||||
#define OMAP4_GPIO_CTRL 0x0130
|
||||
#define OMAP4_GPIO_OE 0x0134
|
||||
#define OMAP4_GPIO_DATAIN 0x0138
|
||||
#define OMAP4_GPIO_DATAOUT 0x013c
|
||||
#define OMAP4_GPIO_LEVELDETECT0 0x0140
|
||||
#define OMAP4_GPIO_LEVELDETECT1 0x0144
|
||||
#define OMAP4_GPIO_RISINGDETECT 0x0148
|
||||
#define OMAP4_GPIO_FALLINGDETECT 0x014c
|
||||
#define OMAP4_GPIO_DEBOUNCENABLE 0x0150
|
||||
#define OMAP4_GPIO_DEBOUNCINGTIME 0x0154
|
||||
#define OMAP4_GPIO_CLEARIRQENABLE1 0x0160
|
||||
#define OMAP4_GPIO_SETIRQENABLE1 0x0164
|
||||
#define OMAP4_GPIO_CLEARWKUENA 0x0180
|
||||
#define OMAP4_GPIO_SETWKUENA 0x0184
|
||||
#define OMAP4_GPIO_CLEARDATAOUT 0x0190
|
||||
#define OMAP4_GPIO_SETDATAOUT 0x0194
|
||||
|
||||
#define OMAP_MPUIO(nr) (OMAP_MAX_GPIO_LINES + (nr))
|
||||
#define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES)
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ obj-y += gpio.o
|
|||
obj-y += gpio-config.o
|
||||
obj-y += dev-asocdma.o
|
||||
|
||||
obj-$(CONFIG_SAMSUNG_GPIOLIB_4BIT) += gpiolib.o
|
||||
obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o
|
||||
|
||||
obj-$(CONFIG_SAMSUNG_IRQ_UART) += irq-uart.o
|
||||
|
|
|
@ -86,6 +86,30 @@ config GPIO_IT8761E
|
|||
help
|
||||
Say yes here to support GPIO functionality of IT8761E super I/O chip.
|
||||
|
||||
config GPIO_EXYNOS4
|
||||
bool "Samsung Exynos4 GPIO library support"
|
||||
default y if CPU_EXYNOS4210
|
||||
help
|
||||
Say yes here to support Samsung Exynos4 series SoCs GPIO library
|
||||
|
||||
config GPIO_PLAT_SAMSUNG
|
||||
bool "Samsung SoCs GPIO library support"
|
||||
default y if SAMSUNG_GPIOLIB_4BIT
|
||||
help
|
||||
Say yes here to support Samsung SoCs GPIO library
|
||||
|
||||
config GPIO_S5PC100
|
||||
bool "Samsung S5PC100 GPIO library support"
|
||||
default y if CPU_S5PC100
|
||||
help
|
||||
Say yes here to support Samsung S5PC100 SoCs GPIO library
|
||||
|
||||
config GPIO_S5PV210
|
||||
bool "Samsung S5PV210/S5PC110 GPIO library support"
|
||||
default y if CPU_S5PV210
|
||||
help
|
||||
Say yes here to support Samsung S5PV210/S5PC110 SoCs GPIO library
|
||||
|
||||
config GPIO_PL061
|
||||
bool "PrimeCell PL061 GPIO support"
|
||||
depends on ARM_AMBA
|
||||
|
@ -303,7 +327,7 @@ comment "PCI GPIO expanders:"
|
|||
|
||||
config GPIO_CS5535
|
||||
tristate "AMD CS5535/CS5536 GPIO support"
|
||||
depends on PCI && X86 && !CS5535_GPIO
|
||||
depends on PCI && X86 && !CS5535_GPIO && MFD_CS5535
|
||||
help
|
||||
The AMD CS5535 and CS5536 southbridges support 28 GPIO pins that
|
||||
can be used for quite a number of things. The CS5535/6 is found on
|
||||
|
@ -334,13 +358,19 @@ config GPIO_LANGWELL
|
|||
Say Y here to support Intel Langwell/Penwell GPIO.
|
||||
|
||||
config GPIO_PCH
|
||||
tristate "PCH GPIO of Intel Topcliff"
|
||||
tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7223 IOH GPIO"
|
||||
depends on PCI && X86
|
||||
help
|
||||
This driver is for PCH(Platform controller Hub) GPIO of Intel Topcliff
|
||||
which is an IOH(Input/Output Hub) for x86 embedded processor.
|
||||
This driver can access PCH GPIO device.
|
||||
|
||||
This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
|
||||
Output Hub), ML7223.
|
||||
ML7223 IOH is for MP(Media Phone) use.
|
||||
ML7223 is companion chip for Intel Atom E6xx series.
|
||||
ML7223 is completely compatible for Intel EG20T PCH.
|
||||
|
||||
config GPIO_ML_IOH
|
||||
tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support"
|
||||
depends on PCI
|
||||
|
|
|
@ -8,6 +8,10 @@ obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o
|
|||
obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o
|
||||
obj-$(CONFIG_GPIO_BASIC_MMIO_CORE) += basic_mmio_gpio.o
|
||||
obj-$(CONFIG_GPIO_BASIC_MMIO) += basic_mmio_gpio.o
|
||||
obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o
|
||||
obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o
|
||||
obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o
|
||||
obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o
|
||||
obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o
|
||||
obj-$(CONFIG_GPIO_MAX730X) += max730x.o
|
||||
obj-$(CONFIG_GPIO_MAX7300) += max7300.o
|
||||
|
@ -16,6 +20,7 @@ obj-$(CONFIG_GPIO_MAX732X) += max732x.o
|
|||
obj-$(CONFIG_GPIO_MC33880) += mc33880.o
|
||||
obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o
|
||||
obj-$(CONFIG_GPIO_74X164) += 74x164.o
|
||||
obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o
|
||||
obj-$(CONFIG_GPIO_PCA953X) += pca953x.o
|
||||
obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o
|
||||
obj-$(CONFIG_GPIO_PCH) += pch_gpio.o
|
||||
|
@ -34,6 +39,8 @@ obj-$(CONFIG_GPIO_WM831X) += wm831x-gpio.o
|
|||
obj-$(CONFIG_GPIO_WM8350) += wm8350-gpiolib.o
|
||||
obj-$(CONFIG_GPIO_WM8994) += wm8994-gpio.o
|
||||
obj-$(CONFIG_GPIO_SCH) += sch_gpio.o
|
||||
obj-$(CONFIG_MACH_U300) += gpio-u300.o
|
||||
obj-$(CONFIG_PLAT_NOMADIK) += gpio-nomadik.o
|
||||
obj-$(CONFIG_GPIO_RDC321X) += rdc321x-gpio.o
|
||||
obj-$(CONFIG_GPIO_JANZ_TTL) += janz-ttl.o
|
||||
obj-$(CONFIG_GPIO_SX150X) += sx150x.o
|
||||
|
|
|
@ -57,6 +57,7 @@ struct nmk_gpio_chip {
|
|||
u32 fwimsc;
|
||||
u32 slpm;
|
||||
u32 enabled;
|
||||
u32 pull_up;
|
||||
};
|
||||
|
||||
static struct nmk_gpio_chip *
|
||||
|
@ -103,16 +104,22 @@ static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
|
|||
u32 pdis;
|
||||
|
||||
pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS);
|
||||
if (pull == NMK_GPIO_PULL_NONE)
|
||||
if (pull == NMK_GPIO_PULL_NONE) {
|
||||
pdis |= bit;
|
||||
else
|
||||
nmk_chip->pull_up &= ~bit;
|
||||
} else {
|
||||
pdis &= ~bit;
|
||||
}
|
||||
|
||||
writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS);
|
||||
|
||||
if (pull == NMK_GPIO_PULL_UP)
|
||||
if (pull == NMK_GPIO_PULL_UP) {
|
||||
nmk_chip->pull_up |= bit;
|
||||
writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
|
||||
else if (pull == NMK_GPIO_PULL_DOWN)
|
||||
} else if (pull == NMK_GPIO_PULL_DOWN) {
|
||||
nmk_chip->pull_up &= ~bit;
|
||||
writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
|
||||
}
|
||||
}
|
||||
|
||||
static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
|
||||
|
@ -811,20 +818,43 @@ static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
|
|||
bool pull;
|
||||
u32 bit = 1 << i;
|
||||
|
||||
if (!label)
|
||||
continue;
|
||||
|
||||
is_out = readl(nmk_chip->addr + NMK_GPIO_DIR) & bit;
|
||||
pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit);
|
||||
mode = nmk_gpio_get_mode(gpio);
|
||||
seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s",
|
||||
gpio, label,
|
||||
gpio, label ?: "(none)",
|
||||
is_out ? "out" : "in ",
|
||||
chip->get
|
||||
? (chip->get(chip, i) ? "hi" : "lo")
|
||||
: "? ",
|
||||
(mode < 0) ? "unknown" : modes[mode],
|
||||
pull ? "pull" : "none");
|
||||
|
||||
if (label && !is_out) {
|
||||
int irq = gpio_to_irq(gpio);
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
|
||||
/* This races with request_irq(), set_irq_type(),
|
||||
* and set_irq_wake() ... but those are "rare".
|
||||
*/
|
||||
if (irq >= 0 && desc->action) {
|
||||
char *trigger;
|
||||
u32 bitmask = nmk_gpio_get_bitmask(gpio);
|
||||
|
||||
if (nmk_chip->edge_rising & bitmask)
|
||||
trigger = "edge-rising";
|
||||
else if (nmk_chip->edge_falling & bitmask)
|
||||
trigger = "edge-falling";
|
||||
else
|
||||
trigger = "edge-undefined";
|
||||
|
||||
seq_printf(s, " irq-%d %s%s",
|
||||
irq, trigger,
|
||||
irqd_is_wakeup_set(&desc->irq_data)
|
||||
? " wakeup" : "");
|
||||
}
|
||||
}
|
||||
|
||||
seq_printf(s, "\n");
|
||||
}
|
||||
}
|
||||
|
@ -898,6 +928,25 @@ void nmk_gpio_wakeups_resume(void)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the pull up/pull down status.
|
||||
* A bit set in 'pull_up' means that pull up
|
||||
* is selected if pull is enabled in PDIS register.
|
||||
* Note: only pull up/down set via this driver can
|
||||
* be detected due to HW limitations.
|
||||
*/
|
||||
void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up)
|
||||
{
|
||||
if (gpio_bank < NUM_BANKS) {
|
||||
struct nmk_gpio_chip *chip = nmk_gpio_chips[gpio_bank];
|
||||
|
||||
if (!chip)
|
||||
return;
|
||||
|
||||
*pull_up = chip->pull_up;
|
||||
}
|
||||
}
|
||||
|
||||
static int __devinit nmk_gpio_probe(struct platform_device *dev)
|
||||
{
|
||||
struct nmk_gpio_platform_data *pdata = dev->dev.platform_data;
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/arch/arm/plat-omap/gpio.c
|
||||
*
|
||||
* Support functions for OMAP GPIO
|
||||
*
|
||||
* Copyright (C) 2003-2005 Nokia Corporation
|
||||
|
@ -30,109 +28,6 @@
|
|||
#include <mach/gpio.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
/*
|
||||
* OMAP1510 GPIO registers
|
||||
*/
|
||||
#define OMAP1510_GPIO_DATA_INPUT 0x00
|
||||
#define OMAP1510_GPIO_DATA_OUTPUT 0x04
|
||||
#define OMAP1510_GPIO_DIR_CONTROL 0x08
|
||||
#define OMAP1510_GPIO_INT_CONTROL 0x0c
|
||||
#define OMAP1510_GPIO_INT_MASK 0x10
|
||||
#define OMAP1510_GPIO_INT_STATUS 0x14
|
||||
#define OMAP1510_GPIO_PIN_CONTROL 0x18
|
||||
|
||||
#define OMAP1510_IH_GPIO_BASE 64
|
||||
|
||||
/*
|
||||
* OMAP1610 specific GPIO registers
|
||||
*/
|
||||
#define OMAP1610_GPIO_REVISION 0x0000
|
||||
#define OMAP1610_GPIO_SYSCONFIG 0x0010
|
||||
#define OMAP1610_GPIO_SYSSTATUS 0x0014
|
||||
#define OMAP1610_GPIO_IRQSTATUS1 0x0018
|
||||
#define OMAP1610_GPIO_IRQENABLE1 0x001c
|
||||
#define OMAP1610_GPIO_WAKEUPENABLE 0x0028
|
||||
#define OMAP1610_GPIO_DATAIN 0x002c
|
||||
#define OMAP1610_GPIO_DATAOUT 0x0030
|
||||
#define OMAP1610_GPIO_DIRECTION 0x0034
|
||||
#define OMAP1610_GPIO_EDGE_CTRL1 0x0038
|
||||
#define OMAP1610_GPIO_EDGE_CTRL2 0x003c
|
||||
#define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c
|
||||
#define OMAP1610_GPIO_CLEAR_WAKEUPENA 0x00a8
|
||||
#define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0
|
||||
#define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc
|
||||
#define OMAP1610_GPIO_SET_WAKEUPENA 0x00e8
|
||||
#define OMAP1610_GPIO_SET_DATAOUT 0x00f0
|
||||
|
||||
/*
|
||||
* OMAP7XX specific GPIO registers
|
||||
*/
|
||||
#define OMAP7XX_GPIO_DATA_INPUT 0x00
|
||||
#define OMAP7XX_GPIO_DATA_OUTPUT 0x04
|
||||
#define OMAP7XX_GPIO_DIR_CONTROL 0x08
|
||||
#define OMAP7XX_GPIO_INT_CONTROL 0x0c
|
||||
#define OMAP7XX_GPIO_INT_MASK 0x10
|
||||
#define OMAP7XX_GPIO_INT_STATUS 0x14
|
||||
|
||||
/*
|
||||
* omap2+ specific GPIO registers
|
||||
*/
|
||||
#define OMAP24XX_GPIO_REVISION 0x0000
|
||||
#define OMAP24XX_GPIO_IRQSTATUS1 0x0018
|
||||
#define OMAP24XX_GPIO_IRQSTATUS2 0x0028
|
||||
#define OMAP24XX_GPIO_IRQENABLE2 0x002c
|
||||
#define OMAP24XX_GPIO_IRQENABLE1 0x001c
|
||||
#define OMAP24XX_GPIO_WAKE_EN 0x0020
|
||||
#define OMAP24XX_GPIO_CTRL 0x0030
|
||||
#define OMAP24XX_GPIO_OE 0x0034
|
||||
#define OMAP24XX_GPIO_DATAIN 0x0038
|
||||
#define OMAP24XX_GPIO_DATAOUT 0x003c
|
||||
#define OMAP24XX_GPIO_LEVELDETECT0 0x0040
|
||||
#define OMAP24XX_GPIO_LEVELDETECT1 0x0044
|
||||
#define OMAP24XX_GPIO_RISINGDETECT 0x0048
|
||||
#define OMAP24XX_GPIO_FALLINGDETECT 0x004c
|
||||
#define OMAP24XX_GPIO_DEBOUNCE_EN 0x0050
|
||||
#define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0054
|
||||
#define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060
|
||||
#define OMAP24XX_GPIO_SETIRQENABLE1 0x0064
|
||||
#define OMAP24XX_GPIO_CLEARWKUENA 0x0080
|
||||
#define OMAP24XX_GPIO_SETWKUENA 0x0084
|
||||
#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090
|
||||
#define OMAP24XX_GPIO_SETDATAOUT 0x0094
|
||||
|
||||
#define OMAP4_GPIO_REVISION 0x0000
|
||||
#define OMAP4_GPIO_EOI 0x0020
|
||||
#define OMAP4_GPIO_IRQSTATUSRAW0 0x0024
|
||||
#define OMAP4_GPIO_IRQSTATUSRAW1 0x0028
|
||||
#define OMAP4_GPIO_IRQSTATUS0 0x002c
|
||||
#define OMAP4_GPIO_IRQSTATUS1 0x0030
|
||||
#define OMAP4_GPIO_IRQSTATUSSET0 0x0034
|
||||
#define OMAP4_GPIO_IRQSTATUSSET1 0x0038
|
||||
#define OMAP4_GPIO_IRQSTATUSCLR0 0x003c
|
||||
#define OMAP4_GPIO_IRQSTATUSCLR1 0x0040
|
||||
#define OMAP4_GPIO_IRQWAKEN0 0x0044
|
||||
#define OMAP4_GPIO_IRQWAKEN1 0x0048
|
||||
#define OMAP4_GPIO_IRQENABLE1 0x011c
|
||||
#define OMAP4_GPIO_WAKE_EN 0x0120
|
||||
#define OMAP4_GPIO_IRQSTATUS2 0x0128
|
||||
#define OMAP4_GPIO_IRQENABLE2 0x012c
|
||||
#define OMAP4_GPIO_CTRL 0x0130
|
||||
#define OMAP4_GPIO_OE 0x0134
|
||||
#define OMAP4_GPIO_DATAIN 0x0138
|
||||
#define OMAP4_GPIO_DATAOUT 0x013c
|
||||
#define OMAP4_GPIO_LEVELDETECT0 0x0140
|
||||
#define OMAP4_GPIO_LEVELDETECT1 0x0144
|
||||
#define OMAP4_GPIO_RISINGDETECT 0x0148
|
||||
#define OMAP4_GPIO_FALLINGDETECT 0x014c
|
||||
#define OMAP4_GPIO_DEBOUNCENABLE 0x0150
|
||||
#define OMAP4_GPIO_DEBOUNCINGTIME 0x0154
|
||||
#define OMAP4_GPIO_CLEARIRQENABLE1 0x0160
|
||||
#define OMAP4_GPIO_SETIRQENABLE1 0x0164
|
||||
#define OMAP4_GPIO_CLEARWKUENA 0x0180
|
||||
#define OMAP4_GPIO_SETWKUENA 0x0184
|
||||
#define OMAP4_GPIO_CLEARDATAOUT 0x0190
|
||||
#define OMAP4_GPIO_SETDATAOUT 0x0194
|
||||
|
||||
struct gpio_bank {
|
||||
unsigned long pbase;
|
||||
void __iomem *base;
|
|
@ -1296,7 +1296,7 @@ EXPORT_SYMBOL_GPL(gpio_request_one);
|
|||
* @array: array of the 'struct gpio'
|
||||
* @num: how many GPIOs in the array
|
||||
*/
|
||||
int gpio_request_array(struct gpio *array, size_t num)
|
||||
int gpio_request_array(const struct gpio *array, size_t num)
|
||||
{
|
||||
int i, err;
|
||||
|
||||
|
@ -1319,7 +1319,7 @@ EXPORT_SYMBOL_GPL(gpio_request_array);
|
|||
* @array: array of the 'struct gpio'
|
||||
* @num: how many GPIOs in the array
|
||||
*/
|
||||
void gpio_free_array(struct gpio *array, size_t num)
|
||||
void gpio_free_array(const struct gpio *array, size_t num)
|
||||
{
|
||||
while (num--)
|
||||
gpio_free((array++)->gpio);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
/*
|
||||
* Langwell chip has 64 pins and thus there are 2 32bit registers to control
|
||||
|
@ -63,6 +64,7 @@ struct lnw_gpio {
|
|||
void *reg_base;
|
||||
spinlock_t lock;
|
||||
unsigned irq_base;
|
||||
struct pci_dev *pdev;
|
||||
};
|
||||
|
||||
static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset,
|
||||
|
@ -104,11 +106,18 @@ static int lnw_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
|||
u32 value;
|
||||
unsigned long flags;
|
||||
|
||||
if (lnw->pdev)
|
||||
pm_runtime_get(&lnw->pdev->dev);
|
||||
|
||||
spin_lock_irqsave(&lnw->lock, flags);
|
||||
value = readl(gpdr);
|
||||
value &= ~BIT(offset % 32);
|
||||
writel(value, gpdr);
|
||||
spin_unlock_irqrestore(&lnw->lock, flags);
|
||||
|
||||
if (lnw->pdev)
|
||||
pm_runtime_put(&lnw->pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -120,11 +129,19 @@ static int lnw_gpio_direction_output(struct gpio_chip *chip,
|
|||
unsigned long flags;
|
||||
|
||||
lnw_gpio_set(chip, offset, value);
|
||||
|
||||
if (lnw->pdev)
|
||||
pm_runtime_get(&lnw->pdev->dev);
|
||||
|
||||
spin_lock_irqsave(&lnw->lock, flags);
|
||||
value = readl(gpdr);
|
||||
value |= BIT(offset % 32);
|
||||
writel(value, gpdr);
|
||||
spin_unlock_irqrestore(&lnw->lock, flags);
|
||||
|
||||
if (lnw->pdev)
|
||||
pm_runtime_put(&lnw->pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -145,6 +162,10 @@ static int lnw_irq_type(struct irq_data *d, unsigned type)
|
|||
|
||||
if (gpio >= lnw->chip.ngpio)
|
||||
return -EINVAL;
|
||||
|
||||
if (lnw->pdev)
|
||||
pm_runtime_get(&lnw->pdev->dev);
|
||||
|
||||
spin_lock_irqsave(&lnw->lock, flags);
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
value = readl(grer) | BIT(gpio % 32);
|
||||
|
@ -159,6 +180,9 @@ static int lnw_irq_type(struct irq_data *d, unsigned type)
|
|||
writel(value, gfer);
|
||||
spin_unlock_irqrestore(&lnw->lock, flags);
|
||||
|
||||
if (lnw->pdev)
|
||||
pm_runtime_put(&lnw->pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -211,6 +235,39 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
|
|||
chip->irq_eoi(data);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int lnw_gpio_runtime_resume(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lnw_gpio_runtime_suspend(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lnw_gpio_runtime_idle(struct device *dev)
|
||||
{
|
||||
int err = pm_schedule_suspend(dev, 500);
|
||||
|
||||
if (!err)
|
||||
return 0;
|
||||
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
#else
|
||||
#define lnw_gpio_runtime_suspend NULL
|
||||
#define lnw_gpio_runtime_resume NULL
|
||||
#define lnw_gpio_runtime_idle NULL
|
||||
#endif
|
||||
|
||||
static const struct dev_pm_ops lnw_gpio_pm_ops = {
|
||||
.runtime_suspend = lnw_gpio_runtime_suspend,
|
||||
.runtime_resume = lnw_gpio_runtime_resume,
|
||||
.runtime_idle = lnw_gpio_runtime_idle,
|
||||
};
|
||||
|
||||
static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
|
@ -270,6 +327,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
|
|||
lnw->chip.base = gpio_base;
|
||||
lnw->chip.ngpio = id->driver_data;
|
||||
lnw->chip.can_sleep = 0;
|
||||
lnw->pdev = pdev;
|
||||
pci_set_drvdata(pdev, lnw);
|
||||
retval = gpiochip_add(&lnw->chip);
|
||||
if (retval) {
|
||||
|
@ -285,6 +343,10 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
|
|||
}
|
||||
|
||||
spin_lock_init(&lnw->lock);
|
||||
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
pm_runtime_allow(&pdev->dev);
|
||||
|
||||
goto done;
|
||||
err5:
|
||||
kfree(lnw);
|
||||
|
@ -302,6 +364,9 @@ static struct pci_driver lnw_gpio_driver = {
|
|||
.name = "langwell_gpio",
|
||||
.id_table = lnw_gpio_ids,
|
||||
.probe = lnw_gpio_probe,
|
||||
.driver = {
|
||||
.pm = &lnw_gpio_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -24,33 +24,46 @@
|
|||
#include <linux/of_gpio.h>
|
||||
#endif
|
||||
|
||||
#define PCA953X_INPUT 0
|
||||
#define PCA953X_OUTPUT 1
|
||||
#define PCA953X_INVERT 2
|
||||
#define PCA953X_DIRECTION 3
|
||||
#define PCA953X_INPUT 0
|
||||
#define PCA953X_OUTPUT 1
|
||||
#define PCA953X_INVERT 2
|
||||
#define PCA953X_DIRECTION 3
|
||||
|
||||
#define PCA953X_GPIOS 0x00FF
|
||||
#define PCA953X_INT 0x0100
|
||||
#define PCA957X_IN 0
|
||||
#define PCA957X_INVRT 1
|
||||
#define PCA957X_BKEN 2
|
||||
#define PCA957X_PUPD 3
|
||||
#define PCA957X_CFG 4
|
||||
#define PCA957X_OUT 5
|
||||
#define PCA957X_MSK 6
|
||||
#define PCA957X_INTS 7
|
||||
|
||||
#define PCA_GPIO_MASK 0x00FF
|
||||
#define PCA_INT 0x0100
|
||||
#define PCA953X_TYPE 0x1000
|
||||
#define PCA957X_TYPE 0x2000
|
||||
|
||||
static const struct i2c_device_id pca953x_id[] = {
|
||||
{ "pca9534", 8 | PCA953X_INT, },
|
||||
{ "pca9535", 16 | PCA953X_INT, },
|
||||
{ "pca9536", 4, },
|
||||
{ "pca9537", 4 | PCA953X_INT, },
|
||||
{ "pca9538", 8 | PCA953X_INT, },
|
||||
{ "pca9539", 16 | PCA953X_INT, },
|
||||
{ "pca9554", 8 | PCA953X_INT, },
|
||||
{ "pca9555", 16 | PCA953X_INT, },
|
||||
{ "pca9556", 8, },
|
||||
{ "pca9557", 8, },
|
||||
{ "pca9534", 8 | PCA953X_TYPE | PCA_INT, },
|
||||
{ "pca9535", 16 | PCA953X_TYPE | PCA_INT, },
|
||||
{ "pca9536", 4 | PCA953X_TYPE, },
|
||||
{ "pca9537", 4 | PCA953X_TYPE | PCA_INT, },
|
||||
{ "pca9538", 8 | PCA953X_TYPE | PCA_INT, },
|
||||
{ "pca9539", 16 | PCA953X_TYPE | PCA_INT, },
|
||||
{ "pca9554", 8 | PCA953X_TYPE | PCA_INT, },
|
||||
{ "pca9555", 16 | PCA953X_TYPE | PCA_INT, },
|
||||
{ "pca9556", 8 | PCA953X_TYPE, },
|
||||
{ "pca9557", 8 | PCA953X_TYPE, },
|
||||
{ "pca9574", 8 | PCA957X_TYPE | PCA_INT, },
|
||||
{ "pca9575", 16 | PCA957X_TYPE | PCA_INT, },
|
||||
|
||||
{ "max7310", 8, },
|
||||
{ "max7312", 16 | PCA953X_INT, },
|
||||
{ "max7313", 16 | PCA953X_INT, },
|
||||
{ "max7315", 8 | PCA953X_INT, },
|
||||
{ "pca6107", 8 | PCA953X_INT, },
|
||||
{ "tca6408", 8 | PCA953X_INT, },
|
||||
{ "tca6416", 16 | PCA953X_INT, },
|
||||
{ "max7310", 8 | PCA953X_TYPE, },
|
||||
{ "max7312", 16 | PCA953X_TYPE | PCA_INT, },
|
||||
{ "max7313", 16 | PCA953X_TYPE | PCA_INT, },
|
||||
{ "max7315", 8 | PCA953X_TYPE | PCA_INT, },
|
||||
{ "pca6107", 8 | PCA953X_TYPE | PCA_INT, },
|
||||
{ "tca6408", 8 | PCA953X_TYPE | PCA_INT, },
|
||||
{ "tca6416", 16 | PCA953X_TYPE | PCA_INT, },
|
||||
/* NYET: { "tca6424", 24, }, */
|
||||
{ }
|
||||
};
|
||||
|
@ -75,16 +88,32 @@ struct pca953x_chip {
|
|||
struct pca953x_platform_data *dyn_pdata;
|
||||
struct gpio_chip gpio_chip;
|
||||
const char *const *names;
|
||||
int chip_type;
|
||||
};
|
||||
|
||||
static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (chip->gpio_chip.ngpio <= 8)
|
||||
ret = i2c_smbus_write_byte_data(chip->client, reg, val);
|
||||
else
|
||||
ret = i2c_smbus_write_word_data(chip->client, reg << 1, val);
|
||||
else {
|
||||
switch (chip->chip_type) {
|
||||
case PCA953X_TYPE:
|
||||
ret = i2c_smbus_write_word_data(chip->client,
|
||||
reg << 1, val);
|
||||
break;
|
||||
case PCA957X_TYPE:
|
||||
ret = i2c_smbus_write_byte_data(chip->client, reg << 1,
|
||||
val & 0xff);
|
||||
if (ret < 0)
|
||||
break;
|
||||
ret = i2c_smbus_write_byte_data(chip->client,
|
||||
(reg << 1) + 1,
|
||||
(val & 0xff00) >> 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(&chip->client->dev, "failed writing register\n");
|
||||
|
@ -116,13 +145,22 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
|
|||
{
|
||||
struct pca953x_chip *chip;
|
||||
uint16_t reg_val;
|
||||
int ret;
|
||||
int ret, offset = 0;
|
||||
|
||||
chip = container_of(gc, struct pca953x_chip, gpio_chip);
|
||||
|
||||
mutex_lock(&chip->i2c_lock);
|
||||
reg_val = chip->reg_direction | (1u << off);
|
||||
ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
|
||||
|
||||
switch (chip->chip_type) {
|
||||
case PCA953X_TYPE:
|
||||
offset = PCA953X_DIRECTION;
|
||||
break;
|
||||
case PCA957X_TYPE:
|
||||
offset = PCA957X_CFG;
|
||||
break;
|
||||
}
|
||||
ret = pca953x_write_reg(chip, offset, reg_val);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
|
@ -138,7 +176,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
|
|||
{
|
||||
struct pca953x_chip *chip;
|
||||
uint16_t reg_val;
|
||||
int ret;
|
||||
int ret, offset = 0;
|
||||
|
||||
chip = container_of(gc, struct pca953x_chip, gpio_chip);
|
||||
|
||||
|
@ -149,7 +187,15 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
|
|||
else
|
||||
reg_val = chip->reg_output & ~(1u << off);
|
||||
|
||||
ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
|
||||
switch (chip->chip_type) {
|
||||
case PCA953X_TYPE:
|
||||
offset = PCA953X_OUTPUT;
|
||||
break;
|
||||
case PCA957X_TYPE:
|
||||
offset = PCA957X_OUT;
|
||||
break;
|
||||
}
|
||||
ret = pca953x_write_reg(chip, offset, reg_val);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
|
@ -157,7 +203,15 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
|
|||
|
||||
/* then direction */
|
||||
reg_val = chip->reg_direction & ~(1u << off);
|
||||
ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
|
||||
switch (chip->chip_type) {
|
||||
case PCA953X_TYPE:
|
||||
offset = PCA953X_DIRECTION;
|
||||
break;
|
||||
case PCA957X_TYPE:
|
||||
offset = PCA957X_CFG;
|
||||
break;
|
||||
}
|
||||
ret = pca953x_write_reg(chip, offset, reg_val);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
|
@ -172,12 +226,20 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
|
|||
{
|
||||
struct pca953x_chip *chip;
|
||||
uint16_t reg_val;
|
||||
int ret;
|
||||
int ret, offset = 0;
|
||||
|
||||
chip = container_of(gc, struct pca953x_chip, gpio_chip);
|
||||
|
||||
mutex_lock(&chip->i2c_lock);
|
||||
ret = pca953x_read_reg(chip, PCA953X_INPUT, ®_val);
|
||||
switch (chip->chip_type) {
|
||||
case PCA953X_TYPE:
|
||||
offset = PCA953X_INPUT;
|
||||
break;
|
||||
case PCA957X_TYPE:
|
||||
offset = PCA957X_IN;
|
||||
break;
|
||||
}
|
||||
ret = pca953x_read_reg(chip, offset, ®_val);
|
||||
mutex_unlock(&chip->i2c_lock);
|
||||
if (ret < 0) {
|
||||
/* NOTE: diagnostic already emitted; that's all we should
|
||||
|
@ -194,7 +256,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
|
|||
{
|
||||
struct pca953x_chip *chip;
|
||||
uint16_t reg_val;
|
||||
int ret;
|
||||
int ret, offset = 0;
|
||||
|
||||
chip = container_of(gc, struct pca953x_chip, gpio_chip);
|
||||
|
||||
|
@ -204,7 +266,15 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
|
|||
else
|
||||
reg_val = chip->reg_output & ~(1u << off);
|
||||
|
||||
ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
|
||||
switch (chip->chip_type) {
|
||||
case PCA953X_TYPE:
|
||||
offset = PCA953X_OUTPUT;
|
||||
break;
|
||||
case PCA957X_TYPE:
|
||||
offset = PCA957X_OUT;
|
||||
break;
|
||||
}
|
||||
ret = pca953x_write_reg(chip, offset, reg_val);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
|
@ -322,9 +392,17 @@ static uint16_t pca953x_irq_pending(struct pca953x_chip *chip)
|
|||
uint16_t old_stat;
|
||||
uint16_t pending;
|
||||
uint16_t trigger;
|
||||
int ret;
|
||||
int ret, offset = 0;
|
||||
|
||||
ret = pca953x_read_reg(chip, PCA953X_INPUT, &cur_stat);
|
||||
switch (chip->chip_type) {
|
||||
case PCA953X_TYPE:
|
||||
offset = PCA953X_INPUT;
|
||||
break;
|
||||
case PCA957X_TYPE:
|
||||
offset = PCA957X_IN;
|
||||
break;
|
||||
}
|
||||
ret = pca953x_read_reg(chip, offset, &cur_stat);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
|
@ -372,14 +450,21 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
|
|||
{
|
||||
struct i2c_client *client = chip->client;
|
||||
struct pca953x_platform_data *pdata = client->dev.platform_data;
|
||||
int ret;
|
||||
int ret, offset = 0;
|
||||
|
||||
if (pdata->irq_base != -1
|
||||
&& (id->driver_data & PCA953X_INT)) {
|
||||
&& (id->driver_data & PCA_INT)) {
|
||||
int lvl;
|
||||
|
||||
ret = pca953x_read_reg(chip, PCA953X_INPUT,
|
||||
&chip->irq_stat);
|
||||
switch (chip->chip_type) {
|
||||
case PCA953X_TYPE:
|
||||
offset = PCA953X_INPUT;
|
||||
break;
|
||||
case PCA957X_TYPE:
|
||||
offset = PCA957X_IN;
|
||||
break;
|
||||
}
|
||||
ret = pca953x_read_reg(chip, offset, &chip->irq_stat);
|
||||
if (ret)
|
||||
goto out_failed;
|
||||
|
||||
|
@ -439,7 +524,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
|
|||
struct i2c_client *client = chip->client;
|
||||
struct pca953x_platform_data *pdata = client->dev.platform_data;
|
||||
|
||||
if (pdata->irq_base != -1 && (id->driver_data & PCA953X_INT))
|
||||
if (pdata->irq_base != -1 && (id->driver_data & PCA_INT))
|
||||
dev_warn(&client->dev, "interrupt support not compiled in\n");
|
||||
|
||||
return 0;
|
||||
|
@ -499,12 +584,65 @@ pca953x_get_alt_pdata(struct i2c_client *client)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int __devinit device_pca953x_init(struct pca953x_chip *chip, int invert)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = pca953x_read_reg(chip, PCA953X_DIRECTION,
|
||||
&chip->reg_direction);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* set platform specific polarity inversion */
|
||||
ret = pca953x_write_reg(chip, PCA953X_INVERT, invert);
|
||||
if (ret)
|
||||
goto out;
|
||||
return 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devinit device_pca957x_init(struct pca953x_chip *chip, int invert)
|
||||
{
|
||||
int ret;
|
||||
uint16_t val = 0;
|
||||
|
||||
/* Let every port in proper state, that could save power */
|
||||
pca953x_write_reg(chip, PCA957X_PUPD, 0x0);
|
||||
pca953x_write_reg(chip, PCA957X_CFG, 0xffff);
|
||||
pca953x_write_reg(chip, PCA957X_OUT, 0x0);
|
||||
|
||||
ret = pca953x_read_reg(chip, PCA957X_IN, &val);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = pca953x_read_reg(chip, PCA957X_OUT, &chip->reg_output);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = pca953x_read_reg(chip, PCA957X_CFG, &chip->reg_direction);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* set platform specific polarity inversion */
|
||||
pca953x_write_reg(chip, PCA957X_INVRT, invert);
|
||||
|
||||
/* To enable register 6, 7 to controll pull up and pull down */
|
||||
pca953x_write_reg(chip, PCA957X_BKEN, 0x202);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devinit pca953x_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct pca953x_platform_data *pdata;
|
||||
struct pca953x_chip *chip;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
|
||||
if (chip == NULL)
|
||||
|
@ -531,25 +669,20 @@ static int __devinit pca953x_probe(struct i2c_client *client,
|
|||
chip->gpio_start = pdata->gpio_base;
|
||||
|
||||
chip->names = pdata->names;
|
||||
chip->chip_type = id->driver_data & (PCA953X_TYPE | PCA957X_TYPE);
|
||||
|
||||
mutex_init(&chip->i2c_lock);
|
||||
|
||||
/* initialize cached registers from their original values.
|
||||
* we can't share this chip with another i2c master.
|
||||
*/
|
||||
pca953x_setup_gpio(chip, id->driver_data & PCA953X_GPIOS);
|
||||
pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK);
|
||||
|
||||
ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
|
||||
if (ret)
|
||||
goto out_failed;
|
||||
|
||||
ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction);
|
||||
if (ret)
|
||||
goto out_failed;
|
||||
|
||||
/* set platform specific polarity inversion */
|
||||
ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert);
|
||||
if (ret)
|
||||
if (chip->chip_type == PCA953X_TYPE)
|
||||
device_pca953x_init(chip, pdata->invert);
|
||||
else if (chip->chip_type == PCA957X_TYPE)
|
||||
device_pca957x_init(chip, pdata->invert);
|
||||
else
|
||||
goto out_failed;
|
||||
|
||||
ret = pca953x_irq_setup(chip, id);
|
||||
|
|
|
@ -283,8 +283,10 @@ static int pch_gpio_resume(struct pci_dev *pdev)
|
|||
#define pch_gpio_resume NULL
|
||||
#endif
|
||||
|
||||
#define PCI_VENDOR_ID_ROHM 0x10DB
|
||||
static DEFINE_PCI_DEVICE_TABLE(pch_gpio_pcidev_id) = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8014) },
|
||||
{ 0, }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id);
|
||||
|
|
|
@ -35,9 +35,9 @@
|
|||
* platform data and other tables.
|
||||
*/
|
||||
|
||||
static inline int gpio_is_valid(int number)
|
||||
static inline bool gpio_is_valid(int number)
|
||||
{
|
||||
return ((unsigned)number) < ARCH_NR_GPIOS;
|
||||
return number >= 0 && number < ARCH_NR_GPIOS;
|
||||
}
|
||||
|
||||
struct device;
|
||||
|
@ -193,8 +193,8 @@ struct gpio {
|
|||
};
|
||||
|
||||
extern int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
|
||||
extern int gpio_request_array(struct gpio *array, size_t num);
|
||||
extern void gpio_free_array(struct gpio *array, size_t num);
|
||||
extern int gpio_request_array(const struct gpio *array, size_t num);
|
||||
extern void gpio_free_array(const struct gpio *array, size_t num);
|
||||
|
||||
#ifdef CONFIG_GPIO_SYSFS
|
||||
|
||||
|
@ -212,7 +212,7 @@ extern void gpio_unexport(unsigned gpio);
|
|||
|
||||
#else /* !CONFIG_GPIOLIB */
|
||||
|
||||
static inline int gpio_is_valid(int number)
|
||||
static inline bool gpio_is_valid(int number)
|
||||
{
|
||||
/* only non-negative numbers are valid */
|
||||
return number >= 0;
|
||||
|
|
|
@ -25,9 +25,9 @@ struct gpio_chip;
|
|||
* warning when something is wrongly called.
|
||||
*/
|
||||
|
||||
static inline int gpio_is_valid(int number)
|
||||
static inline bool gpio_is_valid(int number)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int gpio_request(unsigned gpio, const char *label)
|
||||
|
@ -41,7 +41,7 @@ static inline int gpio_request_one(unsigned gpio,
|
|||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int gpio_request_array(struct gpio *array, size_t num)
|
||||
static inline int gpio_request_array(const struct gpio *array, size_t num)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ static inline void gpio_free(unsigned gpio)
|
|||
WARN_ON(1);
|
||||
}
|
||||
|
||||
static inline void gpio_free_array(struct gpio *array, size_t num)
|
||||
static inline void gpio_free_array(const struct gpio *array, size_t num)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
|
|
Loading…
Reference in a new issue