linux/drivers/gpio/gpio-tps65086.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
   3 *      Andrew F. Davis <afd@ti.com>
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  10 * kind, whether expressed or implied; without even the implied warranty
  11 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License version 2 for more details.
  13 *
  14 * Based on the TPS65912 driver
  15 */
  16
  17#include <linux/gpio.h>
  18#include <linux/module.h>
  19#include <linux/platform_device.h>
  20
  21#include <linux/mfd/tps65086.h>
  22
  23struct tps65086_gpio {
  24        struct gpio_chip chip;
  25        struct tps65086 *tps;
  26};
  27
  28static int tps65086_gpio_get_direction(struct gpio_chip *chip,
  29                                       unsigned offset)
  30{
  31        /* This device is output only */
  32        return 0;
  33}
  34
  35static int tps65086_gpio_direction_input(struct gpio_chip *chip,
  36                                         unsigned offset)
  37{
  38        /* This device is output only */
  39        return -EINVAL;
  40}
  41
  42static int tps65086_gpio_direction_output(struct gpio_chip *chip,
  43                                          unsigned offset, int value)
  44{
  45        struct tps65086_gpio *gpio = gpiochip_get_data(chip);
  46
  47        /* Set the initial value */
  48        regmap_update_bits(gpio->tps->regmap, TPS65086_GPOCTRL,
  49                           BIT(4 + offset), value ? BIT(4 + offset) : 0);
  50
  51        return 0;
  52}
  53
  54static int tps65086_gpio_get(struct gpio_chip *chip, unsigned offset)
  55{
  56        struct tps65086_gpio *gpio = gpiochip_get_data(chip);
  57        int ret, val;
  58
  59        ret = regmap_read(gpio->tps->regmap, TPS65086_GPOCTRL, &val);
  60        if (ret < 0)
  61                return ret;
  62
  63        return val & BIT(4 + offset);
  64}
  65
  66static void tps65086_gpio_set(struct gpio_chip *chip, unsigned offset,
  67                              int value)
  68{
  69        struct tps65086_gpio *gpio = gpiochip_get_data(chip);
  70
  71        regmap_update_bits(gpio->tps->regmap, TPS65086_GPOCTRL,
  72                           BIT(4 + offset), value ? BIT(4 + offset) : 0);
  73}
  74
  75static struct gpio_chip template_chip = {
  76        .label                  = "tps65086-gpio",
  77        .owner                  = THIS_MODULE,
  78        .get_direction          = tps65086_gpio_get_direction,
  79        .direction_input        = tps65086_gpio_direction_input,
  80        .direction_output       = tps65086_gpio_direction_output,
  81        .get                    = tps65086_gpio_get,
  82        .set                    = tps65086_gpio_set,
  83        .base                   = -1,
  84        .ngpio                  = 4,
  85        .can_sleep              = true,
  86};
  87
  88static int tps65086_gpio_probe(struct platform_device *pdev)
  89{
  90        struct tps65086_gpio *gpio;
  91        int ret;
  92
  93        gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
  94        if (!gpio)
  95                return -ENOMEM;
  96
  97        platform_set_drvdata(pdev, gpio);
  98
  99        gpio->tps = dev_get_drvdata(pdev->dev.parent);
 100        gpio->chip = template_chip;
 101        gpio->chip.parent = gpio->tps->dev;
 102
 103        ret = gpiochip_add_data(&gpio->chip, gpio);
 104        if (ret < 0) {
 105                dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
 106                return ret;
 107        }
 108
 109        return 0;
 110}
 111
 112static int tps65086_gpio_remove(struct platform_device *pdev)
 113{
 114        struct tps65086_gpio *gpio = platform_get_drvdata(pdev);
 115
 116        gpiochip_remove(&gpio->chip);
 117
 118        return 0;
 119}
 120
 121static const struct platform_device_id tps65086_gpio_id_table[] = {
 122        { "tps65086-gpio", },
 123        { /* sentinel */ }
 124};
 125MODULE_DEVICE_TABLE(platform, tps65086_gpio_id_table);
 126
 127static struct platform_driver tps65086_gpio_driver = {
 128        .driver = {
 129                .name = "tps65086-gpio",
 130        },
 131        .probe = tps65086_gpio_probe,
 132        .remove = tps65086_gpio_remove,
 133        .id_table = tps65086_gpio_id_table,
 134};
 135module_platform_driver(tps65086_gpio_driver);
 136
 137MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
 138MODULE_DESCRIPTION("TPS65086 GPIO driver");
 139MODULE_LICENSE("GPL v2");
 140