root/drivers/gpio/gpio-menz127.c

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

DEFINITIONS

This source file includes following definitions.
  1. men_z127_debounce
  2. men_z127_set_single_ended
  3. men_z127_set_config
  4. men_z127_probe
  5. men_z127_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * MEN 16Z127 GPIO driver
   4  *
   5  * Copyright (C) 2016 MEN Mikroelektronik GmbH (www.men.de)
   6  */
   7 
   8 #include <linux/kernel.h>
   9 #include <linux/module.h>
  10 #include <linux/io.h>
  11 #include <linux/err.h>
  12 #include <linux/mcb.h>
  13 #include <linux/bitops.h>
  14 #include <linux/gpio/driver.h>
  15 
  16 #define MEN_Z127_CTRL   0x00
  17 #define MEN_Z127_PSR    0x04
  18 #define MEN_Z127_IRQR   0x08
  19 #define MEN_Z127_GPIODR 0x0c
  20 #define MEN_Z127_IER1   0x10
  21 #define MEN_Z127_IER2   0x14
  22 #define MEN_Z127_DBER   0x18
  23 #define MEN_Z127_ODER   0x1C
  24 #define GPIO_TO_DBCNT_REG(gpio) ((gpio * 4) + 0x80)
  25 
  26 #define MEN_Z127_DB_MIN_US      50
  27 /* 16 bit compare register. Each bit represents 50us */
  28 #define MEN_Z127_DB_MAX_US      (0xffff * MEN_Z127_DB_MIN_US)
  29 #define MEN_Z127_DB_IN_RANGE(db)        ((db >= MEN_Z127_DB_MIN_US) && \
  30                                          (db <= MEN_Z127_DB_MAX_US))
  31 
  32 struct men_z127_gpio {
  33         struct gpio_chip gc;
  34         void __iomem *reg_base;
  35         struct resource *mem;
  36 };
  37 
  38 static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio,
  39                              unsigned debounce)
  40 {
  41         struct men_z127_gpio *priv = gpiochip_get_data(gc);
  42         struct device *dev = gc->parent;
  43         unsigned int rnd;
  44         u32 db_en, db_cnt;
  45 
  46         if (!MEN_Z127_DB_IN_RANGE(debounce)) {
  47                 dev_err(dev, "debounce value %u out of range", debounce);
  48                 return -EINVAL;
  49         }
  50 
  51         if (debounce > 0) {
  52                 /* round up or down depending on MSB-1 */
  53                 rnd = fls(debounce) - 1;
  54 
  55                 if (rnd && (debounce & BIT(rnd - 1)))
  56                         debounce = roundup(debounce, MEN_Z127_DB_MIN_US);
  57                 else
  58                         debounce = rounddown(debounce, MEN_Z127_DB_MIN_US);
  59 
  60                 if (debounce > MEN_Z127_DB_MAX_US)
  61                         debounce = MEN_Z127_DB_MAX_US;
  62 
  63                 /* 50us per register unit */
  64                 debounce /= 50;
  65         }
  66 
  67         spin_lock(&gc->bgpio_lock);
  68 
  69         db_en = readl(priv->reg_base + MEN_Z127_DBER);
  70 
  71         if (debounce == 0) {
  72                 db_en &= ~BIT(gpio);
  73                 db_cnt = 0;
  74         } else {
  75                 db_en |= BIT(gpio);
  76                 db_cnt = debounce;
  77         }
  78 
  79         writel(db_en, priv->reg_base + MEN_Z127_DBER);
  80         writel(db_cnt, priv->reg_base + GPIO_TO_DBCNT_REG(gpio));
  81 
  82         spin_unlock(&gc->bgpio_lock);
  83 
  84         return 0;
  85 }
  86 
  87 static int men_z127_set_single_ended(struct gpio_chip *gc,
  88                                      unsigned offset,
  89                                      enum pin_config_param param)
  90 {
  91         struct men_z127_gpio *priv = gpiochip_get_data(gc);
  92         u32 od_en;
  93 
  94         spin_lock(&gc->bgpio_lock);
  95         od_en = readl(priv->reg_base + MEN_Z127_ODER);
  96 
  97         if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN)
  98                 od_en |= BIT(offset);
  99         else
 100                 /* Implicitly PIN_CONFIG_DRIVE_PUSH_PULL */
 101                 od_en &= ~BIT(offset);
 102 
 103         writel(od_en, priv->reg_base + MEN_Z127_ODER);
 104         spin_unlock(&gc->bgpio_lock);
 105 
 106         return 0;
 107 }
 108 
 109 static int men_z127_set_config(struct gpio_chip *gc, unsigned offset,
 110                                unsigned long config)
 111 {
 112         enum pin_config_param param = pinconf_to_config_param(config);
 113 
 114         switch (param) {
 115         case PIN_CONFIG_DRIVE_OPEN_DRAIN:
 116         case PIN_CONFIG_DRIVE_PUSH_PULL:
 117                 return men_z127_set_single_ended(gc, offset, param);
 118 
 119         case PIN_CONFIG_INPUT_DEBOUNCE:
 120                 return men_z127_debounce(gc, offset,
 121                         pinconf_to_config_argument(config));
 122 
 123         default:
 124                 break;
 125         }
 126 
 127         return -ENOTSUPP;
 128 }
 129 
 130 static int men_z127_probe(struct mcb_device *mdev,
 131                           const struct mcb_device_id *id)
 132 {
 133         struct men_z127_gpio *men_z127_gpio;
 134         struct device *dev = &mdev->dev;
 135         int ret;
 136 
 137         men_z127_gpio = devm_kzalloc(dev, sizeof(struct men_z127_gpio),
 138                                      GFP_KERNEL);
 139         if (!men_z127_gpio)
 140                 return -ENOMEM;
 141 
 142         men_z127_gpio->mem = mcb_request_mem(mdev, dev_name(dev));
 143         if (IS_ERR(men_z127_gpio->mem)) {
 144                 dev_err(dev, "failed to request device memory");
 145                 return PTR_ERR(men_z127_gpio->mem);
 146         }
 147 
 148         men_z127_gpio->reg_base = ioremap(men_z127_gpio->mem->start,
 149                                           resource_size(men_z127_gpio->mem));
 150         if (men_z127_gpio->reg_base == NULL) {
 151                 ret = -ENXIO;
 152                 goto err_release;
 153         }
 154 
 155         mcb_set_drvdata(mdev, men_z127_gpio);
 156 
 157         ret = bgpio_init(&men_z127_gpio->gc, &mdev->dev, 4,
 158                          men_z127_gpio->reg_base + MEN_Z127_PSR,
 159                          men_z127_gpio->reg_base + MEN_Z127_CTRL,
 160                          NULL,
 161                          men_z127_gpio->reg_base + MEN_Z127_GPIODR,
 162                          NULL, 0);
 163         if (ret)
 164                 goto err_unmap;
 165 
 166         men_z127_gpio->gc.set_config = men_z127_set_config;
 167 
 168         ret = gpiochip_add_data(&men_z127_gpio->gc, men_z127_gpio);
 169         if (ret) {
 170                 dev_err(dev, "failed to register MEN 16Z127 GPIO controller");
 171                 goto err_unmap;
 172         }
 173 
 174         dev_info(dev, "MEN 16Z127 GPIO driver registered");
 175 
 176         return 0;
 177 
 178 err_unmap:
 179         iounmap(men_z127_gpio->reg_base);
 180 err_release:
 181         mcb_release_mem(men_z127_gpio->mem);
 182         return ret;
 183 }
 184 
 185 static void men_z127_remove(struct mcb_device *mdev)
 186 {
 187         struct men_z127_gpio *men_z127_gpio = mcb_get_drvdata(mdev);
 188 
 189         gpiochip_remove(&men_z127_gpio->gc);
 190         iounmap(men_z127_gpio->reg_base);
 191         mcb_release_mem(men_z127_gpio->mem);
 192 }
 193 
 194 static const struct mcb_device_id men_z127_ids[] = {
 195         { .device = 0x7f },
 196         { }
 197 };
 198 MODULE_DEVICE_TABLE(mcb, men_z127_ids);
 199 
 200 static struct mcb_driver men_z127_driver = {
 201         .driver = {
 202                 .name = "z127-gpio",
 203         },
 204         .probe = men_z127_probe,
 205         .remove = men_z127_remove,
 206         .id_table = men_z127_ids,
 207 };
 208 module_mcb_driver(men_z127_driver);
 209 
 210 MODULE_AUTHOR("Andreas Werner <andreas.werner@men.de>");
 211 MODULE_DESCRIPTION("MEN 16z127 GPIO Controller");
 212 MODULE_LICENSE("GPL v2");
 213 MODULE_ALIAS("mcb:16z127");

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