diff options
Diffstat (limited to 'drivers/gpio/gpio-tps65912.c')
| -rw-r--r-- | drivers/gpio/gpio-tps65912.c | 171 |
1 files changed, 79 insertions, 92 deletions
diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c index 30a5844a7dca..7a2c5685c2fd 100644 --- a/drivers/gpio/gpio-tps65912.c +++ b/drivers/gpio/gpio-tps65912.c @@ -1,147 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Copyright 2011 Texas Instruments Inc. + * GPIO driver for TI TPS65912x PMICs * - * Author: Margarita Olaya <magi@slimlogic.co.uk> + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ + * Andrew F. Davis <afd@ti.com> * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This driver is based on wm8350 implementation. + * Based on the Arizona GPIO driver and the previous TPS65912 driver by + * Margarita Olaya Cabrera <magi@slimlogic.co.uk> */ -#include <linux/kernel.h> +#include <linux/gpio/driver.h> #include <linux/module.h> -#include <linux/errno.h> -#include <linux/gpio.h> -#include <linux/mfd/core.h> #include <linux/platform_device.h> -#include <linux/seq_file.h> -#include <linux/slab.h> + #include <linux/mfd/tps65912.h> -struct tps65912_gpio_data { - struct tps65912 *tps65912; +struct tps65912_gpio { struct gpio_chip gpio_chip; + struct tps65912 *tps; }; -static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset) +static int tps65912_gpio_get_direction(struct gpio_chip *gc, + unsigned offset) { - struct tps65912 *tps65912 = container_of(gc, struct tps65912, gpio); - int val; + struct tps65912_gpio *gpio = gpiochip_get_data(gc); - val = tps65912_reg_read(tps65912, TPS65912_GPIO1 + offset); + int ret, val; - if (val & GPIO_STS_MASK) - return 1; + ret = regmap_read(gpio->tps->regmap, TPS65912_GPIO1 + offset, &val); + if (ret) + return ret; - return 0; + if (val & GPIO_CFG_MASK) + return GPIO_LINE_DIRECTION_OUT; + else + return GPIO_LINE_DIRECTION_IN; } -static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset, - int value) +static int tps65912_gpio_direction_input(struct gpio_chip *gc, unsigned offset) { - struct tps65912 *tps65912 = container_of(gc, struct tps65912, gpio); + struct tps65912_gpio *gpio = gpiochip_get_data(gc); - if (value) - tps65912_set_bits(tps65912, TPS65912_GPIO1 + offset, - GPIO_SET_MASK); - else - tps65912_clear_bits(tps65912, TPS65912_GPIO1 + offset, - GPIO_SET_MASK); + return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, + GPIO_CFG_MASK, 0); } -static int tps65912_gpio_output(struct gpio_chip *gc, unsigned offset, - int value) +static int tps65912_gpio_direction_output(struct gpio_chip *gc, + unsigned offset, int value) { - struct tps65912 *tps65912 = container_of(gc, struct tps65912, gpio); + struct tps65912_gpio *gpio = gpiochip_get_data(gc); + int ret; /* Set the initial value */ - tps65912_gpio_set(gc, offset, value); + ret = regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, + GPIO_SET_MASK, value ? GPIO_SET_MASK : 0); + if (ret) + return ret; + + 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 tps65912_set_bits(tps65912, TPS65912_GPIO1 + offset, - GPIO_CFG_MASK); + return 0; } -static int tps65912_gpio_input(struct gpio_chip *gc, unsigned offset) +static int tps65912_gpio_set(struct gpio_chip *gc, unsigned int offset, + int value) { - struct tps65912 *tps65912 = container_of(gc, struct tps65912, gpio); + struct tps65912_gpio *gpio = gpiochip_get_data(gc); - return tps65912_clear_bits(tps65912, TPS65912_GPIO1 + offset, - GPIO_CFG_MASK); + return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, + GPIO_SET_MASK, value ? GPIO_SET_MASK : 0); } -static struct gpio_chip template_chip = { - .label = "tps65912", +static const struct gpio_chip template_chip = { + .label = "tps65912-gpio", .owner = THIS_MODULE, - .direction_input = tps65912_gpio_input, - .direction_output = tps65912_gpio_output, + .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, - .can_sleep = 1, - .ngpio = 5, .base = -1, + .ngpio = 5, + .can_sleep = true, }; static int tps65912_gpio_probe(struct platform_device *pdev) { - struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent); - struct tps65912_board *pdata = tps65912->dev->platform_data; - struct tps65912_gpio_data *tps65912_gpio; - int ret; + struct tps65912 *tps = dev_get_drvdata(pdev->dev.parent); + struct tps65912_gpio *gpio; - tps65912_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps65912_gpio), - GFP_KERNEL); - if (tps65912_gpio == NULL) + gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); + if (!gpio) return -ENOMEM; - tps65912_gpio->tps65912 = tps65912; - tps65912_gpio->gpio_chip = template_chip; - tps65912_gpio->gpio_chip.dev = &pdev->dev; - if (pdata && pdata->gpio_base) - tps65912_gpio->gpio_chip.base = pdata->gpio_base; - - ret = gpiochip_add(&tps65912_gpio->gpio_chip); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to register gpiochip, %d\n", ret); - return ret; - } + gpio->tps = dev_get_drvdata(pdev->dev.parent); + gpio->gpio_chip = template_chip; + gpio->gpio_chip.parent = tps->dev; - platform_set_drvdata(pdev, tps65912_gpio); - - return ret; + return devm_gpiochip_add_data(&pdev->dev, &gpio->gpio_chip, gpio); } -static int tps65912_gpio_remove(struct platform_device *pdev) -{ - struct tps65912_gpio_data *tps65912_gpio = platform_get_drvdata(pdev); - - return gpiochip_remove(&tps65912_gpio->gpio_chip); -} +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", - .owner = THIS_MODULE, }, .probe = tps65912_gpio_probe, - .remove = tps65912_gpio_remove, + .id_table = tps65912_gpio_id_table, }; +module_platform_driver(tps65912_gpio_driver); -static int __init tps65912_gpio_init(void) -{ - return platform_driver_register(&tps65912_gpio_driver); -} -subsys_initcall(tps65912_gpio_init); - -static void __exit tps65912_gpio_exit(void) -{ - platform_driver_unregister(&tps65912_gpio_driver); -} -module_exit(tps65912_gpio_exit); - -MODULE_AUTHOR("Margarita Olaya Cabrera <magi@slimlogic.co.uk>"); -MODULE_DESCRIPTION("GPIO interface for TPS65912 PMICs"); +MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); +MODULE_DESCRIPTION("TPS65912 GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:tps65912-gpio"); |
