Lines Matching +full:- +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
12 #include <linux/gpio/driver.h>
22 #define GPIO_BANK(gpio) ((gpio) >> 5) argument
23 #define GPIO_BIT(gpio) ((gpio) & (GPIO_PER_BANK - 1)) argument
25 /* There is a GPIO control register for each GPIO */
26 #define GPIO_CONTROL(gpio) (0x00000100 + ((gpio) << 2)) argument
28 /* The remaining registers are per GPIO bank */
29 #define GPIO_OUT_STATUS(bank) (0x00000000 + ((bank) << 2)) argument
30 #define GPIO_IN_STATUS(bank) (0x00000020 + ((bank) << 2)) argument
31 #define GPIO_OUT_SET(bank) (0x00000040 + ((bank) << 2)) argument
32 #define GPIO_OUT_CLEAR(bank) (0x00000060 + ((bank) << 2)) argument
33 #define GPIO_INT_STATUS(bank) (0x00000080 + ((bank) << 2)) argument
34 #define GPIO_INT_MASK(bank) (0x000000a0 + ((bank) << 2)) argument
35 #define GPIO_INT_MSKCLR(bank) (0x000000c0 + ((bank) << 2)) argument
36 #define GPIO_PWD_STATUS(bank) (0x00000500 + ((bank) << 2)) argument
83 unsigned gpio) in bcm_kona_gpio_lock_gpio() argument
87 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_lock_gpio()
89 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_lock_gpio()
91 val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); in bcm_kona_gpio_lock_gpio()
92 val |= BIT(gpio); in bcm_kona_gpio_lock_gpio()
93 bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); in bcm_kona_gpio_lock_gpio()
95 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_lock_gpio()
99 unsigned gpio) in bcm_kona_gpio_unlock_gpio() argument
103 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_unlock_gpio()
105 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_unlock_gpio()
107 val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); in bcm_kona_gpio_unlock_gpio()
108 val &= ~BIT(gpio); in bcm_kona_gpio_unlock_gpio()
109 bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); in bcm_kona_gpio_unlock_gpio()
111 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_unlock_gpio()
114 static int bcm_kona_gpio_get_dir(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_get_dir() argument
117 void __iomem *reg_base = kona_gpio->reg_base; in bcm_kona_gpio_get_dir()
120 val = readl(reg_base + GPIO_CONTROL(gpio)) & GPIO_GPCTR0_IOTR_MASK; in bcm_kona_gpio_get_dir()
124 static void bcm_kona_gpio_set(struct gpio_chip *chip, unsigned gpio, int value) in bcm_kona_gpio_set() argument
128 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_set()
129 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_set()
134 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_set()
135 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_set()
138 if (bcm_kona_gpio_get_dir(chip, gpio) == GPIO_LINE_DIRECTION_IN) in bcm_kona_gpio_set()
148 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_set()
151 static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_get() argument
155 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_get()
156 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_get()
161 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_get()
162 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_get()
164 if (bcm_kona_gpio_get_dir(chip, gpio) == GPIO_LINE_DIRECTION_IN) in bcm_kona_gpio_get()
169 /* read the GPIO bank status */ in bcm_kona_gpio_get()
172 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_get()
178 static int bcm_kona_gpio_request(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_request() argument
182 bcm_kona_gpio_unlock_gpio(kona_gpio, gpio); in bcm_kona_gpio_request()
186 static void bcm_kona_gpio_free(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_free() argument
190 bcm_kona_gpio_lock_gpio(kona_gpio, gpio); in bcm_kona_gpio_free()
193 static int bcm_kona_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_direction_input() argument
201 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_direction_input()
202 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_direction_input()
204 val = readl(reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_direction_input()
207 writel(val, reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_direction_input()
209 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_direction_input()
215 unsigned gpio, int value) in bcm_kona_gpio_direction_output() argument
219 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_direction_output()
220 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_direction_output()
225 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_direction_output()
226 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_direction_output()
228 val = readl(reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_direction_output()
231 writel(val, reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_direction_output()
238 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_direction_output()
243 static int bcm_kona_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) in bcm_kona_gpio_to_irq() argument
248 if (gpio >= kona_gpio->gpio_chip.ngpio) in bcm_kona_gpio_to_irq()
249 return -ENXIO; in bcm_kona_gpio_to_irq()
250 return irq_create_mapping(kona_gpio->irq_domain, gpio); in bcm_kona_gpio_to_irq()
253 static int bcm_kona_gpio_set_debounce(struct gpio_chip *chip, unsigned gpio, in bcm_kona_gpio_set_debounce() argument
262 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_set_debounce()
263 /* debounce must be 1-128ms (or 0) */ in bcm_kona_gpio_set_debounce()
265 dev_err(chip->parent, "Debounce value %u not in range\n", in bcm_kona_gpio_set_debounce()
267 return -EINVAL; in bcm_kona_gpio_set_debounce()
275 res = fls(debounce) - 1; in bcm_kona_gpio_set_debounce()
276 /* Check if MSB-1 is set (round up or down) */ in bcm_kona_gpio_set_debounce()
277 if (res > 0 && (debounce & BIT(res - 1))) in bcm_kona_gpio_set_debounce()
281 /* spin lock for read-modify-write of the GPIO register */ in bcm_kona_gpio_set_debounce()
282 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_set_debounce()
284 val = readl(reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_set_debounce()
295 writel(val, reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_set_debounce()
297 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_set_debounce()
302 static int bcm_kona_gpio_set_config(struct gpio_chip *chip, unsigned gpio, in bcm_kona_gpio_set_config() argument
308 return -ENOTSUPP; in bcm_kona_gpio_set_config()
311 return bcm_kona_gpio_set_debounce(chip, gpio, debounce); in bcm_kona_gpio_set_config()
315 .label = "bcm-kona-gpio",
333 unsigned gpio = d->hwirq; in bcm_kona_gpio_irq_ack() local
334 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_irq_ack()
335 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_irq_ack()
340 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_irq_ack()
341 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_ack()
347 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_ack()
354 unsigned gpio = d->hwirq; in bcm_kona_gpio_irq_mask() local
355 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_irq_mask()
356 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_irq_mask()
361 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_irq_mask()
362 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_mask()
367 gpiochip_disable_irq(&kona_gpio->gpio_chip, gpio); in bcm_kona_gpio_irq_mask()
369 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_mask()
376 unsigned gpio = d->hwirq; in bcm_kona_gpio_irq_unmask() local
377 int bank_id = GPIO_BANK(gpio); in bcm_kona_gpio_irq_unmask()
378 int bit = GPIO_BIT(gpio); in bcm_kona_gpio_irq_unmask()
383 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_irq_unmask()
384 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_unmask()
389 gpiochip_enable_irq(&kona_gpio->gpio_chip, gpio); in bcm_kona_gpio_irq_unmask()
391 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_unmask()
398 unsigned gpio = d->hwirq; in bcm_kona_gpio_irq_set_type() local
404 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_irq_set_type()
420 /* BCM GPIO doesn't support level triggering */ in bcm_kona_gpio_irq_set_type()
422 dev_err(kona_gpio->gpio_chip.parent, in bcm_kona_gpio_irq_set_type()
423 "Invalid BCM GPIO irq type 0x%x\n", type); in bcm_kona_gpio_irq_set_type()
424 return -EINVAL; in bcm_kona_gpio_irq_set_type()
427 raw_spin_lock_irqsave(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_set_type()
429 val = readl(reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_irq_set_type()
432 writel(val, reg_base + GPIO_CONTROL(gpio)); in bcm_kona_gpio_irq_set_type()
434 raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); in bcm_kona_gpio_irq_set_type()
444 struct bcm_kona_gpio_bank *bank = irq_desc_get_handler_data(desc); in bcm_kona_gpio_irq_handler() local
450 * For bank interrupts, we can't use chip_data to store the kona_gpio in bcm_kona_gpio_irq_handler()
452 * our pointer from the bank structure. in bcm_kona_gpio_irq_handler()
454 reg_base = bank->kona_gpio->reg_base; in bcm_kona_gpio_irq_handler()
455 bank_id = bank->id; in bcm_kona_gpio_irq_handler()
468 generic_handle_domain_irq(bank->kona_gpio->irq_domain, in bcm_kona_gpio_irq_handler()
480 return gpiochip_reqres_irq(&kona_gpio->gpio_chip, d->hwirq); in bcm_kona_gpio_irq_reqres()
487 gpiochip_relres_irq(&kona_gpio->gpio_chip, d->hwirq); in bcm_kona_gpio_irq_relres()
491 .name = "bcm-kona-gpio",
501 { .compatible = "brcm,kona-gpio" },
506 * This lock class tells lockdep that GPIO irqs are in a different
517 ret = irq_set_chip_data(irq, d->host_data); in bcm_kona_gpio_irq_map()
544 reg_base = kona_gpio->reg_base; in bcm_kona_gpio_reset()
546 for (i = 0; i < kona_gpio->num_bank; i++) { in bcm_kona_gpio_reset()
547 /* Unlock the entire bank first */ in bcm_kona_gpio_reset()
551 /* Now re-lock the bank */ in bcm_kona_gpio_reset()
558 struct device *dev = &pdev->dev; in bcm_kona_gpio_probe()
560 struct bcm_kona_gpio_bank *bank; in bcm_kona_gpio_probe() local
568 dev_err(dev, "Failed to find gpio controller\n"); in bcm_kona_gpio_probe()
569 return -ENODEV; in bcm_kona_gpio_probe()
574 return -ENOMEM; in bcm_kona_gpio_probe()
576 kona_gpio->gpio_chip = template_chip; in bcm_kona_gpio_probe()
577 chip = &kona_gpio->gpio_chip; in bcm_kona_gpio_probe()
580 dev_err(dev, "Couldn't determine # GPIO banks\n"); in bcm_kona_gpio_probe()
581 return -ENOENT; in bcm_kona_gpio_probe()
583 return dev_err_probe(dev, ret, "Couldn't determine GPIO banks\n"); in bcm_kona_gpio_probe()
585 kona_gpio->num_bank = ret; in bcm_kona_gpio_probe()
587 if (kona_gpio->num_bank > GPIO_MAX_BANK_NUM) { in bcm_kona_gpio_probe()
588 dev_err(dev, "Too many GPIO banks configured (max=%d)\n", in bcm_kona_gpio_probe()
590 return -ENXIO; in bcm_kona_gpio_probe()
592 kona_gpio->banks = devm_kcalloc(dev, in bcm_kona_gpio_probe()
593 kona_gpio->num_bank, in bcm_kona_gpio_probe()
594 sizeof(*kona_gpio->banks), in bcm_kona_gpio_probe()
596 if (!kona_gpio->banks) in bcm_kona_gpio_probe()
597 return -ENOMEM; in bcm_kona_gpio_probe()
599 kona_gpio->pdev = pdev; in bcm_kona_gpio_probe()
601 chip->parent = dev; in bcm_kona_gpio_probe()
602 chip->ngpio = kona_gpio->num_bank * GPIO_PER_BANK; in bcm_kona_gpio_probe()
604 kona_gpio->irq_domain = irq_domain_add_linear(dev->of_node, in bcm_kona_gpio_probe()
605 chip->ngpio, in bcm_kona_gpio_probe()
608 if (!kona_gpio->irq_domain) { in bcm_kona_gpio_probe()
610 return -ENXIO; in bcm_kona_gpio_probe()
613 kona_gpio->reg_base = devm_platform_ioremap_resource(pdev, 0); in bcm_kona_gpio_probe()
614 if (IS_ERR(kona_gpio->reg_base)) { in bcm_kona_gpio_probe()
615 ret = PTR_ERR(kona_gpio->reg_base); in bcm_kona_gpio_probe()
619 for (i = 0; i < kona_gpio->num_bank; i++) { in bcm_kona_gpio_probe()
620 bank = &kona_gpio->banks[i]; in bcm_kona_gpio_probe()
621 bank->id = i; in bcm_kona_gpio_probe()
622 bank->irq = platform_get_irq(pdev, i); in bcm_kona_gpio_probe()
623 bank->kona_gpio = kona_gpio; in bcm_kona_gpio_probe()
624 if (bank->irq < 0) { in bcm_kona_gpio_probe()
625 dev_err(dev, "Couldn't get IRQ for bank %d", i); in bcm_kona_gpio_probe()
626 ret = -ENOENT; in bcm_kona_gpio_probe()
631 dev_info(&pdev->dev, "Setting up Kona GPIO\n"); in bcm_kona_gpio_probe()
637 dev_err(dev, "Couldn't add GPIO chip -- %d\n", ret); in bcm_kona_gpio_probe()
640 for (i = 0; i < kona_gpio->num_bank; i++) { in bcm_kona_gpio_probe()
641 bank = &kona_gpio->banks[i]; in bcm_kona_gpio_probe()
642 irq_set_chained_handler_and_data(bank->irq, in bcm_kona_gpio_probe()
644 bank); in bcm_kona_gpio_probe()
647 raw_spin_lock_init(&kona_gpio->lock); in bcm_kona_gpio_probe()
652 irq_domain_remove(kona_gpio->irq_domain); in bcm_kona_gpio_probe()
659 .name = "bcm-kona-gpio",