linux/drivers/gpio/gpio-lp873x.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
   3 *      Keerthy <j-keerthy@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 TPS65218 driver
  15 */
  16
  17#include <linux/gpio/driver.h>
  18#include <linux/module.h>
  19#include <linux/platform_device.h>
  20#include <linux/regmap.h>
  21
  22#include <linux/mfd/lp873x.h>
  23
  24#define BITS_PER_GPO            0x4
  25#define LP873X_GPO_CTRL_OD      0x2
  26
  27struct lp873x_gpio {
  28        struct gpio_chip chip;
  29        struct lp873x *lp873;
  30};
  31
  32static int lp873x_gpio_get_direction(struct gpio_chip *chip,
  33                                     unsigned int offset)
  34{
  35        /* This device is output only */
  36        return GPIO_LINE_DIRECTION_OUT;
  37}
  38
  39static int lp873x_gpio_direction_input(struct gpio_chip *chip,
  40                                       unsigned int offset)
  41{
  42        /* This device is output only */
  43        return -EINVAL;
  44}
  45
  46static int lp873x_gpio_direction_output(struct gpio_chip *chip,
  47                                        unsigned int offset, int value)
  48{
  49        struct lp873x_gpio *gpio = gpiochip_get_data(chip);
  50
  51        /* Set the initial value */
  52        return regmap_update_bits(gpio->lp873->regmap, LP873X_REG_GPO_CTRL,
  53                                  BIT(offset * BITS_PER_GPO),
  54                                  value ? BIT(offset * BITS_PER_GPO) : 0);
  55}
  56
  57static int lp873x_gpio_get(struct gpio_chip *chip, unsigned int offset)
  58{
  59        struct lp873x_gpio *gpio = gpiochip_get_data(chip);
  60        int ret, val;
  61
  62        ret = regmap_read(gpio->lp873->regmap, LP873X_REG_GPO_CTRL, &val);
  63        if (ret < 0)
  64                return ret;
  65
  66        return val & BIT(offset * BITS_PER_GPO);
  67}
  68
  69static void lp873x_gpio_set(struct gpio_chip *chip, unsigned int offset,
  70                            int value)
  71{
  72        struct lp873x_gpio *gpio = gpiochip_get_data(chip);
  73
  74        regmap_update_bits(gpio->lp873->regmap, LP873X_REG_GPO_CTRL,
  75                           BIT(offset * BITS_PER_GPO),
  76                           value ? BIT(offset * BITS_PER_GPO) : 0);
  77}
  78
  79static int lp873x_gpio_request(struct gpio_chip *gc, unsigned int offset)
  80{
  81        struct lp873x_gpio *gpio = gpiochip_get_data(gc);
  82        int ret;
  83
  84        switch (offset) {
  85        case 0:
  86                /* No MUX Set up Needed for GPO */
  87                break;
  88        case 1:
  89                /* Setup the CLKIN_PIN_SEL MUX to GPO2 */
  90                ret = regmap_update_bits(gpio->lp873->regmap, LP873X_REG_CONFIG,
  91                                         LP873X_CONFIG_CLKIN_PIN_SEL, 0);
  92                if (ret)
  93                        return ret;
  94
  95                break;
  96        default:
  97                return -EINVAL;
  98        }
  99
 100        return 0;
 101}
 102
 103static int lp873x_gpio_set_config(struct gpio_chip *gc, unsigned offset,
 104                                  unsigned long config)
 105{
 106        struct lp873x_gpio *gpio = gpiochip_get_data(gc);
 107
 108        switch (pinconf_to_config_param(config)) {
 109        case PIN_CONFIG_DRIVE_OPEN_DRAIN:
 110                return regmap_update_bits(gpio->lp873->regmap,
 111                                          LP873X_REG_GPO_CTRL,
 112                                          BIT(offset * BITS_PER_GPO +
 113                                          LP873X_GPO_CTRL_OD),
 114                                          BIT(offset * BITS_PER_GPO +
 115                                          LP873X_GPO_CTRL_OD));
 116
 117        case PIN_CONFIG_DRIVE_PUSH_PULL:
 118                return regmap_update_bits(gpio->lp873->regmap,
 119                                          LP873X_REG_GPO_CTRL,
 120                                          BIT(offset * BITS_PER_GPO +
 121                                          LP873X_GPO_CTRL_OD), 0);
 122        default:
 123                return -ENOTSUPP;
 124        }
 125}
 126
 127static const struct gpio_chip template_chip = {
 128        .label                  = "lp873x-gpio",
 129        .owner                  = THIS_MODULE,
 130        .request                = lp873x_gpio_request,
 131        .get_direction          = lp873x_gpio_get_direction,
 132        .direction_input        = lp873x_gpio_direction_input,
 133        .direction_output       = lp873x_gpio_direction_output,
 134        .get                    = lp873x_gpio_get,
 135        .set                    = lp873x_gpio_set,
 136        .set_config             = lp873x_gpio_set_config,
 137        .base                   = -1,
 138        .ngpio                  = 2,
 139        .can_sleep              = true,
 140};
 141
 142static int lp873x_gpio_probe(struct platform_device *pdev)
 143{
 144        struct lp873x_gpio *gpio;
 145        int ret;
 146
 147        gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
 148        if (!gpio)
 149                return -ENOMEM;
 150
 151        platform_set_drvdata(pdev, gpio);
 152
 153        gpio->lp873 = dev_get_drvdata(pdev->dev.parent);
 154        gpio->chip = template_chip;
 155        gpio->chip.parent = gpio->lp873->dev;
 156
 157        ret = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
 158        if (ret < 0) {
 159                dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
 160                return ret;
 161        }
 162
 163        return 0;
 164}
 165
 166static const struct platform_device_id lp873x_gpio_id_table[] = {
 167        { "lp873x-gpio", },
 168        { /* sentinel */ }
 169};
 170MODULE_DEVICE_TABLE(platform, lp873x_gpio_id_table);
 171
 172static struct platform_driver lp873x_gpio_driver = {
 173        .driver = {
 174                .name = "lp873x-gpio",
 175        },
 176        .probe = lp873x_gpio_probe,
 177        .id_table = lp873x_gpio_id_table,
 178};
 179module_platform_driver(lp873x_gpio_driver);
 180
 181MODULE_AUTHOR("Keerthy <j-keerthy@ti.com>");
 182MODULE_DESCRIPTION("LP873X GPIO driver");
 183MODULE_LICENSE("GPL v2");
 184