• Home
  • Raw
  • Download

Lines Matching +full:gpio +full:- +full:lvl

1 // SPDX-License-Identifier: GPL-2.0-only
3 * arch/arm/mach-tegra/gpio.c
6 * Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved.
17 #include <linux/gpio/driver.h>
30 #define GPIO_REG(tgi, x) (GPIO_BANK(x) * tgi->soc->bank_stride + \
44 #define GPIO_MSK_CNF(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x00)
45 #define GPIO_MSK_OE(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x10)
46 #define GPIO_MSK_OUT(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0X20)
47 #define GPIO_MSK_DBC_EN(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x30)
48 #define GPIO_MSK_INT_STA(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x40)
49 #define GPIO_MSK_INT_ENB(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x50)
50 #define GPIO_MSK_INT_LVL(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x60)
99 writel_relaxed(val, tgi->regs + reg); in tegra_gpio_writel()
104 return readl_relaxed(tgi->regs + reg); in tegra_gpio_readl()
114 unsigned int gpio, u32 value) in tegra_gpio_mask_write() argument
118 val = 0x100 << GPIO_BIT(gpio); in tegra_gpio_mask_write()
120 val |= 1 << GPIO_BIT(gpio); in tegra_gpio_mask_write()
124 static void tegra_gpio_enable(struct tegra_gpio_info *tgi, unsigned int gpio) in tegra_gpio_enable() argument
126 tegra_gpio_mask_write(tgi, GPIO_MSK_CNF(tgi, gpio), gpio, 1); in tegra_gpio_enable()
129 static void tegra_gpio_disable(struct tegra_gpio_info *tgi, unsigned int gpio) in tegra_gpio_disable() argument
131 tegra_gpio_mask_write(tgi, GPIO_MSK_CNF(tgi, gpio), gpio, 0); in tegra_gpio_disable()
136 return pinctrl_gpio_request(chip->base + offset); in tegra_gpio_request()
143 pinctrl_gpio_free(chip->base + offset); in tegra_gpio_free()
160 /* If gpio is in output mode then read from the out value */ in tegra_gpio_get()
176 ret = pinctrl_gpio_direction_input(chip->base + offset); in tegra_gpio_direction_input()
178 dev_err(tgi->dev, in tegra_gpio_direction_input()
179 "Failed to set pinctrl input direction of GPIO %d: %d", in tegra_gpio_direction_input()
180 chip->base + offset, ret); in tegra_gpio_direction_input()
196 ret = pinctrl_gpio_direction_output(chip->base + offset); in tegra_gpio_direction_output()
198 dev_err(tgi->dev, in tegra_gpio_direction_output()
199 "Failed to set pinctrl output direction of GPIO %d: %d", in tegra_gpio_direction_output()
200 chip->base + offset, ret); in tegra_gpio_direction_output()
214 return -EINVAL; in tegra_gpio_get_direction()
228 struct tegra_gpio_bank *bank = &tgi->bank_info[GPIO_BANK(offset)]; in tegra_gpio_set_debounce()
245 spin_lock_irqsave(&bank->dbc_lock[port], flags); in tegra_gpio_set_debounce()
246 if (bank->dbc_cnt[port] < debounce_ms) { in tegra_gpio_set_debounce()
248 bank->dbc_cnt[port] = debounce_ms; in tegra_gpio_set_debounce()
250 spin_unlock_irqrestore(&bank->dbc_lock[port], flags); in tegra_gpio_set_debounce()
263 return -ENOTSUPP; in tegra_gpio_set_config()
273 return irq_find_mapping(tgi->irq_domain, offset); in tegra_gpio_to_irq()
279 struct tegra_gpio_info *tgi = bank->tgi; in tegra_gpio_irq_ack()
280 unsigned int gpio = d->hwirq; in tegra_gpio_irq_ack() local
282 tegra_gpio_writel(tgi, 1 << GPIO_BIT(gpio), GPIO_INT_CLR(tgi, gpio)); in tegra_gpio_irq_ack()
288 struct tegra_gpio_info *tgi = bank->tgi; in tegra_gpio_irq_mask()
289 unsigned int gpio = d->hwirq; in tegra_gpio_irq_mask() local
291 tegra_gpio_mask_write(tgi, GPIO_MSK_INT_ENB(tgi, gpio), gpio, 0); in tegra_gpio_irq_mask()
297 struct tegra_gpio_info *tgi = bank->tgi; in tegra_gpio_irq_unmask()
298 unsigned int gpio = d->hwirq; in tegra_gpio_irq_unmask() local
300 tegra_gpio_mask_write(tgi, GPIO_MSK_INT_ENB(tgi, gpio), gpio, 1); in tegra_gpio_irq_unmask()
305 unsigned int gpio = d->hwirq, port = GPIO_PORT(gpio), lvl_type; in tegra_gpio_irq_set_type() local
307 struct tegra_gpio_info *tgi = bank->tgi; in tegra_gpio_irq_set_type()
334 return -EINVAL; in tegra_gpio_irq_set_type()
337 spin_lock_irqsave(&bank->lvl_lock[port], flags); in tegra_gpio_irq_set_type()
339 val = tegra_gpio_readl(tgi, GPIO_INT_LVL(tgi, gpio)); in tegra_gpio_irq_set_type()
340 val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio)); in tegra_gpio_irq_set_type()
341 val |= lvl_type << GPIO_BIT(gpio); in tegra_gpio_irq_set_type()
342 tegra_gpio_writel(tgi, val, GPIO_INT_LVL(tgi, gpio)); in tegra_gpio_irq_set_type()
344 spin_unlock_irqrestore(&bank->lvl_lock[port], flags); in tegra_gpio_irq_set_type()
346 tegra_gpio_mask_write(tgi, GPIO_MSK_OE(tgi, gpio), gpio, 0); in tegra_gpio_irq_set_type()
347 tegra_gpio_enable(tgi, gpio); in tegra_gpio_irq_set_type()
349 ret = gpiochip_lock_as_irq(&tgi->gc, gpio); in tegra_gpio_irq_set_type()
351 dev_err(tgi->dev, in tegra_gpio_irq_set_type()
352 "unable to lock Tegra GPIO %u as IRQ\n", gpio); in tegra_gpio_irq_set_type()
353 tegra_gpio_disable(tgi, gpio); in tegra_gpio_irq_set_type()
368 struct tegra_gpio_info *tgi = bank->tgi; in tegra_gpio_irq_shutdown()
369 unsigned int gpio = d->hwirq; in tegra_gpio_irq_shutdown() local
372 gpiochip_unlock_as_irq(&tgi->gc, gpio); in tegra_gpio_irq_shutdown()
377 unsigned int port, pin, gpio; in tegra_gpio_irq_handler() local
379 u32 lvl; in tegra_gpio_irq_handler() local
383 struct tegra_gpio_info *tgi = bank->tgi; in tegra_gpio_irq_handler()
388 gpio = tegra_gpio_compose(bank->bank, port, 0); in tegra_gpio_irq_handler()
389 sta = tegra_gpio_readl(tgi, GPIO_INT_STA(tgi, gpio)) & in tegra_gpio_irq_handler()
390 tegra_gpio_readl(tgi, GPIO_INT_ENB(tgi, gpio)); in tegra_gpio_irq_handler()
391 lvl = tegra_gpio_readl(tgi, GPIO_INT_LVL(tgi, gpio)); in tegra_gpio_irq_handler()
395 GPIO_INT_CLR(tgi, gpio)); in tegra_gpio_irq_handler()
397 /* if gpio is edge triggered, clear condition in tegra_gpio_irq_handler()
401 if (!unmasked && lvl & (0x100 << pin)) { in tegra_gpio_irq_handler()
406 generic_handle_irq(irq_find_mapping(tgi->irq_domain, in tegra_gpio_irq_handler()
407 gpio + pin)); in tegra_gpio_irq_handler()
422 for (b = 0; b < tgi->bank_count; b++) { in tegra_gpio_resume()
423 struct tegra_gpio_bank *bank = &tgi->bank_info[b]; in tegra_gpio_resume()
425 for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { in tegra_gpio_resume()
426 unsigned int gpio = (b << 5) | (p << 3); in tegra_gpio_resume() local
428 tegra_gpio_writel(tgi, bank->cnf[p], in tegra_gpio_resume()
429 GPIO_CNF(tgi, gpio)); in tegra_gpio_resume()
431 if (tgi->soc->debounce_supported) { in tegra_gpio_resume()
432 tegra_gpio_writel(tgi, bank->dbc_cnt[p], in tegra_gpio_resume()
433 GPIO_DBC_CNT(tgi, gpio)); in tegra_gpio_resume()
434 tegra_gpio_writel(tgi, bank->dbc_enb[p], in tegra_gpio_resume()
435 GPIO_MSK_DBC_EN(tgi, gpio)); in tegra_gpio_resume()
438 tegra_gpio_writel(tgi, bank->out[p], in tegra_gpio_resume()
439 GPIO_OUT(tgi, gpio)); in tegra_gpio_resume()
440 tegra_gpio_writel(tgi, bank->oe[p], in tegra_gpio_resume()
441 GPIO_OE(tgi, gpio)); in tegra_gpio_resume()
442 tegra_gpio_writel(tgi, bank->int_lvl[p], in tegra_gpio_resume()
443 GPIO_INT_LVL(tgi, gpio)); in tegra_gpio_resume()
444 tegra_gpio_writel(tgi, bank->int_enb[p], in tegra_gpio_resume()
445 GPIO_INT_ENB(tgi, gpio)); in tegra_gpio_resume()
457 for (b = 0; b < tgi->bank_count; b++) { in tegra_gpio_suspend()
458 struct tegra_gpio_bank *bank = &tgi->bank_info[b]; in tegra_gpio_suspend()
460 for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { in tegra_gpio_suspend()
461 unsigned int gpio = (b << 5) | (p << 3); in tegra_gpio_suspend() local
463 bank->cnf[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
464 GPIO_CNF(tgi, gpio)); in tegra_gpio_suspend()
465 bank->out[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
466 GPIO_OUT(tgi, gpio)); in tegra_gpio_suspend()
467 bank->oe[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
468 GPIO_OE(tgi, gpio)); in tegra_gpio_suspend()
469 if (tgi->soc->debounce_supported) { in tegra_gpio_suspend()
470 bank->dbc_enb[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
471 GPIO_MSK_DBC_EN(tgi, gpio)); in tegra_gpio_suspend()
472 bank->dbc_enb[p] = (bank->dbc_enb[p] << 8) | in tegra_gpio_suspend()
473 bank->dbc_enb[p]; in tegra_gpio_suspend()
476 bank->int_enb[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
477 GPIO_INT_ENB(tgi, gpio)); in tegra_gpio_suspend()
478 bank->int_lvl[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
479 GPIO_INT_LVL(tgi, gpio)); in tegra_gpio_suspend()
481 /* Enable gpio irq for wake up source */ in tegra_gpio_suspend()
482 tegra_gpio_writel(tgi, bank->wake_enb[p], in tegra_gpio_suspend()
483 GPIO_INT_ENB(tgi, gpio)); in tegra_gpio_suspend()
493 unsigned int gpio = d->hwirq; in tegra_gpio_irq_set_wake() local
497 err = irq_set_irq_wake(bank->irq, enable); in tegra_gpio_irq_set_wake()
501 port = GPIO_PORT(gpio); in tegra_gpio_irq_set_wake()
502 bit = GPIO_BIT(gpio); in tegra_gpio_irq_set_wake()
506 bank->wake_enb[port] |= mask; in tegra_gpio_irq_set_wake()
508 bank->wake_enb[port] &= ~mask; in tegra_gpio_irq_set_wake()
521 struct tegra_gpio_info *tgi = s->private; in tegra_dbg_gpio_show()
524 for (i = 0; i < tgi->bank_count; i++) { in tegra_dbg_gpio_show()
526 unsigned int gpio = tegra_gpio_compose(i, j, 0); in tegra_dbg_gpio_show() local
531 tegra_gpio_readl(tgi, GPIO_CNF(tgi, gpio)), in tegra_dbg_gpio_show()
532 tegra_gpio_readl(tgi, GPIO_OE(tgi, gpio)), in tegra_dbg_gpio_show()
533 tegra_gpio_readl(tgi, GPIO_OUT(tgi, gpio)), in tegra_dbg_gpio_show()
534 tegra_gpio_readl(tgi, GPIO_IN(tgi, gpio)), in tegra_dbg_gpio_show()
535 tegra_gpio_readl(tgi, GPIO_INT_STA(tgi, gpio)), in tegra_dbg_gpio_show()
536 tegra_gpio_readl(tgi, GPIO_INT_ENB(tgi, gpio)), in tegra_dbg_gpio_show()
537 tegra_gpio_readl(tgi, GPIO_INT_LVL(tgi, gpio))); in tegra_dbg_gpio_show()
567 unsigned int gpio, i, j; in tegra_gpio_probe() local
570 tgi = devm_kzalloc(&pdev->dev, sizeof(*tgi), GFP_KERNEL); in tegra_gpio_probe()
572 return -ENODEV; in tegra_gpio_probe()
574 tgi->soc = of_device_get_match_data(&pdev->dev); in tegra_gpio_probe()
575 tgi->dev = &pdev->dev; in tegra_gpio_probe()
581 tgi->bank_count = ret; in tegra_gpio_probe()
583 if (!tgi->bank_count) { in tegra_gpio_probe()
584 dev_err(&pdev->dev, "Missing IRQ resource\n"); in tegra_gpio_probe()
585 return -ENODEV; in tegra_gpio_probe()
588 tgi->gc.label = "tegra-gpio"; in tegra_gpio_probe()
589 tgi->gc.request = tegra_gpio_request; in tegra_gpio_probe()
590 tgi->gc.free = tegra_gpio_free; in tegra_gpio_probe()
591 tgi->gc.direction_input = tegra_gpio_direction_input; in tegra_gpio_probe()
592 tgi->gc.get = tegra_gpio_get; in tegra_gpio_probe()
593 tgi->gc.direction_output = tegra_gpio_direction_output; in tegra_gpio_probe()
594 tgi->gc.set = tegra_gpio_set; in tegra_gpio_probe()
595 tgi->gc.get_direction = tegra_gpio_get_direction; in tegra_gpio_probe()
596 tgi->gc.to_irq = tegra_gpio_to_irq; in tegra_gpio_probe()
597 tgi->gc.base = 0; in tegra_gpio_probe()
598 tgi->gc.ngpio = tgi->bank_count * 32; in tegra_gpio_probe()
599 tgi->gc.parent = &pdev->dev; in tegra_gpio_probe()
600 tgi->gc.of_node = pdev->dev.of_node; in tegra_gpio_probe()
602 tgi->ic.name = "GPIO"; in tegra_gpio_probe()
603 tgi->ic.irq_ack = tegra_gpio_irq_ack; in tegra_gpio_probe()
604 tgi->ic.irq_mask = tegra_gpio_irq_mask; in tegra_gpio_probe()
605 tgi->ic.irq_unmask = tegra_gpio_irq_unmask; in tegra_gpio_probe()
606 tgi->ic.irq_set_type = tegra_gpio_irq_set_type; in tegra_gpio_probe()
607 tgi->ic.irq_shutdown = tegra_gpio_irq_shutdown; in tegra_gpio_probe()
609 tgi->ic.irq_set_wake = tegra_gpio_irq_set_wake; in tegra_gpio_probe()
614 if (tgi->soc->debounce_supported) in tegra_gpio_probe()
615 tgi->gc.set_config = tegra_gpio_set_config; in tegra_gpio_probe()
617 tgi->bank_info = devm_kcalloc(&pdev->dev, tgi->bank_count, in tegra_gpio_probe()
618 sizeof(*tgi->bank_info), GFP_KERNEL); in tegra_gpio_probe()
619 if (!tgi->bank_info) in tegra_gpio_probe()
620 return -ENOMEM; in tegra_gpio_probe()
622 tgi->irq_domain = irq_domain_add_linear(pdev->dev.of_node, in tegra_gpio_probe()
623 tgi->gc.ngpio, in tegra_gpio_probe()
625 if (!tgi->irq_domain) in tegra_gpio_probe()
626 return -ENODEV; in tegra_gpio_probe()
628 for (i = 0; i < tgi->bank_count; i++) { in tegra_gpio_probe()
633 bank = &tgi->bank_info[i]; in tegra_gpio_probe()
634 bank->bank = i; in tegra_gpio_probe()
635 bank->irq = ret; in tegra_gpio_probe()
636 bank->tgi = tgi; in tegra_gpio_probe()
639 tgi->regs = devm_platform_ioremap_resource(pdev, 0); in tegra_gpio_probe()
640 if (IS_ERR(tgi->regs)) in tegra_gpio_probe()
641 return PTR_ERR(tgi->regs); in tegra_gpio_probe()
643 for (i = 0; i < tgi->bank_count; i++) { in tegra_gpio_probe()
645 int gpio = tegra_gpio_compose(i, j, 0); in tegra_gpio_probe() local
647 tegra_gpio_writel(tgi, 0x00, GPIO_INT_ENB(tgi, gpio)); in tegra_gpio_probe()
651 ret = devm_gpiochip_add_data(&pdev->dev, &tgi->gc, tgi); in tegra_gpio_probe()
653 irq_domain_remove(tgi->irq_domain); in tegra_gpio_probe()
657 for (gpio = 0; gpio < tgi->gc.ngpio; gpio++) { in tegra_gpio_probe()
658 int irq = irq_create_mapping(tgi->irq_domain, gpio); in tegra_gpio_probe()
661 bank = &tgi->bank_info[GPIO_BANK(gpio)]; in tegra_gpio_probe()
664 irq_set_chip_and_handler(irq, &tgi->ic, handle_simple_irq); in tegra_gpio_probe()
667 for (i = 0; i < tgi->bank_count; i++) { in tegra_gpio_probe()
668 bank = &tgi->bank_info[i]; in tegra_gpio_probe()
670 irq_set_chained_handler_and_data(bank->irq, in tegra_gpio_probe()
674 spin_lock_init(&bank->lvl_lock[j]); in tegra_gpio_probe()
675 spin_lock_init(&bank->dbc_lock[j]); in tegra_gpio_probe()
701 { .compatible = "nvidia,tegra210-gpio", .data = &tegra210_gpio_config },
702 { .compatible = "nvidia,tegra30-gpio", .data = &tegra30_gpio_config },
703 { .compatible = "nvidia,tegra20-gpio", .data = &tegra20_gpio_config },
709 .name = "tegra-gpio",