Lines Matching +full:gpio +full:- +full:bank
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Broadcom Kona GPIO Driver
5 * Author: Broadcom Corporation <bcm-kernel-feedback-list@broadcom.com>
6 * Copyright (C) 2012-2014 Broadcom Corporation
11 #include <linux/gpio/driver.h>
24 #define GPIO_BANK(gpio) ((gpio) >> 5) argument
25 #define GPIO_BIT(gpio) ((gpio) & (GPIO_PER_BANK - 1)) argument
27 /* There is a GPIO control register for each GPIO */
28 #define GPIO_CONTROL(gpio) (0x00000100 + ((gpio) << 2)) argument
30 /* The remaining registers are per GPIO bank */
31 #define GPIO_OUT_STATUS(bank) (0x00000000 + ((bank) << 2)) argument
32 #define GPIO_IN_STATUS(bank) (0x00000020 + ((bank) << 2)) argument
33 #define GPIO_OUT_SET(bank) (0x00000040 + ((bank) << 2)) argument
34 #define GPIO_OUT_CLEAR(bank) (0x00000060 + ((bank) << 2)) argument
35 #define GPIO_INT_STATUS(bank) (0x00000080 + ((bank) << 2)) argument
36 #define GPIO_INT_MASK(bank) (0x000000a0 + ((bank) << 2)) argument
37 #define GPIO_INT_MSKCLR(bank) (0x000000c0 + ((bank) << 2)) argument
38 #define GPIO_PWD_STATUS(bank) (0x00000500 + ((bank) << 2)) argument
84 unsigned gpio) in bcm_kona_gpio_lock_gpio() argument
88 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_lock_gpio()
90 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_lock_gpio()
92 val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); in bcm_kona_gpio_lock_gpio()
93 val |= BIT(gpio); in bcm_kona_gpio_lock_gpio()
94 bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); in bcm_kona_gpio_lock_gpio()
96 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_lock_gpio()
100 unsigned gpio) in bcm_kona_gpio_unlock_gpio() argument
104 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_unlock_gpio()
106 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_unlock_gpio()
108 val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); in bcm_kona_gpio_unlock_gpio()
109 val &= ~BIT(gpio); in bcm_kona_gpio_unlock_gpio()
110 bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); in bcm_kona_gpio_unlock_gpio()
112 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_unlock_gpio()
115 static int bcm_kona_gpio_get_dir(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_get_dir() argument
118 void __iomem *reg_base = kona_gpio->reg_base; in bcm_kona_gpio_get_dir()
121 val = readl(reg_base + GPIO_CONTROL(gpio)) & GPIO_GPCTR0_IOTR_MASK; in bcm_kona_gpio_get_dir()
125 static void bcm_kona_gpio_set(struct gpio_chip *chip, unsigned gpio, int value) in bcm_kona_gpio_set() argument
129 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_set()
130 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_set()
135 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_set()
136 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_set()
139 if (bcm_kona_gpio_get_dir(chip, gpio) == GPIO_LINE_DIRECTION_IN) in bcm_kona_gpio_set()
149 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_set()
152 static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_get() argument
156 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_get()
157 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_get()
162 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_get()
163 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_get()
165 if (bcm_kona_gpio_get_dir(chip, gpio) == GPIO_LINE_DIRECTION_IN) in bcm_kona_gpio_get()
170 /* read the GPIO bank status */ in bcm_kona_gpio_get()
173 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_get()
179 static int bcm_kona_gpio_request(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_request() argument
183 bcm_kona_gpio_unlock_gpio(kona_gpio, gpio); in bcm_kona_gpio_request()
187 static void bcm_kona_gpio_free(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_free() argument
191 bcm_kona_gpio_lock_gpio(kona_gpio, gpio); in bcm_kona_gpio_free()
194 static int bcm_kona_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_direction_input() argument
202 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_direction_input()
203 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_direction_input()
205 val = readl(reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_direction_input()
208 writel(val, reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_direction_input()
210 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_direction_input()
216 unsigned gpio, int value) in bcm_kona_gpio_direction_output() argument
220 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_direction_output()
221 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_direction_output()
226 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_direction_output()
227 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_direction_output()
229 val = readl(reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_direction_output()
232 writel(val, reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_direction_output()
239 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_direction_output()
244 static int bcm_kona_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_to_irq() argument
249 if (gpio >= kona_gpio->gpio_chip.ngpio) in bcm_kona_gpio_to_irq()
250 return -ENXIO; in bcm_kona_gpio_to_irq()
251 return irq_create_mapping(kona_gpio->irq_domain, gpio); in bcm_kona_gpio_to_irq()
254 static int bcm_kona_gpio_set_debounce(struct gpio_chip *chip, unsigned gpio, in bcm_kona_gpio_set_debounce() argument
263 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_set_debounce()
264 /* debounce must be 1-128ms (or 0) */ in bcm_kona_gpio_set_debounce()
266 dev_err(chip->parent, "Debounce value %u not in range\n", in bcm_kona_gpio_set_debounce()
268 return -EINVAL; in bcm_kona_gpio_set_debounce()
276 res = fls(debounce) - 1; in bcm_kona_gpio_set_debounce()
277 /* Check if MSB-1 is set (round up or down) */ in bcm_kona_gpio_set_debounce()
278 if (res > 0 && (debounce & BIT(res - 1))) in bcm_kona_gpio_set_debounce()
282 /* spin lock for read-modify-write of the GPIO register */ in bcm_kona_gpio_set_debounce()
283 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_set_debounce()
285 val = readl(reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_set_debounce()
296 writel(val, reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_set_debounce()
298 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_set_debounce()
303 static int bcm_kona_gpio_set_config(struct gpio_chip *chip, unsigned gpio, in bcm_kona_gpio_set_config() argument
309 return -ENOTSUPP; in bcm_kona_gpio_set_config()
312 return bcm_kona_gpio_set_debounce(chip, gpio, debounce); in bcm_kona_gpio_set_config()
316 .label = "bcm-kona-gpio",
334 unsigned gpio = d->hwirq; in bcm_kona_gpio_irq_ack() local
335 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_irq_ack()
336 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_irq_ack()
341 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_irq_ack()
342 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_ack()
348 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_ack()
355 unsigned gpio = d->hwirq; in bcm_kona_gpio_irq_mask() local
356 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_irq_mask()
357 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_irq_mask()
362 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_irq_mask()
363 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_mask()
368 gpiochip_disable_irq(&kona_gpio->gpio_chip, gpio); in bcm_kona_gpio_irq_mask()
370 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_mask()
377 unsigned gpio = d->hwirq; in bcm_kona_gpio_irq_unmask() local
378 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_irq_unmask()
379 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_irq_unmask()
384 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_irq_unmask()
385 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_unmask()
390 gpiochip_enable_irq(&kona_gpio->gpio_chip, gpio); in bcm_kona_gpio_irq_unmask()
392 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_unmask()
399 unsigned gpio = d->hwirq; in bcm_kona_gpio_irq_set_type() local
405 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_irq_set_type()
421 /* BCM GPIO doesn't support level triggering */ in bcm_kona_gpio_irq_set_type()
423 dev_err(kona_gpio->gpio_chip.parent, in bcm_kona_gpio_irq_set_type()
424 "Invalid BCM GPIO irq type 0x%x\n", type); in bcm_kona_gpio_irq_set_type()
425 return -EINVAL; in bcm_kona_gpio_irq_set_type()
428 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_set_type()
430 val = readl(reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_irq_set_type()
433 writel(val, reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_irq_set_type()
435 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_set_type()
445 struct bcm_kona_gpio_bank *bank = irq_desc_get_handler_data(desc); in bcm_kona_gpio_irq_handler() local
451 * For bank interrupts, we can't use chip_data to store the kona_gpio in bcm_kona_gpio_irq_handler()
453 * our pointer from the bank structure. in bcm_kona_gpio_irq_handler()
455 reg_base = bank->kona_gpio->reg_base; in bcm_kona_gpio_irq_handler()
456 bank_id = bank->id; in bcm_kona_gpio_irq_handler()
469 generic_handle_domain_irq(bank->kona_gpio->irq_domain, in bcm_kona_gpio_irq_handler()
481 return gpiochip_reqres_irq(&kona_gpio->gpio_chip, d->hwirq); in bcm_kona_gpio_irq_reqres()
488 gpiochip_relres_irq(&kona_gpio->gpio_chip, d->hwirq); in bcm_kona_gpio_irq_relres()
492 .name = "bcm-kona-gpio",
502 { .compatible = "brcm,kona-gpio" },
507 * This lock class tells lockdep that GPIO irqs are in a different
518 ret = irq_set_chip_data(irq, d->host_data); in bcm_kona_gpio_irq_map()
545 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_reset()
547 for (i = 0; i < kona_gpio->num_bank; i++) { in bcm_kona_gpio_reset()
548 /* Unlock the entire bank first */ in bcm_kona_gpio_reset()
552 /* Now re-lock the bank */ in bcm_kona_gpio_reset()
559 struct device *dev = &pdev->dev; in bcm_kona_gpio_probe()
560 struct bcm_kona_gpio_bank *bank; in bcm_kona_gpio_probe() local
568 return -ENOMEM; in bcm_kona_gpio_probe()
570 kona_gpio->gpio_chip = template_chip; in bcm_kona_gpio_probe()
571 chip = &kona_gpio->gpio_chip; in bcm_kona_gpio_probe()
574 dev_err(dev, "Couldn't determine # GPIO banks\n"); in bcm_kona_gpio_probe()
575 return -ENOENT; in bcm_kona_gpio_probe()
577 return dev_err_probe(dev, ret, "Couldn't determine GPIO banks\n"); in bcm_kona_gpio_probe()
579 kona_gpio->num_bank = ret; in bcm_kona_gpio_probe()
581 if (kona_gpio->num_bank > GPIO_MAX_BANK_NUM) { in bcm_kona_gpio_probe()
582 dev_err(dev, "Too many GPIO banks configured (max=%d)\n", in bcm_kona_gpio_probe()
584 return -ENXIO; in bcm_kona_gpio_probe()
586 kona_gpio->banks = devm_kcalloc(dev, in bcm_kona_gpio_probe()
587 kona_gpio->num_bank, in bcm_kona_gpio_probe()
588 sizeof(*kona_gpio->banks), in bcm_kona_gpio_probe()
590 if (!kona_gpio->banks) in bcm_kona_gpio_probe()
591 return -ENOMEM; in bcm_kona_gpio_probe()
593 chip->parent = dev; in bcm_kona_gpio_probe()
594 chip->ngpio = kona_gpio->num_bank * GPIO_PER_BANK; in bcm_kona_gpio_probe()
596 kona_gpio->irq_domain = irq_domain_create_linear(dev_fwnode(dev), in bcm_kona_gpio_probe()
597 chip->ngpio, in bcm_kona_gpio_probe()
600 if (!kona_gpio->irq_domain) { in bcm_kona_gpio_probe()
602 return -ENXIO; in bcm_kona_gpio_probe()
605 kona_gpio->reg_base = devm_platform_ioremap_resource(pdev, 0); in bcm_kona_gpio_probe()
606 if (IS_ERR(kona_gpio->reg_base)) { in bcm_kona_gpio_probe()
607 ret = PTR_ERR(kona_gpio->reg_base); in bcm_kona_gpio_probe()
611 for (i = 0; i < kona_gpio->num_bank; i++) { in bcm_kona_gpio_probe()
612 bank = &kona_gpio->banks[i]; in bcm_kona_gpio_probe()
613 bank->id = i; in bcm_kona_gpio_probe()
614 bank->irq = platform_get_irq(pdev, i); in bcm_kona_gpio_probe()
615 bank->kona_gpio = kona_gpio; in bcm_kona_gpio_probe()
616 if (bank->irq < 0) { in bcm_kona_gpio_probe()
617 dev_err(dev, "Couldn't get IRQ for bank %d", i); in bcm_kona_gpio_probe()
618 ret = -ENOENT; in bcm_kona_gpio_probe()
623 dev_info(&pdev->dev, "Setting up Kona GPIO\n"); in bcm_kona_gpio_probe()
629 dev_err(dev, "Couldn't add GPIO chip -- %d\n", ret); in bcm_kona_gpio_probe()
632 for (i = 0; i < kona_gpio->num_bank; i++) { in bcm_kona_gpio_probe()
633 bank = &kona_gpio->banks[i]; in bcm_kona_gpio_probe()
634 irq_set_chained_handler_and_data(bank->irq, in bcm_kona_gpio_probe()
636 bank); in bcm_kona_gpio_probe()
639 raw_spin_lock_init(&kona_gpio->lock); in bcm_kona_gpio_probe()
644 irq_domain_remove(kona_gpio->irq_domain); in bcm_kona_gpio_probe()
651 .name = "bcm-kona-gpio",