Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * GPIO driver for TI TPS65912x PMICs
0004  *
0005  * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
0006  *  Andrew F. Davis <afd@ti.com>
0007  *
0008  * Based on the Arizona GPIO driver and the previous TPS65912 driver by
0009  * Margarita Olaya Cabrera <magi@slimlogic.co.uk>
0010  */
0011 
0012 #include <linux/gpio/driver.h>
0013 #include <linux/module.h>
0014 #include <linux/platform_device.h>
0015 
0016 #include <linux/mfd/tps65912.h>
0017 
0018 struct tps65912_gpio {
0019     struct gpio_chip gpio_chip;
0020     struct tps65912 *tps;
0021 };
0022 
0023 static int tps65912_gpio_get_direction(struct gpio_chip *gc,
0024                        unsigned offset)
0025 {
0026     struct tps65912_gpio *gpio = gpiochip_get_data(gc);
0027 
0028     int ret, val;
0029 
0030     ret = regmap_read(gpio->tps->regmap, TPS65912_GPIO1 + offset, &val);
0031     if (ret)
0032         return ret;
0033 
0034     if (val & GPIO_CFG_MASK)
0035         return GPIO_LINE_DIRECTION_OUT;
0036     else
0037         return GPIO_LINE_DIRECTION_IN;
0038 }
0039 
0040 static int tps65912_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
0041 {
0042     struct tps65912_gpio *gpio = gpiochip_get_data(gc);
0043 
0044     return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
0045                   GPIO_CFG_MASK, 0);
0046 }
0047 
0048 static int tps65912_gpio_direction_output(struct gpio_chip *gc,
0049                       unsigned offset, int value)
0050 {
0051     struct tps65912_gpio *gpio = gpiochip_get_data(gc);
0052 
0053     /* Set the initial value */
0054     regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
0055                GPIO_SET_MASK, value ? GPIO_SET_MASK : 0);
0056 
0057     return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
0058                   GPIO_CFG_MASK, GPIO_CFG_MASK);
0059 }
0060 
0061 static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset)
0062 {
0063     struct tps65912_gpio *gpio = gpiochip_get_data(gc);
0064     int ret, val;
0065 
0066     ret = regmap_read(gpio->tps->regmap, TPS65912_GPIO1 + offset, &val);
0067     if (ret)
0068         return ret;
0069 
0070     if (val & GPIO_STS_MASK)
0071         return 1;
0072 
0073     return 0;
0074 }
0075 
0076 static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset,
0077                   int value)
0078 {
0079     struct tps65912_gpio *gpio = gpiochip_get_data(gc);
0080 
0081     regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset,
0082                GPIO_SET_MASK, value ? GPIO_SET_MASK : 0);
0083 }
0084 
0085 static const struct gpio_chip template_chip = {
0086     .label          = "tps65912-gpio",
0087     .owner          = THIS_MODULE,
0088     .get_direction      = tps65912_gpio_get_direction,
0089     .direction_input    = tps65912_gpio_direction_input,
0090     .direction_output   = tps65912_gpio_direction_output,
0091     .get            = tps65912_gpio_get,
0092     .set            = tps65912_gpio_set,
0093     .base           = -1,
0094     .ngpio          = 5,
0095     .can_sleep      = true,
0096 };
0097 
0098 static int tps65912_gpio_probe(struct platform_device *pdev)
0099 {
0100     struct tps65912 *tps = dev_get_drvdata(pdev->dev.parent);
0101     struct tps65912_gpio *gpio;
0102 
0103     gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
0104     if (!gpio)
0105         return -ENOMEM;
0106 
0107     gpio->tps = dev_get_drvdata(pdev->dev.parent);
0108     gpio->gpio_chip = template_chip;
0109     gpio->gpio_chip.parent = tps->dev;
0110 
0111     return devm_gpiochip_add_data(&pdev->dev, &gpio->gpio_chip, gpio);
0112 }
0113 
0114 static const struct platform_device_id tps65912_gpio_id_table[] = {
0115     { "tps65912-gpio", },
0116     { /* sentinel */ }
0117 };
0118 MODULE_DEVICE_TABLE(platform, tps65912_gpio_id_table);
0119 
0120 static struct platform_driver tps65912_gpio_driver = {
0121     .driver = {
0122         .name = "tps65912-gpio",
0123     },
0124     .probe = tps65912_gpio_probe,
0125     .id_table = tps65912_gpio_id_table,
0126 };
0127 module_platform_driver(tps65912_gpio_driver);
0128 
0129 MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
0130 MODULE_DESCRIPTION("TPS65912 GPIO driver");
0131 MODULE_LICENSE("GPL v2");