From 2c3c1048746a4622d8c89a29670120dc8fab93c4 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:49:45 +0200 Subject: Adding upstream version 6.1.76. Signed-off-by: Daniel Baumann --- drivers/gpio/gpio-tps65912.c | 131 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 drivers/gpio/gpio-tps65912.c (limited to 'drivers/gpio/gpio-tps65912.c') diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c new file mode 100644 index 000000000..fab771cb6 --- /dev/null +++ b/drivers/gpio/gpio-tps65912.c @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * GPIO driver for TI TPS65912x PMICs + * + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ + * Andrew F. Davis + * + * Based on the Arizona GPIO driver and the previous TPS65912 driver by + * Margarita Olaya Cabrera + */ + +#include +#include +#include + +#include + +struct tps65912_gpio { + struct gpio_chip gpio_chip; + struct tps65912 *tps; +}; + +static int tps65912_gpio_get_direction(struct gpio_chip *gc, + unsigned offset) +{ + struct tps65912_gpio *gpio = gpiochip_get_data(gc); + + int ret, val; + + ret = regmap_read(gpio->tps->regmap, TPS65912_GPIO1 + offset, &val); + if (ret) + return ret; + + if (val & GPIO_CFG_MASK) + return GPIO_LINE_DIRECTION_OUT; + else + return GPIO_LINE_DIRECTION_IN; +} + +static int tps65912_gpio_direction_input(struct gpio_chip *gc, unsigned offset) +{ + struct tps65912_gpio *gpio = gpiochip_get_data(gc); + + return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, + GPIO_CFG_MASK, 0); +} + +static int tps65912_gpio_direction_output(struct gpio_chip *gc, + unsigned offset, int value) +{ + struct tps65912_gpio *gpio = gpiochip_get_data(gc); + + /* Set the initial value */ + regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, + GPIO_SET_MASK, value ? GPIO_SET_MASK : 0); + + return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, + GPIO_CFG_MASK, GPIO_CFG_MASK); +} + +static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset) +{ + struct tps65912_gpio *gpio = gpiochip_get_data(gc); + int ret, val; + + ret = regmap_read(gpio->tps->regmap, TPS65912_GPIO1 + offset, &val); + if (ret) + return ret; + + if (val & GPIO_STS_MASK) + return 1; + + return 0; +} + +static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset, + int value) +{ + struct tps65912_gpio *gpio = gpiochip_get_data(gc); + + regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, + GPIO_SET_MASK, value ? GPIO_SET_MASK : 0); +} + +static const struct gpio_chip template_chip = { + .label = "tps65912-gpio", + .owner = THIS_MODULE, + .get_direction = tps65912_gpio_get_direction, + .direction_input = tps65912_gpio_direction_input, + .direction_output = tps65912_gpio_direction_output, + .get = tps65912_gpio_get, + .set = tps65912_gpio_set, + .base = -1, + .ngpio = 5, + .can_sleep = true, +}; + +static int tps65912_gpio_probe(struct platform_device *pdev) +{ + struct tps65912 *tps = dev_get_drvdata(pdev->dev.parent); + struct tps65912_gpio *gpio; + + gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); + if (!gpio) + return -ENOMEM; + + gpio->tps = dev_get_drvdata(pdev->dev.parent); + gpio->gpio_chip = template_chip; + gpio->gpio_chip.parent = tps->dev; + + return devm_gpiochip_add_data(&pdev->dev, &gpio->gpio_chip, gpio); +} + +static const struct platform_device_id tps65912_gpio_id_table[] = { + { "tps65912-gpio", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, tps65912_gpio_id_table); + +static struct platform_driver tps65912_gpio_driver = { + .driver = { + .name = "tps65912-gpio", + }, + .probe = tps65912_gpio_probe, + .id_table = tps65912_gpio_id_table, +}; +module_platform_driver(tps65912_gpio_driver); + +MODULE_AUTHOR("Andrew F. Davis "); +MODULE_DESCRIPTION("TPS65912 GPIO driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3