root/drivers/gpio/gpio-pisosr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pisosr_gpio_refresh
  2. pisosr_gpio_get_direction
  3. pisosr_gpio_direction_input
  4. pisosr_gpio_direction_output
  5. pisosr_gpio_get
  6. pisosr_gpio_get_multiple
  7. pisosr_gpio_probe
  8. pisosr_gpio_remove

   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 
  15 #include <linux/bitmap.h>
  16 #include <linux/bitops.h>
  17 #include <linux/delay.h>
  18 #include <linux/gpio/consumer.h>
  19 #include <linux/gpio/driver.h>
  20 #include <linux/module.h>
  21 #include <linux/mutex.h>
  22 #include <linux/spi/spi.h>
  23 
  24 #define DEFAULT_NGPIO 8
  25 
  26 /**
  27  * struct pisosr_gpio - GPIO driver data
  28  * @chip: GPIO controller chip
  29  * @spi: SPI device pointer
  30  * @buffer: Buffer for device reads
  31  * @buffer_size: Size of buffer
  32  * @load_gpio: GPIO pin used to load input into device
  33  * @lock: Protects read sequences
  34  */
  35 struct pisosr_gpio {
  36         struct gpio_chip chip;
  37         struct spi_device *spi;
  38         u8 *buffer;
  39         size_t buffer_size;
  40         struct gpio_desc *load_gpio;
  41         struct mutex lock;
  42 };
  43 
  44 static int pisosr_gpio_refresh(struct pisosr_gpio *gpio)
  45 {
  46         int ret;
  47 
  48         mutex_lock(&gpio->lock);
  49 
  50         if (gpio->load_gpio) {
  51                 gpiod_set_value_cansleep(gpio->load_gpio, 1);
  52                 udelay(1); /* registers load time (~10ns) */
  53                 gpiod_set_value_cansleep(gpio->load_gpio, 0);
  54                 udelay(1); /* registers recovery time (~5ns) */
  55         }
  56 
  57         ret = spi_read(gpio->spi, gpio->buffer, gpio->buffer_size);
  58 
  59         mutex_unlock(&gpio->lock);
  60 
  61         return ret;
  62 }
  63 
  64 static int pisosr_gpio_get_direction(struct gpio_chip *chip,
  65                                      unsigned offset)
  66 {
  67         /* This device always input */
  68         return 1;
  69 }
  70 
  71 static int pisosr_gpio_direction_input(struct gpio_chip *chip,
  72                                        unsigned offset)
  73 {
  74         /* This device always input */
  75         return 0;
  76 }
  77 
  78 static int pisosr_gpio_direction_output(struct gpio_chip *chip,
  79                                         unsigned offset, int value)
  80 {
  81         /* This device is input only */
  82         return -EINVAL;
  83 }
  84 
  85 static int pisosr_gpio_get(struct gpio_chip *chip, unsigned offset)
  86 {
  87         struct pisosr_gpio *gpio = gpiochip_get_data(chip);
  88 
  89         /* Refresh may not always be needed */
  90         pisosr_gpio_refresh(gpio);
  91 
  92         return (gpio->buffer[offset / 8] >> (offset % 8)) & 0x1;
  93 }
  94 
  95 static int pisosr_gpio_get_multiple(struct gpio_chip *chip,
  96                                     unsigned long *mask, unsigned long *bits)
  97 {
  98         struct pisosr_gpio *gpio = gpiochip_get_data(chip);
  99         unsigned int nbytes = DIV_ROUND_UP(chip->ngpio, 8);
 100         unsigned int i, j;
 101 
 102         pisosr_gpio_refresh(gpio);
 103 
 104         bitmap_zero(bits, chip->ngpio);
 105         for (i = 0; i < nbytes; i++) {
 106                 j = i / sizeof(unsigned long);
 107                 bits[j] |= ((unsigned long) gpio->buffer[i])
 108                            << (8 * (i % sizeof(unsigned long)));
 109         }
 110 
 111         return 0;
 112 }
 113 
 114 static const struct gpio_chip template_chip = {
 115         .label                  = "pisosr-gpio",
 116         .owner                  = THIS_MODULE,
 117         .get_direction          = pisosr_gpio_get_direction,
 118         .direction_input        = pisosr_gpio_direction_input,
 119         .direction_output       = pisosr_gpio_direction_output,
 120         .get                    = pisosr_gpio_get,
 121         .get_multiple           = pisosr_gpio_get_multiple,
 122         .base                   = -1,
 123         .ngpio                  = DEFAULT_NGPIO,
 124         .can_sleep              = true,
 125 };
 126 
 127 static int pisosr_gpio_probe(struct spi_device *spi)
 128 {
 129         struct device *dev = &spi->dev;
 130         struct pisosr_gpio *gpio;
 131         int ret;
 132 
 133         gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
 134         if (!gpio)
 135                 return -ENOMEM;
 136 
 137         spi_set_drvdata(spi, gpio);
 138 
 139         gpio->chip = template_chip;
 140         gpio->chip.parent = dev;
 141         of_property_read_u16(dev->of_node, "ngpios", &gpio->chip.ngpio);
 142 
 143         gpio->spi = spi;
 144 
 145         gpio->buffer_size = DIV_ROUND_UP(gpio->chip.ngpio, 8);
 146         gpio->buffer = devm_kzalloc(dev, gpio->buffer_size, GFP_KERNEL);
 147         if (!gpio->buffer)
 148                 return -ENOMEM;
 149 
 150         gpio->load_gpio = devm_gpiod_get_optional(dev, "load", GPIOD_OUT_LOW);
 151         if (IS_ERR(gpio->load_gpio)) {
 152                 ret = PTR_ERR(gpio->load_gpio);
 153                 if (ret != -EPROBE_DEFER)
 154                         dev_err(dev, "Unable to allocate load GPIO\n");
 155                 return ret;
 156         }
 157 
 158         mutex_init(&gpio->lock);
 159 
 160         ret = gpiochip_add_data(&gpio->chip, gpio);
 161         if (ret < 0) {
 162                 dev_err(dev, "Unable to register gpiochip\n");
 163                 return ret;
 164         }
 165 
 166         return 0;
 167 }
 168 
 169 static int pisosr_gpio_remove(struct spi_device *spi)
 170 {
 171         struct pisosr_gpio *gpio = spi_get_drvdata(spi);
 172 
 173         gpiochip_remove(&gpio->chip);
 174 
 175         mutex_destroy(&gpio->lock);
 176 
 177         return 0;
 178 }
 179 
 180 static const struct spi_device_id pisosr_gpio_id_table[] = {
 181         { "pisosr-gpio", },
 182         { /* sentinel */ }
 183 };
 184 MODULE_DEVICE_TABLE(spi, pisosr_gpio_id_table);
 185 
 186 static const struct of_device_id pisosr_gpio_of_match_table[] = {
 187         { .compatible = "pisosr-gpio", },
 188         { /* sentinel */ }
 189 };
 190 MODULE_DEVICE_TABLE(of, pisosr_gpio_of_match_table);
 191 
 192 static struct spi_driver pisosr_gpio_driver = {
 193         .driver = {
 194                 .name = "pisosr-gpio",
 195                 .of_match_table = pisosr_gpio_of_match_table,
 196         },
 197         .probe = pisosr_gpio_probe,
 198         .remove = pisosr_gpio_remove,
 199         .id_table = pisosr_gpio_id_table,
 200 };
 201 module_spi_driver(pisosr_gpio_driver);
 202 
 203 MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
 204 MODULE_DESCRIPTION("SPI Compatible PISO Shift Register GPIO Driver");
 205 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */