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