Lines Matching +full:offset +full:- +full:x

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.
26 #define GPIO_BANK(x) ((x) >> 5) argument
27 #define GPIO_PORT(x) (((x) >> 3) & 0x3) argument
28 #define GPIO_BIT(x) ((x) & 0x7) argument
30 #define GPIO_REG(tgi, x) (GPIO_BANK(x) * tgi->soc->bank_stride + \ argument
31 GPIO_PORT(x) * 4)
33 #define GPIO_CNF(t, x) (GPIO_REG(t, x) + 0x00) argument
34 #define GPIO_OE(t, x) (GPIO_REG(t, x) + 0x10) argument
35 #define GPIO_OUT(t, x) (GPIO_REG(t, x) + 0X20) argument
36 #define GPIO_IN(t, x) (GPIO_REG(t, x) + 0x30) argument
37 #define GPIO_INT_STA(t, x) (GPIO_REG(t, x) + 0x40) argument
38 #define GPIO_INT_ENB(t, x) (GPIO_REG(t, x) + 0x50) argument
39 #define GPIO_INT_LVL(t, x) (GPIO_REG(t, x) + 0x60) argument
40 #define GPIO_INT_CLR(t, x) (GPIO_REG(t, x) + 0x70) argument
41 #define GPIO_DBC_CNT(t, x) (GPIO_REG(t, x) + 0xF0) argument
44 #define GPIO_MSK_CNF(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x00) argument
45 #define GPIO_MSK_OE(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x10) argument
46 #define GPIO_MSK_OUT(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0X20) argument
47 #define GPIO_MSK_DBC_EN(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x30) argument
48 #define GPIO_MSK_INT_STA(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x40) argument
49 #define GPIO_MSK_INT_ENB(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x50) argument
50 #define GPIO_MSK_INT_LVL(t, x) (GPIO_REG(t, x) + t->soc->upper_offset + 0x60) argument
99 writel_relaxed(val, tgi->regs + reg); in tegra_gpio_writel()
104 return readl_relaxed(tgi->regs + reg); in tegra_gpio_readl()
134 static int tegra_gpio_request(struct gpio_chip *chip, unsigned int offset) in tegra_gpio_request() argument
136 return pinctrl_gpio_request(chip->base + offset); in tegra_gpio_request()
139 static void tegra_gpio_free(struct gpio_chip *chip, unsigned int offset) in tegra_gpio_free() argument
143 pinctrl_gpio_free(chip->base + offset); in tegra_gpio_free()
144 tegra_gpio_disable(tgi, offset); in tegra_gpio_free()
147 static void tegra_gpio_set(struct gpio_chip *chip, unsigned int offset, in tegra_gpio_set() argument
152 tegra_gpio_mask_write(tgi, GPIO_MSK_OUT(tgi, offset), offset, value); in tegra_gpio_set()
155 static int tegra_gpio_get(struct gpio_chip *chip, unsigned int offset) in tegra_gpio_get() argument
158 unsigned int bval = BIT(GPIO_BIT(offset)); in tegra_gpio_get()
161 if (tegra_gpio_readl(tgi, GPIO_OE(tgi, offset)) & bval) in tegra_gpio_get()
162 return !!(tegra_gpio_readl(tgi, GPIO_OUT(tgi, offset)) & bval); in tegra_gpio_get()
164 return !!(tegra_gpio_readl(tgi, GPIO_IN(tgi, offset)) & bval); in tegra_gpio_get()
168 unsigned int offset) in tegra_gpio_direction_input() argument
173 tegra_gpio_mask_write(tgi, GPIO_MSK_OE(tgi, offset), offset, 0); in tegra_gpio_direction_input()
174 tegra_gpio_enable(tgi, offset); in tegra_gpio_direction_input()
176 ret = pinctrl_gpio_direction_input(chip->base + offset); in tegra_gpio_direction_input()
178 dev_err(tgi->dev, in tegra_gpio_direction_input()
180 chip->base + offset, ret); in tegra_gpio_direction_input()
186 unsigned int offset, in tegra_gpio_direction_output() argument
192 tegra_gpio_set(chip, offset, value); in tegra_gpio_direction_output()
193 tegra_gpio_mask_write(tgi, GPIO_MSK_OE(tgi, offset), offset, 1); in tegra_gpio_direction_output()
194 tegra_gpio_enable(tgi, offset); in tegra_gpio_direction_output()
196 ret = pinctrl_gpio_direction_output(chip->base + offset); in tegra_gpio_direction_output()
198 dev_err(tgi->dev, in tegra_gpio_direction_output()
200 chip->base + offset, ret); in tegra_gpio_direction_output()
206 unsigned int offset) in tegra_gpio_get_direction() argument
209 u32 pin_mask = BIT(GPIO_BIT(offset)); in tegra_gpio_get_direction()
212 cnf = tegra_gpio_readl(tgi, GPIO_CNF(tgi, offset)); in tegra_gpio_get_direction()
214 return -EINVAL; in tegra_gpio_get_direction()
216 oe = tegra_gpio_readl(tgi, GPIO_OE(tgi, offset)); in tegra_gpio_get_direction()
224 static int tegra_gpio_set_debounce(struct gpio_chip *chip, unsigned int offset, in tegra_gpio_set_debounce() argument
228 struct tegra_gpio_bank *bank = &tgi->bank_info[GPIO_BANK(offset)]; in tegra_gpio_set_debounce()
234 tegra_gpio_mask_write(tgi, GPIO_MSK_DBC_EN(tgi, offset), in tegra_gpio_set_debounce()
235 offset, 0); in tegra_gpio_set_debounce()
240 port = GPIO_PORT(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()
247 tegra_gpio_writel(tgi, debounce_ms, GPIO_DBC_CNT(tgi, offset)); 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()
252 tegra_gpio_mask_write(tgi, GPIO_MSK_DBC_EN(tgi, offset), offset, 1); in tegra_gpio_set_debounce()
257 static int tegra_gpio_set_config(struct gpio_chip *chip, unsigned int offset, in tegra_gpio_set_config() argument
263 return -ENOTSUPP; in tegra_gpio_set_config()
266 return tegra_gpio_set_debounce(chip, offset, debounce); in tegra_gpio_set_config()
269 static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) in tegra_gpio_to_irq() argument
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()
288 struct tegra_gpio_info *tgi = bank->tgi; in tegra_gpio_irq_mask()
289 unsigned int gpio = d->hwirq; 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()
305 unsigned int gpio = d->hwirq, port = GPIO_PORT(gpio), lvl_type; in tegra_gpio_irq_set_type()
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()
344 spin_unlock_irqrestore(&bank->lvl_lock[port], flags); 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()
368 struct tegra_gpio_info *tgi = bank->tgi; in tegra_gpio_irq_shutdown()
369 unsigned int gpio = d->hwirq; in tegra_gpio_irq_shutdown()
372 gpiochip_unlock_as_irq(&tgi->gc, gpio); in tegra_gpio_irq_shutdown()
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()
406 generic_handle_irq(irq_find_mapping(tgi->irq_domain, 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()
428 tegra_gpio_writel(tgi, bank->cnf[p], 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()
434 tegra_gpio_writel(tgi, bank->dbc_enb[p], in tegra_gpio_resume()
438 tegra_gpio_writel(tgi, bank->out[p], in tegra_gpio_resume()
440 tegra_gpio_writel(tgi, bank->oe[p], in tegra_gpio_resume()
442 tegra_gpio_writel(tgi, bank->int_lvl[p], in tegra_gpio_resume()
444 tegra_gpio_writel(tgi, bank->int_enb[p], 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()
463 bank->cnf[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
465 bank->out[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
467 bank->oe[p] = tegra_gpio_readl(tgi, 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()
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()
478 bank->int_lvl[p] = tegra_gpio_readl(tgi, in tegra_gpio_suspend()
482 tegra_gpio_writel(tgi, bank->wake_enb[p], in tegra_gpio_suspend()
493 unsigned int gpio = d->hwirq; in tegra_gpio_irq_set_wake()
497 err = irq_set_irq_wake(bank->irq, enable); 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()
529 "%u:%u %02x %02x %02x %02x %02x %02x %06x\n", in tegra_dbg_gpio_show()
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()
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",