+ reg = <0xfffff400 0x600>;
+
+ atmel,mux-mask = <
+ /* A B */
+ 0xffffffff 0xffc00c3b /* pioA */
+ 0xffffffff 0x7fff3ccf /* pioB */
+ 0xffffffff 0x007fffff /* pioC */
+ >;
+
+ pcfg_none: pcfg_none {
+ bias-disable;
+ };
+
+ pcfg_pull_up: pcfg_pull_up {
+ bias-pullup;
+ };
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <1 14 0x1 &pcfg_none /* PB14 periph A */
+ 1 15 0x1 &pcfg_pull_up>; /* PB15 periph A with pullup */
+ };
+ };
+};
+
dbgu: serial@fffff200 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffff200 0x200>;
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index bdb1a87..55a4f2c 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -54,7 +54,7 @@ config PINCTRL_AT91
depends on OF
depends on ARCH_AT91
select PINMUX
- select PINCONF
+ select GENERIC_PINCONF
help
Say Y here to enable the at91 pinctrl driver
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index 7cce066..1994dd2 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -23,6 +23,7 @@
#include <linux/gpio.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
/* Since we request GPIOs from ourself */
@@ -32,6 +33,7 @@
#include <mach/at91_pio.h>
#include "core.h"
+#include "pinconf.h"
#define MAX_NB_GPIO_PER_BANK 32
@@ -85,6 +87,21 @@ enum at91_mux {
AT91_MUX_PERIPH_D = 4,
};
+struct at91_generic_pinconf {
+ unsigned long *configs;
+ unsigned int nconfigs;
+};
+
+enum at91_pinconf_type {
+ AT91_PINCONF_NATIVE,
+ AT91_PINCONF_GENERIC,
+};
+
+union at91_pinconf {
+ unsigned long native;
+ struct at91_generic_pinconf generic;
+};
+
/**
* struct at91_pmx_pin - describes an At91 pin mux
* @bank: the bank of the pin
@@ -93,10 +110,11 @@ enum at91_mux {
* @conf: the configuration of the pin: PULL_UP, MULTIDRIVE etc...
*/
struct at91_pmx_pin {
- uint32_t bank;
- uint32_t pin;
- enum at91_mux mux;
- unsigned long conf;
+ uint32_t bank;
+ uint32_t pin;
+ enum at91_mux mux;
+ enum at91_pinconf_type conftype;
+ union at91_pinconf conf;
};
/**
@@ -278,8 +296,16 @@ static int at91_dt_node_to_map(struct pinctrl_dev *pctldev,
new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
new_map[i].data.configs.group_or_pin =
pin_get_name(pctldev, grp->pins[i]);
- new_map[i].data.configs.configs = &grp->pins_conf[i].conf;
- new_map[i].data.configs.num_configs = 1;
+ if (!pctldev->desc->confops->is_generic) {
+ new_map[i].data.configs.configs =
+ &grp->pins_conf[i].conf.native;
+ new_map[i].data.configs.num_configs = 1;
+ } else {
+ new_map[i].data.configs.configs =
+ grp->pins_conf[i].conf.generic.configs;
+ new_map[i].data.configs.num_configs =
+ grp->pins_conf[i].conf.generic.nconfigs;
+ }
}
dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n",
@@ -325,7 +351,7 @@ static void at91_mux_disable_interrupt(void __iomem *pio, unsigned mask)
static unsigned at91_mux_get_pullup(void __iomem *pio, unsigned pin)
{
- return (readl_relaxed(pio + PIO_PUSR) >> pin) & 0x1;
+ return !((readl_relaxed(pio + PIO_PUSR) >> pin) & 0x1);
}
static void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on)
@@ -407,6 +433,16 @@ static enum at91_mux at91_mux_get_periph(void __iomem *pio, unsigned mask)
return select + 1;
}
+static bool at91_mux_get_output(void __iomem *pio, unsigned pin)
+{
+ return (readl_relaxed(pio + PIO_OSR) >> pin) & 0x1;
+}
+
+static void at91_mux_set_output(void __iomem *pio, unsigned mask, bool is_on)
+{
+ __raw_writel(mask, pio + (is_on ? PIO_OER : PIO_ODR));
+}
+
static bool at91_mux_get_deglitch(void __iomem *pio, unsigned pin)
{
return (__raw_readl(pio + PIO_IFSR) >> pin) & 0x1;
@@ -445,7 +481,7 @@ static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask,
static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin)
{
- return (__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1;
+ return !((__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1);
}
static void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is_on)
@@ -492,12 +528,17 @@ static struct at91_pinctrl_mux_ops at91sam9x5_ops = {
static void at91_pin_dbg(const struct device *dev, const struct at91_pmx_pin *pin)
{
if (pin->mux) {
- dev_dbg(dev, "pio%c%d configured as periph%c with conf = 0x%lu\n",
- pin->bank + 'A', pin->pin, pin->mux - 1 + 'A', pin->conf);
+ dev_dbg(dev, "pio%c%d configured as periph%c",
+ pin->bank + 'A', pin->pin, pin->mux - 1 + 'A');
} else {
- dev_dbg(dev, "pio%c%d configured as gpio with conf = 0x%lu\n",
- pin->bank + 'A', pin->pin, pin->conf);
+ dev_dbg(dev, "pio%c%d configured as gpio",
+ pin->bank + 'A', pin->pin);
}
+
+ if (pin->conftype == AT91_PINCONF_NATIVE)
+ dev_dbg(dev, " with conf = 0x%lu\n", pin->conf.native);
+ else
+ dev_dbg(dev, "\n");