diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2011-05-13 10:51:48 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2011-05-13 10:51:48 +1000 |
commit | 47d86dcab7cd75c75bdad04c56ca093d71f291f0 (patch) | |
tree | 6fe388ef3edc32f0e3871a17589f542f5b685c46 /include | |
parent | 1fd65d2264d86296e73e3aae62c8c2171783cee6 (diff) | |
parent | 417ffd2681947603a1a60372fd02406890fb120f (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.h | 8 | ||||
-rw-r--r-- | include/linux/gpio.h | 61 | ||||
-rw-r--r-- | include/linux/gpio/nomadik.h | 291 | ||||
-rw-r--r-- | include/linux/gpio/u300.h | 32 |
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; +}; |