summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/pinctrl-rockchip.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 88d40772e387..1882713e68f9 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -2710,6 +2710,57 @@ static int rockchip_gpio_direction_output(struct gpio_chip *gc,
return pinctrl_gpio_direction_output(gc->base + offset);
}
+static void rockchip_gpio_set_debounce(struct gpio_chip *gc,
+ unsigned int offset, bool enable)
+{
+ struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
+ void __iomem *reg = bank->reg_base + GPIO_DEBOUNCE;
+ unsigned long flags;
+ u32 data;
+
+ clk_enable(bank->clk);
+ raw_spin_lock_irqsave(&bank->slock, flags);
+
+ data = readl(reg);
+ if (enable)
+ data |= BIT(offset);
+ else
+ data &= ~BIT(offset);
+ writel(data, reg);
+
+ raw_spin_unlock_irqrestore(&bank->slock, flags);
+ clk_disable(bank->clk);
+}
+
+/*
+ * gpiolib set_config callback function. The setting of the pin
+ * mux function as 'gpio output' will be handled by the pinctrl subsystem
+ * interface.
+ */
+static int rockchip_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
+ unsigned long config)
+{
+ enum pin_config_param param = pinconf_to_config_param(config);
+
+ switch (param) {
+ case PIN_CONFIG_INPUT_DEBOUNCE:
+ rockchip_gpio_set_debounce(gc, offset, true);
+ /*
+ * Rockchip's gpio could only support up to one period
+ * of the debounce clock(pclk), which is far away from
+ * satisftying the requirement, as pclk is usually near
+ * 100MHz shared by all peripherals. So the fact is it
+ * has crippled debounce capability could only be useful
+ * to prevent any spurious glitches from waking up the system
+ * if the gpio is conguired as wakeup interrupt source. Let's
+ * still return -ENOTSUPP as before, to make sure the caller
+ * of gpiod_set_debounce won't change its behaviour.
+ */
+ default:
+ return -ENOTSUPP;
+ }
+}
+
/*
* gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin
* and a virtual IRQ, if not already present.
@@ -2735,6 +2786,7 @@ static const struct gpio_chip rockchip_gpiolib_chip = {
.get_direction = rockchip_gpio_get_direction,
.direction_input = rockchip_gpio_direction_input,
.direction_output = rockchip_gpio_direction_output,
+ .set_config = rockchip_gpio_set_config,
.to_irq = rockchip_gpio_to_irq,
.owner = THIS_MODULE,
};
OpenPOWER on IntegriCloud