aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/plat-nomadik/include/plat/pincfg.h13
-rw-r--r--drivers/pinctrl/Kconfig1
-rw-r--r--drivers/pinctrl/pinctrl-nomadik.c113
3 files changed, 127 insertions, 0 deletions
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h
index c015133a7ad3..9c949c7c98a7 100644
--- a/arch/arm/plat-nomadik/include/plat/pincfg.h
+++ b/arch/arm/plat-nomadik/include/plat/pincfg.h
@@ -124,6 +124,19 @@ typedef unsigned long pin_cfg_t;
124#define PIN_LOWEMI_DISABLED (0 << PIN_LOWEMI_SHIFT) 124#define PIN_LOWEMI_DISABLED (0 << PIN_LOWEMI_SHIFT)
125#define PIN_LOWEMI_ENABLED (1 << PIN_LOWEMI_SHIFT) 125#define PIN_LOWEMI_ENABLED (1 << PIN_LOWEMI_SHIFT)
126 126
127#define PIN_GPIOMODE_SHIFT 26
128#define PIN_GPIOMODE_MASK (0x1 << PIN_GPIOMODE_SHIFT)
129#define PIN_GPIOMODE(x) (((x) & PIN_GPIOMODE_MASK) >> PIN_GPIOMODE_SHIFT)
130#define PIN_GPIOMODE_DISABLED (0 << PIN_GPIOMODE_SHIFT)
131#define PIN_GPIOMODE_ENABLED (1 << PIN_GPIOMODE_SHIFT)
132
133#define PIN_SLEEPMODE_SHIFT 27
134#define PIN_SLEEPMODE_MASK (0x1 << PIN_SLEEPMODE_SHIFT)
135#define PIN_SLEEPMODE(x) (((x) & PIN_SLEEPMODE_MASK) >> PIN_SLEEPMODE_SHIFT)
136#define PIN_SLEEPMODE_DISABLED (0 << PIN_SLEEPMODE_SHIFT)
137#define PIN_SLEEPMODE_ENABLED (1 << PIN_SLEEPMODE_SHIFT)
138
139
127/* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */ 140/* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */
128#define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN) 141#define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN)
129#define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP) 142#define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP)
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index bbf14dc67ad2..81b19671d193 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -40,6 +40,7 @@ config PINCTRL_NOMADIK
40 bool "Nomadik pin controller driver" 40 bool "Nomadik pin controller driver"
41 depends on ARCH_U8500 41 depends on ARCH_U8500
42 select PINMUX 42 select PINMUX
43 select PINCONF
43 44
44config PINCTRL_DB8500 45config PINCTRL_DB8500
45 bool "DB8500 pin controller driver" 46 bool "DB8500 pin controller driver"
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c
index 8c632e931c22..b8e01c3eaa95 100644
--- a/drivers/pinctrl/pinctrl-nomadik.c
+++ b/drivers/pinctrl/pinctrl-nomadik.c
@@ -26,6 +26,7 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/pinctrl/pinctrl.h> 27#include <linux/pinctrl/pinctrl.h>
28#include <linux/pinctrl/pinmux.h> 28#include <linux/pinctrl/pinmux.h>
29#include <linux/pinctrl/pinconf.h>
29/* Since we request GPIOs from ourself */ 30/* Since we request GPIOs from ourself */
30#include <linux/pinctrl/consumer.h> 31#include <linux/pinctrl/consumer.h>
31 32
@@ -1568,10 +1569,122 @@ static struct pinmux_ops nmk_pinmux_ops = {
1568 .gpio_disable_free = nmk_gpio_disable_free, 1569 .gpio_disable_free = nmk_gpio_disable_free,
1569}; 1570};
1570 1571
1572int nmk_pin_config_get(struct pinctrl_dev *pctldev,
1573 unsigned pin,
1574 unsigned long *config)
1575{
1576 /* Not implemented */
1577 return -EINVAL;
1578}
1579
1580int nmk_pin_config_set(struct pinctrl_dev *pctldev,
1581 unsigned pin,
1582 unsigned long config)
1583{
1584 static const char *pullnames[] = {
1585 [NMK_GPIO_PULL_NONE] = "none",
1586 [NMK_GPIO_PULL_UP] = "up",
1587 [NMK_GPIO_PULL_DOWN] = "down",
1588 [3] /* illegal */ = "??"
1589 };
1590 static const char *slpmnames[] = {
1591 [NMK_GPIO_SLPM_INPUT] = "input/wakeup",
1592 [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup",
1593 };
1594 struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
1595 struct nmk_gpio_chip *nmk_chip;
1596 struct pinctrl_gpio_range *range;
1597 struct gpio_chip *chip;
1598 unsigned bit;
1599
1600 /*
1601 * The pin config contains pin number and altfunction fields, here
1602 * we just ignore that part. It's being handled by the framework and
1603 * pinmux callback respectively.
1604 */
1605 pin_cfg_t cfg = (pin_cfg_t) config;
1606 int pull = PIN_PULL(cfg);
1607 int slpm = PIN_SLPM(cfg);
1608 int output = PIN_DIR(cfg);
1609 int val = PIN_VAL(cfg);
1610 bool lowemi = PIN_LOWEMI(cfg);
1611 bool gpiomode = PIN_GPIOMODE(cfg);
1612 bool sleep = PIN_SLEEPMODE(cfg);
1613
1614 range = nmk_match_gpio_range(pctldev, pin);
1615 if (!range) {
1616 dev_err(npct->dev, "invalid pin offset %d\n", pin);
1617 return -EINVAL;
1618 }
1619 if (!range->gc) {
1620 dev_err(npct->dev, "GPIO chip missing in range for pin %d\n",
1621 pin);
1622 return -EINVAL;
1623 }
1624 chip = range->gc;
1625 nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
1626
1627 if (sleep) {
1628 int slpm_pull = PIN_SLPM_PULL(cfg);
1629 int slpm_output = PIN_SLPM_DIR(cfg);
1630 int slpm_val = PIN_SLPM_VAL(cfg);
1631
1632 /* All pins go into GPIO mode at sleep */
1633 gpiomode = true;
1634
1635 /*
1636 * The SLPM_* values are normal values + 1 to allow zero to
1637 * mean "same as normal".
1638 */
1639 if (slpm_pull)
1640 pull = slpm_pull - 1;
1641 if (slpm_output)
1642 output = slpm_output - 1;
1643 if (slpm_val)
1644 val = slpm_val - 1;
1645
1646 dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n",
1647 pin,
1648 slpm_pull ? pullnames[pull] : "same",
1649 slpm_output ? (output ? "output" : "input") : "same",
1650 slpm_val ? (val ? "high" : "low") : "same");
1651 }
1652
1653 dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: pull %s, slpm %s (%s%s), lowemi %s\n",
1654 pin, cfg, pullnames[pull], slpmnames[slpm],
1655 output ? "output " : "input",
1656 output ? (val ? "high" : "low") : "",
1657 lowemi ? "on" : "off" );
1658
1659 clk_enable(nmk_chip->clk);
1660 bit = pin % NMK_GPIO_PER_CHIP;
1661 if (gpiomode)
1662 /* No glitch when going to GPIO mode */
1663 __nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);
1664 if (output)
1665 __nmk_gpio_make_output(nmk_chip, bit, val);
1666 else {
1667 __nmk_gpio_make_input(nmk_chip, bit);
1668 __nmk_gpio_set_pull(nmk_chip, bit, pull);
1669 }
1670 /* TODO: isn't this only applicable on output pins? */
1671 __nmk_gpio_set_lowemi(nmk_chip, bit, lowemi);
1672
1673 __nmk_gpio_set_slpm(nmk_chip, bit, slpm);
1674 clk_disable(nmk_chip->clk);
1675 return 0;
1676}
1677
1678static struct pinconf_ops nmk_pinconf_ops = {
1679 .pin_config_get = nmk_pin_config_get,
1680 .pin_config_set = nmk_pin_config_set,
1681};
1682
1571static struct pinctrl_desc nmk_pinctrl_desc = { 1683static struct pinctrl_desc nmk_pinctrl_desc = {
1572 .name = "pinctrl-nomadik", 1684 .name = "pinctrl-nomadik",
1573 .pctlops = &nmk_pinctrl_ops, 1685 .pctlops = &nmk_pinctrl_ops,
1574 .pmxops = &nmk_pinmux_ops, 1686 .pmxops = &nmk_pinmux_ops,
1687 .confops = &nmk_pinconf_ops,
1575 .owner = THIS_MODULE, 1688 .owner = THIS_MODULE,
1576}; 1689};
1577 1690