mirror of
https://github.com/torvalds/linux
synced 2024-09-24 05:17:36 +00:00
ARM: 6354/1: nomadik-gpio: allow control of sleep mode direction and pull up
DB8500v2 allows control of direction and pull up/down configuration in sleep mode, instead of switching the pin to input with pull up/down enabled. Acked-by: Linus Walleij <linus.walleij@stericsson.com> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
7e3f7e59cc
commit
6720db7cc5
|
@ -102,6 +102,22 @@ static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
|
||||||
writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
|
writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
|
||||||
|
unsigned offset, int val)
|
||||||
|
{
|
||||||
|
if (val)
|
||||||
|
writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATS);
|
||||||
|
else
|
||||||
|
writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
|
||||||
|
unsigned offset, int val)
|
||||||
|
{
|
||||||
|
writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
|
||||||
|
__nmk_gpio_set_output(nmk_chip, offset, val);
|
||||||
|
}
|
||||||
|
|
||||||
static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
|
static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
|
||||||
pin_cfg_t cfg)
|
pin_cfg_t cfg)
|
||||||
{
|
{
|
||||||
|
@ -126,12 +142,21 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
|
||||||
int pull = PIN_PULL(cfg);
|
int pull = PIN_PULL(cfg);
|
||||||
int af = PIN_ALT(cfg);
|
int af = PIN_ALT(cfg);
|
||||||
int slpm = PIN_SLPM(cfg);
|
int slpm = PIN_SLPM(cfg);
|
||||||
|
int output = PIN_DIR(cfg);
|
||||||
|
int val = PIN_VAL(cfg);
|
||||||
|
|
||||||
dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s\n",
|
dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s (%s%s)\n",
|
||||||
pin, afnames[af], pullnames[pull], slpmnames[slpm]);
|
pin, afnames[af], pullnames[pull], slpmnames[slpm],
|
||||||
|
output ? "output " : "input",
|
||||||
|
output ? (val ? "high" : "low") : "");
|
||||||
|
|
||||||
|
if (output)
|
||||||
|
__nmk_gpio_make_output(nmk_chip, offset, val);
|
||||||
|
else {
|
||||||
|
__nmk_gpio_make_input(nmk_chip, offset);
|
||||||
|
__nmk_gpio_set_pull(nmk_chip, offset, pull);
|
||||||
|
}
|
||||||
|
|
||||||
__nmk_gpio_make_input(nmk_chip, offset);
|
|
||||||
__nmk_gpio_set_pull(nmk_chip, offset, pull);
|
|
||||||
__nmk_gpio_set_slpm(nmk_chip, offset, slpm);
|
__nmk_gpio_set_slpm(nmk_chip, offset, slpm);
|
||||||
__nmk_gpio_set_mode(nmk_chip, offset, af);
|
__nmk_gpio_set_mode(nmk_chip, offset, af);
|
||||||
}
|
}
|
||||||
|
@ -519,12 +544,8 @@ static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
|
||||||
{
|
{
|
||||||
struct nmk_gpio_chip *nmk_chip =
|
struct nmk_gpio_chip *nmk_chip =
|
||||||
container_of(chip, struct nmk_gpio_chip, chip);
|
container_of(chip, struct nmk_gpio_chip, chip);
|
||||||
u32 bit = 1 << offset;
|
|
||||||
|
|
||||||
if (val)
|
__nmk_gpio_set_output(nmk_chip, offset, val);
|
||||||
writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
|
|
||||||
else
|
|
||||||
writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
|
static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
|
||||||
|
@ -533,8 +554,7 @@ static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
|
||||||
struct nmk_gpio_chip *nmk_chip =
|
struct nmk_gpio_chip *nmk_chip =
|
||||||
container_of(chip, struct nmk_gpio_chip, chip);
|
container_of(chip, struct nmk_gpio_chip, chip);
|
||||||
|
|
||||||
writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
|
__nmk_gpio_make_output(nmk_chip, offset, val);
|
||||||
nmk_gpio_set_output(chip, offset, val);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,12 +19,16 @@
|
||||||
* bit 9..10 - Alternate Function Selection
|
* bit 9..10 - Alternate Function Selection
|
||||||
* bit 11..12 - Pull up/down state
|
* bit 11..12 - Pull up/down state
|
||||||
* bit 13 - Sleep mode behaviour
|
* bit 13 - Sleep mode behaviour
|
||||||
|
* bit 14 - (sleep mode) Direction
|
||||||
|
* bit 15 - (sleep mode) Value (if output)
|
||||||
*
|
*
|
||||||
* to facilitate the definition, the following macros are provided
|
* to facilitate the definition, the following macros are provided
|
||||||
*
|
*
|
||||||
* PIN_CFG_DEFAULT - default config (0):
|
* PIN_CFG_DEFAULT - default config (0):
|
||||||
* pull up/down = disabled
|
* pull up/down = disabled
|
||||||
* sleep mode = input/wakeup
|
* sleep mode = input/wakeup
|
||||||
|
* (sleep mode) direction = input
|
||||||
|
* (sleep mode) value = low
|
||||||
*
|
*
|
||||||
* PIN_CFG - default config with alternate function
|
* PIN_CFG - default config with alternate function
|
||||||
* PIN_CFG_PULL - default config with alternate function and pull up/down
|
* PIN_CFG_PULL - default config with alternate function and pull up/down
|
||||||
|
@ -53,12 +57,37 @@ typedef unsigned long pin_cfg_t;
|
||||||
#define PIN_SLPM_SHIFT 13
|
#define PIN_SLPM_SHIFT 13
|
||||||
#define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT)
|
#define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT)
|
||||||
#define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT)
|
#define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT)
|
||||||
#define PIN_SLPM_INPUT (NMK_GPIO_SLPM_INPUT << 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)
|
#define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT)
|
||||||
/* These two replace the above in DB8500v2+ */
|
/* These two replace the above in DB8500v2+ */
|
||||||
#define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT)
|
#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_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)
|
||||||
|
|
||||||
|
/* Shortcuts. Use these instead of separate DIR and VAL. */
|
||||||
|
#define PIN_INPUT PIN_DIR_INPUT
|
||||||
|
#define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW)
|
||||||
|
#define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are the same as the ones above, but should make more sense to the
|
||||||
|
* reader when seen along with a setting a pin to AF mode.
|
||||||
|
*/
|
||||||
|
#define PIN_SLPM_INPUT PIN_INPUT
|
||||||
|
#define PIN_SLPM_OUTPUT_LOW PIN_OUTPUT_LOW
|
||||||
|
#define PIN_SLPM_OUTPUT_HIGH PIN_OUTPUT_HIGH
|
||||||
|
|
||||||
#define PIN_CFG_DEFAULT (PIN_PULL_NONE | PIN_SLPM_INPUT)
|
#define PIN_CFG_DEFAULT (PIN_PULL_NONE | PIN_SLPM_INPUT)
|
||||||
|
|
||||||
#define PIN_CFG(num, alt) \
|
#define PIN_CFG(num, alt) \
|
||||||
|
|
Loading…
Reference in a new issue