mirror of
https://gitee.com/openharmony/kernel_linux
synced 2025-04-16 14:20:38 +00:00
pinctrl: at91: add support for OUTPUT config
Add support for pin output control through the pinctrl config: - support enabling/disabling output on a given pin - support output level setting (high or low) Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com> Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
e11dee2e98
commit
96bb12dead
@ -98,6 +98,8 @@ DRIVE_STRENGTH (3 << 5): indicate the drive strength of the pin using the
|
|||||||
01 - Low
|
01 - Low
|
||||||
10 - Medium
|
10 - Medium
|
||||||
11 - High
|
11 - High
|
||||||
|
OUTPUT (1 << 7): indicate this pin need to be configured as an output.
|
||||||
|
OUTPUT_VAL (1 << 8): output val (1 = high, 0 = low)
|
||||||
DEBOUNCE (1 << 16): indicate this pin needs debounce.
|
DEBOUNCE (1 << 16): indicate this pin needs debounce.
|
||||||
DEBOUNCE_VAL (0x3fff << 17): debounce value.
|
DEBOUNCE_VAL (0x3fff << 17): debounce value.
|
||||||
|
|
||||||
|
@ -56,6 +56,9 @@ static int gpio_banks;
|
|||||||
#define DRIVE_STRENGTH_SHIFT 5
|
#define DRIVE_STRENGTH_SHIFT 5
|
||||||
#define DRIVE_STRENGTH_MASK 0x3
|
#define DRIVE_STRENGTH_MASK 0x3
|
||||||
#define DRIVE_STRENGTH (DRIVE_STRENGTH_MASK << DRIVE_STRENGTH_SHIFT)
|
#define DRIVE_STRENGTH (DRIVE_STRENGTH_MASK << DRIVE_STRENGTH_SHIFT)
|
||||||
|
#define OUTPUT (1 << 7)
|
||||||
|
#define OUTPUT_VAL_SHIFT 8
|
||||||
|
#define OUTPUT_VAL (0x1 << OUTPUT_VAL_SHIFT)
|
||||||
#define DEBOUNCE (1 << 16)
|
#define DEBOUNCE (1 << 16)
|
||||||
#define DEBOUNCE_VAL_SHIFT 17
|
#define DEBOUNCE_VAL_SHIFT 17
|
||||||
#define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT)
|
#define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT)
|
||||||
@ -375,6 +378,19 @@ static void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on)
|
|||||||
writel_relaxed(mask, pio + (on ? PIO_PUER : PIO_PUDR));
|
writel_relaxed(mask, pio + (on ? PIO_PUER : PIO_PUDR));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool at91_mux_get_output(void __iomem *pio, unsigned int pin, bool *val)
|
||||||
|
{
|
||||||
|
*val = (readl_relaxed(pio + PIO_ODSR) >> pin) & 0x1;
|
||||||
|
return (readl_relaxed(pio + PIO_OSR) >> pin) & 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void at91_mux_set_output(void __iomem *pio, unsigned int mask,
|
||||||
|
bool is_on, bool val)
|
||||||
|
{
|
||||||
|
writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR));
|
||||||
|
writel_relaxed(mask, pio + (is_on ? PIO_OER : PIO_ODR));
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned at91_mux_get_multidrive(void __iomem *pio, unsigned pin)
|
static unsigned at91_mux_get_multidrive(void __iomem *pio, unsigned pin)
|
||||||
{
|
{
|
||||||
return (readl_relaxed(pio + PIO_MDSR) >> pin) & 0x1;
|
return (readl_relaxed(pio + PIO_MDSR) >> pin) & 0x1;
|
||||||
@ -848,6 +864,7 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
|
|||||||
void __iomem *pio;
|
void __iomem *pio;
|
||||||
unsigned pin;
|
unsigned pin;
|
||||||
int div;
|
int div;
|
||||||
|
bool out;
|
||||||
|
|
||||||
*config = 0;
|
*config = 0;
|
||||||
dev_dbg(info->dev, "%s:%d, pin_id=%d", __func__, __LINE__, pin_id);
|
dev_dbg(info->dev, "%s:%d, pin_id=%d", __func__, __LINE__, pin_id);
|
||||||
@ -875,6 +892,8 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
|
|||||||
if (info->ops->get_drivestrength)
|
if (info->ops->get_drivestrength)
|
||||||
*config |= (info->ops->get_drivestrength(pio, pin)
|
*config |= (info->ops->get_drivestrength(pio, pin)
|
||||||
<< DRIVE_STRENGTH_SHIFT);
|
<< DRIVE_STRENGTH_SHIFT);
|
||||||
|
if (at91_mux_get_output(pio, pin, &out))
|
||||||
|
*config |= OUTPUT | (out << OUTPUT_VAL_SHIFT);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -907,6 +926,8 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev,
|
|||||||
if (config & PULL_UP && config & PULL_DOWN)
|
if (config & PULL_UP && config & PULL_DOWN)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
at91_mux_set_output(pio, mask, config & OUTPUT,
|
||||||
|
(config & OUTPUT_VAL) >> OUTPUT_VAL_SHIFT);
|
||||||
at91_mux_set_pullup(pio, mask, config & PULL_UP);
|
at91_mux_set_pullup(pio, mask, config & PULL_UP);
|
||||||
at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE);
|
at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE);
|
||||||
if (info->ops->set_deglitch)
|
if (info->ops->set_deglitch)
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#define AT91_PINCTRL_DEGLITCH (1 << 2)
|
#define AT91_PINCTRL_DEGLITCH (1 << 2)
|
||||||
#define AT91_PINCTRL_PULL_DOWN (1 << 3)
|
#define AT91_PINCTRL_PULL_DOWN (1 << 3)
|
||||||
#define AT91_PINCTRL_DIS_SCHMIT (1 << 4)
|
#define AT91_PINCTRL_DIS_SCHMIT (1 << 4)
|
||||||
|
#define AT91_PINCTRL_OUTPUT (1 << 7)
|
||||||
|
#define AT91_PINCTRL_OUTPUT_VAL(x) ((x & 0x1) << 8)
|
||||||
#define AT91_PINCTRL_DEBOUNCE (1 << 16)
|
#define AT91_PINCTRL_DEBOUNCE (1 << 16)
|
||||||
#define AT91_PINCTRL_DEBOUNCE_VAL(x) (x << 17)
|
#define AT91_PINCTRL_DEBOUNCE_VAL(x) (x << 17)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user