root/drivers/gpio/gpio-kempld.c

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

DEFINITIONS

This source file includes following definitions.
  1. kempld_gpio_bitop
  2. kempld_gpio_get_bit
  3. kempld_gpio_get
  4. kempld_gpio_set
  5. kempld_gpio_direction_input
  6. kempld_gpio_direction_output
  7. kempld_gpio_get_direction
  8. kempld_gpio_pincount
  9. kempld_gpio_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Kontron PLD GPIO driver
   4  *
   5  * Copyright (c) 2010-2013 Kontron Europe GmbH
   6  * Author: Michael Brunner <michael.brunner@kontron.com>
   7  */
   8 
   9 #include <linux/init.h>
  10 #include <linux/kernel.h>
  11 #include <linux/module.h>
  12 #include <linux/bitops.h>
  13 #include <linux/errno.h>
  14 #include <linux/platform_device.h>
  15 #include <linux/gpio/driver.h>
  16 #include <linux/mfd/kempld.h>
  17 
  18 #define KEMPLD_GPIO_MAX_NUM             16
  19 #define KEMPLD_GPIO_MASK(x)             (BIT((x) % 8))
  20 #define KEMPLD_GPIO_DIR_NUM(x)          (0x40 + (x) / 8)
  21 #define KEMPLD_GPIO_LVL_NUM(x)          (0x42 + (x) / 8)
  22 #define KEMPLD_GPIO_EVT_LVL_EDGE        0x46
  23 #define KEMPLD_GPIO_IEN                 0x4A
  24 
  25 struct kempld_gpio_data {
  26         struct gpio_chip                chip;
  27         struct kempld_device_data       *pld;
  28 };
  29 
  30 /*
  31  * Set or clear GPIO bit
  32  * kempld_get_mutex must be called prior to calling this function.
  33  */
  34 static void kempld_gpio_bitop(struct kempld_device_data *pld,
  35                               u8 reg, u8 bit, u8 val)
  36 {
  37         u8 status;
  38 
  39         status = kempld_read8(pld, reg);
  40         if (val)
  41                 status |= KEMPLD_GPIO_MASK(bit);
  42         else
  43                 status &= ~KEMPLD_GPIO_MASK(bit);
  44         kempld_write8(pld, reg, status);
  45 }
  46 
  47 static int kempld_gpio_get_bit(struct kempld_device_data *pld, u8 reg, u8 bit)
  48 {
  49         u8 status;
  50 
  51         kempld_get_mutex(pld);
  52         status = kempld_read8(pld, reg);
  53         kempld_release_mutex(pld);
  54 
  55         return !!(status & KEMPLD_GPIO_MASK(bit));
  56 }
  57 
  58 static int kempld_gpio_get(struct gpio_chip *chip, unsigned offset)
  59 {
  60         struct kempld_gpio_data *gpio = gpiochip_get_data(chip);
  61         struct kempld_device_data *pld = gpio->pld;
  62 
  63         return !!kempld_gpio_get_bit(pld, KEMPLD_GPIO_LVL_NUM(offset), offset);
  64 }
  65 
  66 static void kempld_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
  67 {
  68         struct kempld_gpio_data *gpio = gpiochip_get_data(chip);
  69         struct kempld_device_data *pld = gpio->pld;
  70 
  71         kempld_get_mutex(pld);
  72         kempld_gpio_bitop(pld, KEMPLD_GPIO_LVL_NUM(offset), offset, value);
  73         kempld_release_mutex(pld);
  74 }
  75 
  76 static int kempld_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
  77 {
  78         struct kempld_gpio_data *gpio = gpiochip_get_data(chip);
  79         struct kempld_device_data *pld = gpio->pld;
  80 
  81         kempld_get_mutex(pld);
  82         kempld_gpio_bitop(pld, KEMPLD_GPIO_DIR_NUM(offset), offset, 0);
  83         kempld_release_mutex(pld);
  84 
  85         return 0;
  86 }
  87 
  88 static int kempld_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
  89                                         int value)
  90 {
  91         struct kempld_gpio_data *gpio = gpiochip_get_data(chip);
  92         struct kempld_device_data *pld = gpio->pld;
  93 
  94         kempld_get_mutex(pld);
  95         kempld_gpio_bitop(pld, KEMPLD_GPIO_LVL_NUM(offset), offset, value);
  96         kempld_gpio_bitop(pld, KEMPLD_GPIO_DIR_NUM(offset), offset, 1);
  97         kempld_release_mutex(pld);
  98 
  99         return 0;
 100 }
 101 
 102 static int kempld_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
 103 {
 104         struct kempld_gpio_data *gpio = gpiochip_get_data(chip);
 105         struct kempld_device_data *pld = gpio->pld;
 106 
 107         return !kempld_gpio_get_bit(pld, KEMPLD_GPIO_DIR_NUM(offset), offset);
 108 }
 109 
 110 static int kempld_gpio_pincount(struct kempld_device_data *pld)
 111 {
 112         u16 evt, evt_back;
 113 
 114         kempld_get_mutex(pld);
 115 
 116         /* Backup event register as it might be already initialized */
 117         evt_back = kempld_read16(pld, KEMPLD_GPIO_EVT_LVL_EDGE);
 118         /* Clear event register */
 119         kempld_write16(pld, KEMPLD_GPIO_EVT_LVL_EDGE, 0x0000);
 120         /* Read back event register */
 121         evt = kempld_read16(pld, KEMPLD_GPIO_EVT_LVL_EDGE);
 122         /* Restore event register */
 123         kempld_write16(pld, KEMPLD_GPIO_EVT_LVL_EDGE, evt_back);
 124 
 125         kempld_release_mutex(pld);
 126 
 127         return evt ? __ffs(evt) : 16;
 128 }
 129 
 130 static int kempld_gpio_probe(struct platform_device *pdev)
 131 {
 132         struct device *dev = &pdev->dev;
 133         struct kempld_device_data *pld = dev_get_drvdata(dev->parent);
 134         struct kempld_platform_data *pdata = dev_get_platdata(pld->dev);
 135         struct kempld_gpio_data *gpio;
 136         struct gpio_chip *chip;
 137         int ret;
 138 
 139         if (pld->info.spec_major < 2) {
 140                 dev_err(dev,
 141                         "Driver only supports GPIO devices compatible to PLD spec. rev. 2.0 or higher\n");
 142                 return -ENODEV;
 143         }
 144 
 145         gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
 146         if (!gpio)
 147                 return -ENOMEM;
 148 
 149         gpio->pld = pld;
 150 
 151         platform_set_drvdata(pdev, gpio);
 152 
 153         chip = &gpio->chip;
 154         chip->label = "gpio-kempld";
 155         chip->owner = THIS_MODULE;
 156         chip->parent = dev;
 157         chip->can_sleep = true;
 158         if (pdata && pdata->gpio_base)
 159                 chip->base = pdata->gpio_base;
 160         else
 161                 chip->base = -1;
 162         chip->direction_input = kempld_gpio_direction_input;
 163         chip->direction_output = kempld_gpio_direction_output;
 164         chip->get_direction = kempld_gpio_get_direction;
 165         chip->get = kempld_gpio_get;
 166         chip->set = kempld_gpio_set;
 167         chip->ngpio = kempld_gpio_pincount(pld);
 168         if (chip->ngpio == 0) {
 169                 dev_err(dev, "No GPIO pins detected\n");
 170                 return -ENODEV;
 171         }
 172 
 173         ret = devm_gpiochip_add_data(dev, chip, gpio);
 174         if (ret) {
 175                 dev_err(dev, "Could not register GPIO chip\n");
 176                 return ret;
 177         }
 178 
 179         dev_info(dev, "GPIO functionality initialized with %d pins\n",
 180                  chip->ngpio);
 181 
 182         return 0;
 183 }
 184 
 185 static struct platform_driver kempld_gpio_driver = {
 186         .driver = {
 187                 .name = "kempld-gpio",
 188         },
 189         .probe          = kempld_gpio_probe,
 190 };
 191 
 192 module_platform_driver(kempld_gpio_driver);
 193 
 194 MODULE_DESCRIPTION("KEM PLD GPIO Driver");
 195 MODULE_AUTHOR("Michael Brunner <michael.brunner@kontron.com>");
 196 MODULE_LICENSE("GPL");
 197 MODULE_ALIAS("platform:kempld-gpio");

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