Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * MEN 16Z127 GPIO driver
0004  *
0005  * Copyright (C) 2016 MEN Mikroelektronik GmbH (www.men.de)
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/module.h>
0010 #include <linux/io.h>
0011 #include <linux/err.h>
0012 #include <linux/mcb.h>
0013 #include <linux/bitops.h>
0014 #include <linux/gpio/driver.h>
0015 
0016 #define MEN_Z127_CTRL   0x00
0017 #define MEN_Z127_PSR    0x04
0018 #define MEN_Z127_IRQR   0x08
0019 #define MEN_Z127_GPIODR 0x0c
0020 #define MEN_Z127_IER1   0x10
0021 #define MEN_Z127_IER2   0x14
0022 #define MEN_Z127_DBER   0x18
0023 #define MEN_Z127_ODER   0x1C
0024 #define GPIO_TO_DBCNT_REG(gpio) ((gpio * 4) + 0x80)
0025 
0026 #define MEN_Z127_DB_MIN_US  50
0027 /* 16 bit compare register. Each bit represents 50us */
0028 #define MEN_Z127_DB_MAX_US  (0xffff * MEN_Z127_DB_MIN_US)
0029 #define MEN_Z127_DB_IN_RANGE(db)    ((db >= MEN_Z127_DB_MIN_US) && \
0030                      (db <= MEN_Z127_DB_MAX_US))
0031 
0032 struct men_z127_gpio {
0033     struct gpio_chip gc;
0034     void __iomem *reg_base;
0035     struct resource *mem;
0036 };
0037 
0038 static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio,
0039                  unsigned debounce)
0040 {
0041     struct men_z127_gpio *priv = gpiochip_get_data(gc);
0042     struct device *dev = gc->parent;
0043     unsigned int rnd;
0044     u32 db_en, db_cnt;
0045 
0046     if (!MEN_Z127_DB_IN_RANGE(debounce)) {
0047         dev_err(dev, "debounce value %u out of range", debounce);
0048         return -EINVAL;
0049     }
0050 
0051     if (debounce > 0) {
0052         /* round up or down depending on MSB-1 */
0053         rnd = fls(debounce) - 1;
0054 
0055         if (rnd && (debounce & BIT(rnd - 1)))
0056             debounce = roundup(debounce, MEN_Z127_DB_MIN_US);
0057         else
0058             debounce = rounddown(debounce, MEN_Z127_DB_MIN_US);
0059 
0060         if (debounce > MEN_Z127_DB_MAX_US)
0061             debounce = MEN_Z127_DB_MAX_US;
0062 
0063         /* 50us per register unit */
0064         debounce /= 50;
0065     }
0066 
0067     raw_spin_lock(&gc->bgpio_lock);
0068 
0069     db_en = readl(priv->reg_base + MEN_Z127_DBER);
0070 
0071     if (debounce == 0) {
0072         db_en &= ~BIT(gpio);
0073         db_cnt = 0;
0074     } else {
0075         db_en |= BIT(gpio);
0076         db_cnt = debounce;
0077     }
0078 
0079     writel(db_en, priv->reg_base + MEN_Z127_DBER);
0080     writel(db_cnt, priv->reg_base + GPIO_TO_DBCNT_REG(gpio));
0081 
0082     raw_spin_unlock(&gc->bgpio_lock);
0083 
0084     return 0;
0085 }
0086 
0087 static int men_z127_set_single_ended(struct gpio_chip *gc,
0088                      unsigned offset,
0089                      enum pin_config_param param)
0090 {
0091     struct men_z127_gpio *priv = gpiochip_get_data(gc);
0092     u32 od_en;
0093 
0094     raw_spin_lock(&gc->bgpio_lock);
0095     od_en = readl(priv->reg_base + MEN_Z127_ODER);
0096 
0097     if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN)
0098         od_en |= BIT(offset);
0099     else
0100         /* Implicitly PIN_CONFIG_DRIVE_PUSH_PULL */
0101         od_en &= ~BIT(offset);
0102 
0103     writel(od_en, priv->reg_base + MEN_Z127_ODER);
0104     raw_spin_unlock(&gc->bgpio_lock);
0105 
0106     return 0;
0107 }
0108 
0109 static int men_z127_set_config(struct gpio_chip *gc, unsigned offset,
0110                    unsigned long config)
0111 {
0112     enum pin_config_param param = pinconf_to_config_param(config);
0113 
0114     switch (param) {
0115     case PIN_CONFIG_DRIVE_OPEN_DRAIN:
0116     case PIN_CONFIG_DRIVE_PUSH_PULL:
0117         return men_z127_set_single_ended(gc, offset, param);
0118 
0119     case PIN_CONFIG_INPUT_DEBOUNCE:
0120         return men_z127_debounce(gc, offset,
0121             pinconf_to_config_argument(config));
0122 
0123     default:
0124         break;
0125     }
0126 
0127     return -ENOTSUPP;
0128 }
0129 
0130 static int men_z127_probe(struct mcb_device *mdev,
0131               const struct mcb_device_id *id)
0132 {
0133     struct men_z127_gpio *men_z127_gpio;
0134     struct device *dev = &mdev->dev;
0135     int ret;
0136 
0137     men_z127_gpio = devm_kzalloc(dev, sizeof(struct men_z127_gpio),
0138                      GFP_KERNEL);
0139     if (!men_z127_gpio)
0140         return -ENOMEM;
0141 
0142     men_z127_gpio->mem = mcb_request_mem(mdev, dev_name(dev));
0143     if (IS_ERR(men_z127_gpio->mem)) {
0144         dev_err(dev, "failed to request device memory");
0145         return PTR_ERR(men_z127_gpio->mem);
0146     }
0147 
0148     men_z127_gpio->reg_base = ioremap(men_z127_gpio->mem->start,
0149                       resource_size(men_z127_gpio->mem));
0150     if (men_z127_gpio->reg_base == NULL) {
0151         ret = -ENXIO;
0152         goto err_release;
0153     }
0154 
0155     mcb_set_drvdata(mdev, men_z127_gpio);
0156 
0157     ret = bgpio_init(&men_z127_gpio->gc, &mdev->dev, 4,
0158              men_z127_gpio->reg_base + MEN_Z127_PSR,
0159              men_z127_gpio->reg_base + MEN_Z127_CTRL,
0160              NULL,
0161              men_z127_gpio->reg_base + MEN_Z127_GPIODR,
0162              NULL, 0);
0163     if (ret)
0164         goto err_unmap;
0165 
0166     men_z127_gpio->gc.set_config = men_z127_set_config;
0167 
0168     ret = gpiochip_add_data(&men_z127_gpio->gc, men_z127_gpio);
0169     if (ret) {
0170         dev_err(dev, "failed to register MEN 16Z127 GPIO controller");
0171         goto err_unmap;
0172     }
0173 
0174     dev_info(dev, "MEN 16Z127 GPIO driver registered");
0175 
0176     return 0;
0177 
0178 err_unmap:
0179     iounmap(men_z127_gpio->reg_base);
0180 err_release:
0181     mcb_release_mem(men_z127_gpio->mem);
0182     return ret;
0183 }
0184 
0185 static void men_z127_remove(struct mcb_device *mdev)
0186 {
0187     struct men_z127_gpio *men_z127_gpio = mcb_get_drvdata(mdev);
0188 
0189     gpiochip_remove(&men_z127_gpio->gc);
0190     iounmap(men_z127_gpio->reg_base);
0191     mcb_release_mem(men_z127_gpio->mem);
0192 }
0193 
0194 static const struct mcb_device_id men_z127_ids[] = {
0195     { .device = 0x7f },
0196     { }
0197 };
0198 MODULE_DEVICE_TABLE(mcb, men_z127_ids);
0199 
0200 static struct mcb_driver men_z127_driver = {
0201     .driver = {
0202         .name = "z127-gpio",
0203     },
0204     .probe = men_z127_probe,
0205     .remove = men_z127_remove,
0206     .id_table = men_z127_ids,
0207 };
0208 module_mcb_driver(men_z127_driver);
0209 
0210 MODULE_AUTHOR("Andreas Werner <andreas.werner@men.de>");
0211 MODULE_DESCRIPTION("MEN 16z127 GPIO Controller");
0212 MODULE_LICENSE("GPL v2");
0213 MODULE_ALIAS("mcb:16z127");
0214 MODULE_IMPORT_NS(MCB);