summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2011-05-13 10:51:48 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2011-05-13 10:51:48 +1000
commit47d86dcab7cd75c75bdad04c56ca093d71f291f0 (patch)
tree6fe388ef3edc32f0e3871a17589f542f5b685c46 /include
parent1fd65d2264d86296e73e3aae62c8c2171783cee6 (diff)
parent417ffd2681947603a1a60372fd02406890fb120f (diff)
Merge remote-tracking branch 'ux500-core/ux500-core'
Conflicts: drivers/gpio/nomadik-gpio.c
Diffstat (limited to 'include')
-rw-r--r--include/asm-generic/gpio.h8
-rw-r--r--include/linux/gpio.h61
-rw-r--r--include/linux/gpio/nomadik.h291
-rw-r--r--include/linux/gpio/u300.h32
4 files changed, 390 insertions, 2 deletions
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index ff5c66080c8c..ce16e70cb8f6 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -61,6 +61,7 @@ struct device_node;
* @set: assigns output value for signal "offset"
* @to_irq: optional hook supporting non-static gpio_to_irq() mappings;
* implementation may not sleep
+ * @config: set/get a certain custom parameter for the GPIO
* @dbg_show: optional routine to show contents in debugfs; default code
* will be used when this is omitted, but custom code can show extra
* state (such as pullup/pulldown configuration).
@@ -105,12 +106,14 @@ struct gpio_chip {
unsigned offset, int value);
int (*set_debounce)(struct gpio_chip *chip,
unsigned offset, unsigned debounce);
-
void (*set)(struct gpio_chip *chip,
unsigned offset, int value);
-
int (*to_irq)(struct gpio_chip *chip,
unsigned offset);
+ int (*config)(struct gpio_chip *chip,
+ unsigned offset,
+ u16 param,
+ unsigned long *data);
void (*dbg_show)(struct seq_file *s,
struct gpio_chip *chip);
@@ -158,6 +161,7 @@ extern int gpio_set_debounce(unsigned gpio, unsigned debounce);
extern int gpio_get_value_cansleep(unsigned gpio);
extern void gpio_set_value_cansleep(unsigned gpio, int value);
+extern int gpio_config(unsigned gpio, u16 param, unsigned long *data);
/* A platform's <asm/gpio.h> code may want to inline the I/O calls when
* the GPIO is constant and refers to some always-present controller,
diff --git a/include/linux/gpio.h b/include/linux/gpio.h
index 32720baf70f1..fa92e50f54b7 100644
--- a/include/linux/gpio.h
+++ b/include/linux/gpio.h
@@ -3,6 +3,60 @@
/* see Documentation/gpio.txt */
+/*
+ * Bias modes for GPIOs - if you have more biases, add them here or provide
+ * custom enumerators for your driver if you find they are not generally
+ * useful.
+ *
+ * GPIO_CONFIG_BIAS_UNKNOWN: this bias mode is not known to us
+ * GPIO_CONFIG_BIAS_FLOAT: no specific bias, the GPIO will float or state
+ * is not controlled by software
+ * GPIO_CONFIG_BIAS_PULL_UP: the GPIO will be pulled up (usually with high
+ * impedance to VDD)
+ * GPIO_CONFIG_BIAS_PULL_DOWN: the GPIO will be pulled down (usually with high
+ * impedance to GROUND)
+ * GPIO_BIAS_HIGH: the GPIO will be wired high, connected to VDD
+ * GPIO_BIAS_GROUND: the GPIO will be grounded, connected to GROUND
+ */
+#define GPIO_CONFIG_BIAS_UNKNOWN 0x1000
+#define GPIO_CONFIG_BIAS_FLOAT 0x1001
+#define GPIO_CONFIG_BIAS_PULL_UP 0x1002
+#define GPIO_CONFIG_BIAS_PULL_DOWN 0x1003
+#define GPIO_CONFIG_BIAS_HIGH 0x1004
+#define GPIO_CONFIG_BIAS_GROUND 0x1005
+
+/*
+ * Drive modes for GPIOs (output) - if you have more custom modes either
+ * add them here or keep them to your driver if you think they are not
+ * generally useful.
+ *
+ * GPIO_CONFIG_DRIVE_UNKNOWN: we don't know the drive mode of this GPIO, for
+ * example since it is controlled by hardware or the information is not
+ * accessible but we need a meaningful enumerator in e.g. initialization
+ * code
+ * GPIO_CONFIG_DRIVE_PUSH_PULL: the GPIO will be driven actively high and
+ * low, this is the most typical case and is typically achieved with two
+ * active transistors on the output
+ * GPIO_CONFIG_DRIVE_OPEN_DRAIN: the GPIO will be driven with open drain (open
+ * collector) which means it is usually wired with other output ports
+ * which are then pulled up with an external resistor
+ * GPIO_CONFIG_DRIVE_OPEN_SOURCE: the GPIO will be driven with open drain
+ * (open emitter) which is the same as open drain mutatis mutandis but
+ * pulled to ground
+ * GPIO_CONFIG_DRIVE_OFF: the GPIO pin is set to inactive mode, off
+ */
+#define GPIO_CONFIG_DRIVE_UNKNOWN 0x2010
+#define GPIO_CONFIG_DRIVE_PUSH_PULL 0x2011
+#define GPIO_CONFIG_DRIVE_OPEN_DRAIN 0x2012
+#define GPIO_CONFIG_DRIVE_OPEN_SOURCE 0x2013
+#define GPIO_CONFIG_DRIVE_OFF 0x2014
+
+/*
+ * From this value on, the configuration commands are custom and shall be
+ * defined in the header file for your specific GPIO driver.
+ */
+#define GPIO_CONFIG_CUSTOM_BASE 0x8000
+
#ifdef CONFIG_GENERIC_GPIO
#include <asm/gpio.h>
@@ -152,6 +206,13 @@ static inline int irq_to_gpio(unsigned irq)
return -EINVAL;
}
+static inline int gpio_config(unsigned gpio, u16 param, unsigned long *data)
+{
+ /* GPIO can never have been requested */
+ WARN_ON(1);
+ return -EINVAL;
+}
+
#endif
#endif /* __LINUX_GPIO_H */
diff --git a/include/linux/gpio/nomadik.h b/include/linux/gpio/nomadik.h
new file mode 100644
index 000000000000..c78068176841
--- /dev/null
+++ b/include/linux/gpio/nomadik.h
@@ -0,0 +1,291 @@
+/*
+ * Structures and registers for GPIO access in the Nomadik SoC
+ *
+ * Copyright (C) 2008 STMicroelectronics
+ * Author: Prafulla WADASKAR <prafulla.wadaskar@st.com>
+ * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
+ * Copyright (C) 2011 ST-Ericsson SA
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * Authot: Linus Walleij <linus.wallej@linaro.org>
+ *
+ * Pin config API based on arch/arm/mach-pxa/include/mach/mfp.h:
+ * Copyright (C) 2007 Marvell International Ltd.
+ * eric miao <eric.miao@marvell.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_NOMADIK_H
+#define __GPIO_NOMADIK_H
+
+#include <linux/gpio.h>
+#include <asm-generic/gpio.h>
+
+/*
+ * Custom pin configuration options
+ */
+#define GPIO_CONFIG_NMK_ALTF_GPIO (GPIO_CONFIG_CUSTOM_BASE+0)
+#define GPIO_CONFIG_NMK_ALTF_A (GPIO_CONFIG_CUSTOM_BASE+1)
+#define GPIO_CONFIG_NMK_ALTF_B (GPIO_CONFIG_CUSTOM_BASE+2)
+#define GPIO_CONFIG_NMK_ALTF_C (GPIO_CONFIG_CUSTOM_BASE+3)
+#define GPIO_CONFIG_NMK_GET_ALTF (GPIO_CONFIG_CUSTOM_BASE+4)
+#define GPIO_CONFIG_NMK_SLPM_INPUT (GPIO_CONFIG_CUSTOM_BASE+5)
+#define GPIO_CONFIG_NMK_WAKEUP_ENABLE (GPIO_CONFIG_CUSTOM_BASE+6)
+#define GPIO_CONFIG_NMK_SLPM_NOCHANGE (GPIO_CONFIG_CUSTOM_BASE+7)
+#define GPIO_CONFIG_NMK_WAKEUP_DISABLE (GPIO_CONFIG_CUSTOM_BASE+8)
+#define GPIO_CONFIG_NMK_SETUP_PIN (GPIO_CONFIG_CUSTOM_BASE+9)
+#define GPIO_CONFIG_NMK_SETUP_PIN_LEGACY (GPIO_CONFIG_CUSTOM_BASE+10)
+
+/*
+ * Platform data to register a block: only the initial gpio/irq number.
+ */
+struct nmk_gpio_platform_data {
+ char *name;
+ int first_gpio;
+ int first_irq;
+ int num_gpio;
+ u32 (*get_secondary_status)(unsigned int bank);
+ void (*set_ioforce)(bool enable);
+ bool supports_sleepmode;
+};
+
+/**
+ * nmk_gpio_pin_config - configuration data for a single GPIO pin
+ * @altfunc: the alternate function setting for the pin
+ * @bias_mode: pull up/down/none (float) bias setting for the pin
+ * @output: if this pin is to be configured for output or not
+ * @outval: if configured for output, the default output value (0 or 1)
+ * @sleep_mode: if true, this pin will wake up the system in sleep mode
+ * (DB8500v2) or force the pin to retain its value and not become an
+ * input (as is the default on DB8500v1, pull up/down is retained)
+ */
+struct nmk_gpio_pin_config {
+ int pin;
+ u16 altfunc;
+ u16 bias_mode;
+ bool output;
+ int outval;
+ bool sleep_mode;
+};
+
+/* A horde of exported functions */
+extern void nmk_gpio_wakeups_suspend(void);
+extern void nmk_gpio_wakeups_resume(void);
+extern void nmk_gpio_clocks_enable(void);
+extern void nmk_gpio_clocks_disable(void);
+extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up);
+
+/*
+ * pin configurations are represented by 32-bit integers:
+ *
+ * bit 0.. 8 - Pin Number (512 Pins Maximum)
+ * bit 9..10 - Alternate Function Selection
+ * bit 11..12 - Pull up/down state
+ * bit 13 - Sleep mode behaviour
+ * bit 14 - Direction
+ * bit 15 - Value (if output)
+ * bit 16..18 - SLPM pull up/down state
+ * bit 19..20 - SLPM direction
+ * bit 21..22 - SLPM Value (if output)
+ *
+ * to facilitate the definition, the following macros are provided
+ *
+ * PIN_CFG_DEFAULT - default config (0):
+ * pull up/down = disabled
+ * sleep mode = input/wakeup
+ * direction = input
+ * value = low
+ * SLPM direction = same as normal
+ * SLPM pull = same as normal
+ * SLPM value = same as normal
+ *
+ * PIN_CFG - default config with alternate function
+ */
+
+typedef unsigned long pin_cfg_t;
+
+/* Alternate functions: function C is set in hw by setting both A and B */
+#define NMK_GPIO_ALT_GPIO 0
+#define NMK_GPIO_ALT_A 1
+#define NMK_GPIO_ALT_B 2
+#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
+
+/* Pull up/down values */
+enum nmk_gpio_pull {
+ NMK_GPIO_PULL_NONE,
+ NMK_GPIO_PULL_UP,
+ NMK_GPIO_PULL_DOWN,
+};
+
+/* Sleep mode */
+enum nmk_gpio_slpm {
+ NMK_GPIO_SLPM_INPUT,
+ NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
+ NMK_GPIO_SLPM_NOCHANGE,
+ NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
+};
+
+#define PIN_NUM_MASK 0x1ff
+#define PIN_NUM(x) ((x) & PIN_NUM_MASK)
+
+#define PIN_ALT_SHIFT 9
+#define PIN_ALT_MASK (0x3 << PIN_ALT_SHIFT)
+#define PIN_ALT(x) (((x) & PIN_ALT_MASK) >> PIN_ALT_SHIFT)
+#define PIN_GPIO (NMK_GPIO_ALT_GPIO << PIN_ALT_SHIFT)
+#define PIN_ALT_A (NMK_GPIO_ALT_A << PIN_ALT_SHIFT)
+#define PIN_ALT_B (NMK_GPIO_ALT_B << PIN_ALT_SHIFT)
+#define PIN_ALT_C (NMK_GPIO_ALT_C << PIN_ALT_SHIFT)
+
+#define PIN_PULL_SHIFT 11
+#define PIN_PULL_MASK (0x3 << PIN_PULL_SHIFT)
+#define PIN_PULL(x) (((x) & PIN_PULL_MASK) >> PIN_PULL_SHIFT)
+#define PIN_PULL_NONE (NMK_GPIO_PULL_NONE << PIN_PULL_SHIFT)
+#define PIN_PULL_UP (NMK_GPIO_PULL_UP << PIN_PULL_SHIFT)
+#define PIN_PULL_DOWN (NMK_GPIO_PULL_DOWN << PIN_PULL_SHIFT)
+
+#define PIN_SLPM_SHIFT 13
+#define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT)
+#define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT)
+#define PIN_SLPM_MAKE_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT)
+#define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT)
+/* These two replace the above in DB8500v2+ */
+#define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT)
+#define PIN_SLPM_WAKEUP_DISABLE (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT)
+
+#define PIN_DIR_SHIFT 14
+#define PIN_DIR_MASK (0x1 << PIN_DIR_SHIFT)
+#define PIN_DIR(x) (((x) & PIN_DIR_MASK) >> PIN_DIR_SHIFT)
+#define PIN_DIR_INPUT (0 << PIN_DIR_SHIFT)
+#define PIN_DIR_OUTPUT (1 << PIN_DIR_SHIFT)
+
+#define PIN_VAL_SHIFT 15
+#define PIN_VAL_MASK (0x1 << PIN_VAL_SHIFT)
+#define PIN_VAL(x) (((x) & PIN_VAL_MASK) >> PIN_VAL_SHIFT)
+#define PIN_VAL_LOW (0 << PIN_VAL_SHIFT)
+#define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT)
+
+#define PIN_SLPM_PULL_SHIFT 16
+#define PIN_SLPM_PULL_MASK (0x7 << PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL(x) \
+ (((x) & PIN_SLPM_PULL_MASK) >> PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL_NONE \
+ ((1 + NMK_GPIO_PULL_NONE) << PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL_UP \
+ ((1 + NMK_GPIO_PULL_UP) << PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL_DOWN \
+ ((1 + NMK_GPIO_PULL_DOWN) << PIN_SLPM_PULL_SHIFT)
+
+#define PIN_SLPM_DIR_SHIFT 19
+#define PIN_SLPM_DIR_MASK (0x3 << PIN_SLPM_DIR_SHIFT)
+#define PIN_SLPM_DIR(x) \
+ (((x) & PIN_SLPM_DIR_MASK) >> PIN_SLPM_DIR_SHIFT)
+#define PIN_SLPM_DIR_INPUT ((1 + 0) << PIN_SLPM_DIR_SHIFT)
+#define PIN_SLPM_DIR_OUTPUT ((1 + 1) << PIN_SLPM_DIR_SHIFT)
+
+#define PIN_SLPM_VAL_SHIFT 21
+#define PIN_SLPM_VAL_MASK (0x3 << PIN_SLPM_VAL_SHIFT)
+#define PIN_SLPM_VAL(x) \
+ (((x) & PIN_SLPM_VAL_MASK) >> PIN_SLPM_VAL_SHIFT)
+#define PIN_SLPM_VAL_LOW ((1 + 0) << PIN_SLPM_VAL_SHIFT)
+#define PIN_SLPM_VAL_HIGH ((1 + 1) << PIN_SLPM_VAL_SHIFT)
+
+/* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */
+#define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN)
+#define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP)
+#define PIN_INPUT_NOPULL (PIN_DIR_INPUT | PIN_PULL_NONE)
+#define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW)
+#define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH)
+
+#define PIN_SLPM_INPUT_PULLDOWN (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_DOWN)
+#define PIN_SLPM_INPUT_PULLUP (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_UP)
+#define PIN_SLPM_INPUT_NOPULL (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_NONE)
+#define PIN_SLPM_OUTPUT_LOW (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_LOW)
+#define PIN_SLPM_OUTPUT_HIGH (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_HIGH)
+
+#define PIN_CFG_DEFAULT (0)
+
+#define PIN_CFG(num, alt) \
+ (PIN_CFG_DEFAULT |\
+ (PIN_NUM(num) | PIN_##alt))
+
+#define PIN_CFG_INPUT(num, alt, pull) \
+ (PIN_CFG_DEFAULT |\
+ (PIN_NUM(num) | PIN_##alt | PIN_INPUT_##pull))
+
+#define PIN_CFG_OUTPUT(num, alt, val) \
+ (PIN_CFG_DEFAULT |\
+ (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val))
+
+/*
+ * We want to keep this function outside the driver since it is only using the
+ * externally visible gpio_config() function and merely twisting bits around
+ * for the legacy pin configuration API.
+ */
+static inline int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep)
+{
+ pin_cfg_t cfg;
+ int ret;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ cfg = cfgs[i];
+
+ if (sleep) {
+ /*
+ * We reconfigure for sleep mode, mask off the
+ * normal configs and replace them with sleep mode
+ * configs and pass into the same legacy config
+ * function, simply. Zero values mean "same as in
+ * normal mode".
+ */
+ int slpm_pull = PIN_SLPM_PULL(cfg);
+ int slpm_output = PIN_SLPM_DIR(cfg);
+ int slpm_val = PIN_SLPM_VAL(cfg);
+
+ /* Override bias mode */
+ if (slpm_pull) {
+ cfg &= ~PIN_PULL_MASK;
+ cfg |= (slpm_pull - 1) << PIN_PULL_SHIFT;
+ }
+
+ /* Override in/output mode */
+ if (slpm_output) {
+ cfg &= ~PIN_DIR_MASK;
+ cfg |= (slpm_output - 1) << PIN_DIR_SHIFT;
+ }
+
+ /* Override output value */
+ if (slpm_val) {
+ cfg &= ~PIN_VAL_MASK;
+ cfg |= (slpm_output - 1) << PIN_VAL_SHIFT;
+ }
+ }
+
+ ret = gpio_config(PIN_NUM(cfg),
+ GPIO_CONFIG_NMK_SETUP_PIN_LEGACY,
+ (unsigned long *) &cfg);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
+extern int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep);
+
+static inline int nmk_config_pin(pin_cfg_t cfg, bool sleep)
+{
+ return __nmk_config_pins(&cfg, 1, sleep);
+}
+
+static inline int nmk_config_pins(pin_cfg_t *cfgs, int num)
+{
+ return __nmk_config_pins(cfgs, num, false);
+}
+
+static inline int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num)
+{
+ return __nmk_config_pins(cfgs, num, true);
+}
+
+#endif
diff --git a/include/linux/gpio/u300.h b/include/linux/gpio/u300.h
new file mode 100644
index 000000000000..38cd064b728e
--- /dev/null
+++ b/include/linux/gpio/u300.h
@@ -0,0 +1,32 @@
+/*
+ * U300 GPIO platform data header
+ * Copyright (C) 2011 ST-Ericsson SA
+ * Written on behalf of Linaro for ST-Ericsson
+ *
+ * Author: Linus Walleij <linus.walleij@linaro.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+/**
+ * enum u300_gpio_variant - the type of U300 GPIO employed
+ */
+enum u300_gpio_variant {
+ U300_GPIO_COH901335,
+ U300_GPIO_COH901571_3_BS335,
+ U300_GPIO_COH901571_3_BS365,
+};
+
+/**
+ * struct u300_gpio_platform - U300 GPIO platform data
+ * @variant: IP block variant
+ * @ports: number of GPIO block ports
+ * @gpio_base: first GPIO number for this block (use a free range)
+ * @gpio_irq_base: first GPIO IRQ number for this block (use a free range)
+ */
+struct u300_gpio_platform {
+ enum u300_gpio_variant variant;
+ u8 ports;
+ int gpio_base;
+ int gpio_irq_base;
+};