root/drivers/gpio/gpio-exar.c

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

DEFINITIONS

This source file includes following definitions.
  1. exar_update
  2. exar_set_direction
  3. exar_get
  4. exar_get_direction
  5. exar_get_value
  6. exar_set_value
  7. exar_direction_output
  8. exar_direction_input
  9. gpio_exar_probe
  10. gpio_exar_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * GPIO driver for Exar XR17V35X chip
   4  *
   5  * Copyright (C) 2015 Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
   6  */
   7 #include <linux/bitops.h>
   8 #include <linux/device.h>
   9 #include <linux/gpio/driver.h>
  10 #include <linux/init.h>
  11 #include <linux/kernel.h>
  12 #include <linux/module.h>
  13 #include <linux/pci.h>
  14 #include <linux/platform_device.h>
  15 
  16 #define EXAR_OFFSET_MPIOLVL_LO 0x90
  17 #define EXAR_OFFSET_MPIOSEL_LO 0x93
  18 #define EXAR_OFFSET_MPIOLVL_HI 0x96
  19 #define EXAR_OFFSET_MPIOSEL_HI 0x99
  20 
  21 #define DRIVER_NAME "gpio_exar"
  22 
  23 static DEFINE_IDA(ida_index);
  24 
  25 struct exar_gpio_chip {
  26         struct gpio_chip gpio_chip;
  27         struct mutex lock;
  28         int index;
  29         void __iomem *regs;
  30         char name[20];
  31         unsigned int first_pin;
  32 };
  33 
  34 static void exar_update(struct gpio_chip *chip, unsigned int reg, int val,
  35                         unsigned int offset)
  36 {
  37         struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
  38         int temp;
  39 
  40         mutex_lock(&exar_gpio->lock);
  41         temp = readb(exar_gpio->regs + reg);
  42         temp &= ~BIT(offset);
  43         if (val)
  44                 temp |= BIT(offset);
  45         writeb(temp, exar_gpio->regs + reg);
  46         mutex_unlock(&exar_gpio->lock);
  47 }
  48 
  49 static int exar_set_direction(struct gpio_chip *chip, int direction,
  50                               unsigned int offset)
  51 {
  52         struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
  53         unsigned int addr = (offset + exar_gpio->first_pin) / 8 ?
  54                 EXAR_OFFSET_MPIOSEL_HI : EXAR_OFFSET_MPIOSEL_LO;
  55         unsigned int bit  = (offset + exar_gpio->first_pin) % 8;
  56 
  57         exar_update(chip, addr, direction, bit);
  58         return 0;
  59 }
  60 
  61 static int exar_get(struct gpio_chip *chip, unsigned int reg)
  62 {
  63         struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
  64         int value;
  65 
  66         mutex_lock(&exar_gpio->lock);
  67         value = readb(exar_gpio->regs + reg);
  68         mutex_unlock(&exar_gpio->lock);
  69 
  70         return value;
  71 }
  72 
  73 static int exar_get_direction(struct gpio_chip *chip, unsigned int offset)
  74 {
  75         struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
  76         unsigned int addr = (offset + exar_gpio->first_pin) / 8 ?
  77                 EXAR_OFFSET_MPIOSEL_HI : EXAR_OFFSET_MPIOSEL_LO;
  78         unsigned int bit  = (offset + exar_gpio->first_pin) % 8;
  79 
  80         return !!(exar_get(chip, addr) & BIT(bit));
  81 }
  82 
  83 static int exar_get_value(struct gpio_chip *chip, unsigned int offset)
  84 {
  85         struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
  86         unsigned int addr = (offset + exar_gpio->first_pin) / 8 ?
  87                 EXAR_OFFSET_MPIOLVL_HI : EXAR_OFFSET_MPIOLVL_LO;
  88         unsigned int bit  = (offset + exar_gpio->first_pin) % 8;
  89 
  90         return !!(exar_get(chip, addr) & BIT(bit));
  91 }
  92 
  93 static void exar_set_value(struct gpio_chip *chip, unsigned int offset,
  94                            int value)
  95 {
  96         struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
  97         unsigned int addr = (offset + exar_gpio->first_pin) / 8 ?
  98                 EXAR_OFFSET_MPIOLVL_HI : EXAR_OFFSET_MPIOLVL_LO;
  99         unsigned int bit  = (offset + exar_gpio->first_pin) % 8;
 100 
 101         exar_update(chip, addr, value, bit);
 102 }
 103 
 104 static int exar_direction_output(struct gpio_chip *chip, unsigned int offset,
 105                                  int value)
 106 {
 107         exar_set_value(chip, offset, value);
 108         return exar_set_direction(chip, 0, offset);
 109 }
 110 
 111 static int exar_direction_input(struct gpio_chip *chip, unsigned int offset)
 112 {
 113         return exar_set_direction(chip, 1, offset);
 114 }
 115 
 116 static int gpio_exar_probe(struct platform_device *pdev)
 117 {
 118         struct pci_dev *pcidev = to_pci_dev(pdev->dev.parent);
 119         struct exar_gpio_chip *exar_gpio;
 120         u32 first_pin, ngpios;
 121         void __iomem *p;
 122         int index, ret;
 123 
 124         /*
 125          * The UART driver must have mapped region 0 prior to registering this
 126          * device - use it.
 127          */
 128         p = pcim_iomap_table(pcidev)[0];
 129         if (!p)
 130                 return -ENOMEM;
 131 
 132         ret = device_property_read_u32(&pdev->dev, "exar,first-pin",
 133                                        &first_pin);
 134         if (ret)
 135                 return ret;
 136 
 137         ret = device_property_read_u32(&pdev->dev, "ngpios", &ngpios);
 138         if (ret)
 139                 return ret;
 140 
 141         exar_gpio = devm_kzalloc(&pdev->dev, sizeof(*exar_gpio), GFP_KERNEL);
 142         if (!exar_gpio)
 143                 return -ENOMEM;
 144 
 145         mutex_init(&exar_gpio->lock);
 146 
 147         index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL);
 148         if (index < 0) {
 149                 ret = index;
 150                 goto err_mutex_destroy;
 151         }
 152 
 153         sprintf(exar_gpio->name, "exar_gpio%d", index);
 154         exar_gpio->gpio_chip.label = exar_gpio->name;
 155         exar_gpio->gpio_chip.parent = &pdev->dev;
 156         exar_gpio->gpio_chip.direction_output = exar_direction_output;
 157         exar_gpio->gpio_chip.direction_input = exar_direction_input;
 158         exar_gpio->gpio_chip.get_direction = exar_get_direction;
 159         exar_gpio->gpio_chip.get = exar_get_value;
 160         exar_gpio->gpio_chip.set = exar_set_value;
 161         exar_gpio->gpio_chip.base = -1;
 162         exar_gpio->gpio_chip.ngpio = ngpios;
 163         exar_gpio->regs = p;
 164         exar_gpio->index = index;
 165         exar_gpio->first_pin = first_pin;
 166 
 167         ret = devm_gpiochip_add_data(&pdev->dev,
 168                                      &exar_gpio->gpio_chip, exar_gpio);
 169         if (ret)
 170                 goto err_destroy;
 171 
 172         platform_set_drvdata(pdev, exar_gpio);
 173 
 174         return 0;
 175 
 176 err_destroy:
 177         ida_simple_remove(&ida_index, index);
 178 err_mutex_destroy:
 179         mutex_destroy(&exar_gpio->lock);
 180         return ret;
 181 }
 182 
 183 static int gpio_exar_remove(struct platform_device *pdev)
 184 {
 185         struct exar_gpio_chip *exar_gpio = platform_get_drvdata(pdev);
 186 
 187         ida_simple_remove(&ida_index, exar_gpio->index);
 188         mutex_destroy(&exar_gpio->lock);
 189 
 190         return 0;
 191 }
 192 
 193 static struct platform_driver gpio_exar_driver = {
 194         .probe  = gpio_exar_probe,
 195         .remove = gpio_exar_remove,
 196         .driver = {
 197                 .name = DRIVER_NAME,
 198         },
 199 };
 200 
 201 module_platform_driver(gpio_exar_driver);
 202 
 203 MODULE_ALIAS("platform:" DRIVER_NAME);
 204 MODULE_DESCRIPTION("Exar GPIO driver");
 205 MODULE_AUTHOR("Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>");
 206 MODULE_LICENSE("GPL");

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