gpio: tegra186: Add debounce support

The GPIO controller found on Tegra186 and later supports debouncing for
inputs for up to 255 ms.

Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
This commit is contained in:
Thierry Reding 2019-11-08 16:33:53 +01:00 committed by Bartosz Golaszewski
parent 22635ed8a2
commit adce118393

View file

@ -32,6 +32,7 @@
#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_DOUBLE_EDGE (0x3 << 2)
#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_MASK (0x3 << 2)
#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_LEVEL BIT(4)
#define TEGRA186_GPIO_ENABLE_CONFIG_DEBOUNCE BIT(5)
#define TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT BIT(6)
#define TEGRA186_GPIO_DEBOUNCE_CONTROL 0x04
@ -217,6 +218,42 @@ static void tegra186_gpio_set(struct gpio_chip *chip, unsigned int offset,
writel(value, base + TEGRA186_GPIO_OUTPUT_VALUE);
}
static int tegra186_gpio_set_config(struct gpio_chip *chip,
unsigned int offset,
unsigned long config)
{
struct tegra_gpio *gpio = gpiochip_get_data(chip);
u32 debounce, value;
void __iomem *base;
base = tegra186_gpio_get_base(gpio, offset);
if (base == NULL)
return -ENXIO;
if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)
return -ENOTSUPP;
debounce = pinconf_to_config_argument(config);
/*
* The Tegra186 GPIO controller supports a maximum of 255 ms debounce
* time.
*/
if (debounce > 255000)
return -EINVAL;
debounce = DIV_ROUND_UP(debounce, USEC_PER_MSEC);
value = TEGRA186_GPIO_DEBOUNCE_CONTROL_THRESHOLD(debounce);
writel(value, base + TEGRA186_GPIO_DEBOUNCE_CONTROL);
value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG);
value |= TEGRA186_GPIO_ENABLE_CONFIG_DEBOUNCE;
writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG);
return 0;
}
static int tegra186_gpio_of_xlate(struct gpio_chip *chip,
const struct of_phandle_args *spec,
u32 *flags)
@ -539,6 +576,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
gpio->gpio.direction_output = tegra186_gpio_direction_output;
gpio->gpio.get = tegra186_gpio_get,
gpio->gpio.set = tegra186_gpio_set;
gpio->gpio.set_config = tegra186_gpio_set_config;
gpio->gpio.base = -1;