Lines Matching +full:gpio +full:- +full:bank

1 // SPDX-License-Identifier: GPL-2.0-only
13 #include <linux/gpio/driver.h>
22 #include <linux/pinctrl/pinconf-generic.h>
27 #include "../pinctrl/pinctrl-rockchip.h"
31 * Bits [31:24] - Major Version
32 * Bits [23:16] - Minor Version
33 * Bits [15:0] - Revision Number
35 #define GPIO_TYPE_V1 (0) /* GPIO Version ID reserved */
83 static inline void rockchip_gpio_writel(struct rockchip_pin_bank *bank, in rockchip_gpio_writel() argument
86 void __iomem *reg = bank->reg_base + offset; in rockchip_gpio_writel()
88 if (bank->gpio_type == GPIO_TYPE_V2) in rockchip_gpio_writel()
94 static inline u32 rockchip_gpio_readl(struct rockchip_pin_bank *bank, in rockchip_gpio_readl() argument
97 void __iomem *reg = bank->reg_base + offset; in rockchip_gpio_readl()
100 if (bank->gpio_type == GPIO_TYPE_V2) in rockchip_gpio_readl()
108 static inline void rockchip_gpio_writel_bit(struct rockchip_pin_bank *bank, in rockchip_gpio_writel_bit() argument
112 void __iomem *reg = bank->reg_base + offset; in rockchip_gpio_writel_bit()
115 if (bank->gpio_type == GPIO_TYPE_V2) { in rockchip_gpio_writel_bit()
130 static inline u32 rockchip_gpio_readl_bit(struct rockchip_pin_bank *bank, in rockchip_gpio_readl_bit() argument
133 void __iomem *reg = bank->reg_base + offset; in rockchip_gpio_readl_bit()
136 if (bank->gpio_type == GPIO_TYPE_V2) { in rockchip_gpio_readl_bit()
150 struct rockchip_pin_bank *bank = gpiochip_get_data(chip); in rockchip_gpio_get_direction() local
153 data = rockchip_gpio_readl_bit(bank, offset, bank->gpio_regs->port_ddr); in rockchip_gpio_get_direction()
163 struct rockchip_pin_bank *bank = gpiochip_get_data(chip); in rockchip_gpio_set_direction() local
173 raw_spin_lock_irqsave(&bank->slock, flags); in rockchip_gpio_set_direction()
174 rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr); in rockchip_gpio_set_direction()
175 raw_spin_unlock_irqrestore(&bank->slock, flags); in rockchip_gpio_set_direction()
183 struct rockchip_pin_bank *bank = gpiochip_get_data(gc); in rockchip_gpio_set() local
186 raw_spin_lock_irqsave(&bank->slock, flags); in rockchip_gpio_set()
187 rockchip_gpio_writel_bit(bank, offset, value, bank->gpio_regs->port_dr); in rockchip_gpio_set()
188 raw_spin_unlock_irqrestore(&bank->slock, flags); in rockchip_gpio_set()
193 struct rockchip_pin_bank *bank = gpiochip_get_data(gc); in rockchip_gpio_get() local
196 data = readl(bank->reg_base + bank->gpio_regs->ext_port); in rockchip_gpio_get()
207 struct rockchip_pin_bank *bank = gpiochip_get_data(gc); in rockchip_gpio_set_debounce() local
208 const struct rockchip_gpio_regs *reg = bank->gpio_regs; in rockchip_gpio_set_debounce()
214 if (bank->gpio_type == GPIO_TYPE_V2 && !IS_ERR(bank->db_clk)) { in rockchip_gpio_set_debounce()
216 freq = clk_get_rate(bank->db_clk); in rockchip_gpio_set_debounce()
219 return -EINVAL; in rockchip_gpio_set_debounce()
222 div_reg = DIV_ROUND_CLOSEST_ULL(div, 2 * USEC_PER_SEC) - 1; in rockchip_gpio_set_debounce()
227 raw_spin_lock_irqsave(&bank->slock, flags); in rockchip_gpio_set_debounce()
233 cur_div_reg = readl(bank->reg_base + in rockchip_gpio_set_debounce()
234 reg->dbclk_div_con); in rockchip_gpio_set_debounce()
236 writel(div_reg, bank->reg_base + in rockchip_gpio_set_debounce()
237 reg->dbclk_div_con); in rockchip_gpio_set_debounce()
238 rockchip_gpio_writel_bit(bank, offset, 1, in rockchip_gpio_set_debounce()
239 reg->dbclk_div_en); in rockchip_gpio_set_debounce()
242 rockchip_gpio_writel_bit(bank, offset, 1, reg->debounce); in rockchip_gpio_set_debounce()
245 rockchip_gpio_writel_bit(bank, offset, 0, in rockchip_gpio_set_debounce()
246 reg->dbclk_div_en); in rockchip_gpio_set_debounce()
248 rockchip_gpio_writel_bit(bank, offset, 0, reg->debounce); in rockchip_gpio_set_debounce()
251 raw_spin_unlock_irqrestore(&bank->slock, flags); in rockchip_gpio_set_debounce()
256 clk_prepare_enable(bank->db_clk); in rockchip_gpio_set_debounce()
258 clk_disable_unprepare(bank->db_clk); in rockchip_gpio_set_debounce()
280 * mux function as 'gpio output' will be handled by the pinctrl subsystem
292 * Rockchip's gpio could only support up to one period in rockchip_gpio_set_config()
298 * if the gpio is conguired as wakeup interrupt source. Let's in rockchip_gpio_set_config()
299 * still return -ENOTSUPP as before, to make sure the caller in rockchip_gpio_set_config()
302 return -ENOTSUPP; in rockchip_gpio_set_config()
304 return -ENOTSUPP; in rockchip_gpio_set_config()
309 * gpiod_to_irq() callback function. Creates a mapping between a GPIO pin
314 struct rockchip_pin_bank *bank = gpiochip_get_data(gc); in rockchip_gpio_to_irq() local
317 if (!bank->domain) in rockchip_gpio_to_irq()
318 return -ENXIO; in rockchip_gpio_to_irq()
320 virq = irq_create_mapping(bank->domain, offset); in rockchip_gpio_to_irq()
322 return (virq) ? : -ENXIO; in rockchip_gpio_to_irq()
341 struct rockchip_pin_bank *bank = irq_desc_get_handler_data(desc); in rockchip_irq_demux() local
345 dev_dbg(bank->dev, "got irq for bank %s\n", bank->name); in rockchip_irq_demux()
349 pending = readl_relaxed(bank->reg_base + bank->gpio_regs->int_status); in rockchip_irq_demux()
351 dev_dbg(bank->dev, "handling irq %d\n", irq); in rockchip_irq_demux()
357 if (bank->toggle_edge_mode & BIT(irq)) { in rockchip_irq_demux()
361 data = readl_relaxed(bank->reg_base + in rockchip_irq_demux()
362 bank->gpio_regs->ext_port); in rockchip_irq_demux()
364 raw_spin_lock_irqsave(&bank->slock, flags); in rockchip_irq_demux()
366 polarity = readl_relaxed(bank->reg_base + in rockchip_irq_demux()
367 bank->gpio_regs->int_polarity); in rockchip_irq_demux()
373 bank->reg_base + in rockchip_irq_demux()
374 bank->gpio_regs->int_polarity); in rockchip_irq_demux()
376 raw_spin_unlock_irqrestore(&bank->slock, flags); in rockchip_irq_demux()
379 data = readl_relaxed(bank->reg_base + in rockchip_irq_demux()
380 bank->gpio_regs->ext_port); in rockchip_irq_demux()
384 generic_handle_domain_irq(bank->domain, irq); in rockchip_irq_demux()
393 struct rockchip_pin_bank *bank = gc->private; in rockchip_irq_set_type() local
394 u32 mask = BIT(d->hwirq); in rockchip_irq_set_type()
401 raw_spin_lock_irqsave(&bank->slock, flags); in rockchip_irq_set_type()
403 rockchip_gpio_writel_bit(bank, d->hwirq, 0, in rockchip_irq_set_type()
404 bank->gpio_regs->port_ddr); in rockchip_irq_set_type()
406 raw_spin_unlock_irqrestore(&bank->slock, flags); in rockchip_irq_set_type()
413 raw_spin_lock_irqsave(&bank->slock, flags); in rockchip_irq_set_type()
415 level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type); in rockchip_irq_set_type()
416 polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity); in rockchip_irq_set_type()
419 if (bank->gpio_type == GPIO_TYPE_V2) { in rockchip_irq_set_type()
420 rockchip_gpio_writel_bit(bank, d->hwirq, 1, in rockchip_irq_set_type()
421 bank->gpio_regs->int_bothedge); in rockchip_irq_set_type()
424 bank->toggle_edge_mode |= mask; in rockchip_irq_set_type()
428 * Determine gpio state. If 1 next interrupt should be in rockchip_irq_set_type()
431 data = readl(bank->reg_base + bank->gpio_regs->ext_port); in rockchip_irq_set_type()
438 if (bank->gpio_type == GPIO_TYPE_V2) { in rockchip_irq_set_type()
439 rockchip_gpio_writel_bit(bank, d->hwirq, 0, in rockchip_irq_set_type()
440 bank->gpio_regs->int_bothedge); in rockchip_irq_set_type()
442 bank->toggle_edge_mode &= ~mask; in rockchip_irq_set_type()
462 ret = -EINVAL; in rockchip_irq_set_type()
467 rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type); in rockchip_irq_set_type()
468 rockchip_gpio_writel(bank, polarity, bank->gpio_regs->int_polarity); in rockchip_irq_set_type()
470 raw_spin_unlock_irqrestore(&bank->slock, flags); in rockchip_irq_set_type()
478 struct rockchip_pin_bank *bank = gc->private; in rockchip_irq_reqres() local
480 return gpiochip_reqres_irq(&bank->gpio_chip, d->hwirq); in rockchip_irq_reqres()
486 struct rockchip_pin_bank *bank = gc->private; in rockchip_irq_relres() local
488 gpiochip_relres_irq(&bank->gpio_chip, d->hwirq); in rockchip_irq_relres()
494 struct rockchip_pin_bank *bank = gc->private; in rockchip_irq_suspend() local
496 bank->saved_masks = irq_reg_readl(gc, bank->gpio_regs->int_mask); in rockchip_irq_suspend()
497 irq_reg_writel(gc, ~gc->wake_active, bank->gpio_regs->int_mask); in rockchip_irq_suspend()
503 struct rockchip_pin_bank *bank = gc->private; in rockchip_irq_resume() local
505 irq_reg_writel(gc, bank->saved_masks, bank->gpio_regs->int_mask); in rockchip_irq_resume()
518 static int rockchip_interrupts_register(struct rockchip_pin_bank *bank) in rockchip_interrupts_register() argument
524 bank->domain = irq_domain_add_linear(bank->of_node, 32, in rockchip_interrupts_register()
526 if (!bank->domain) { in rockchip_interrupts_register()
527 dev_warn(bank->dev, "could not init irq domain for bank %s\n", in rockchip_interrupts_register()
528 bank->name); in rockchip_interrupts_register()
529 return -EINVAL; in rockchip_interrupts_register()
532 ret = irq_alloc_domain_generic_chips(bank->domain, 32, 1, in rockchip_interrupts_register()
537 dev_err(bank->dev, "could not alloc generic chips for bank %s\n", in rockchip_interrupts_register()
538 bank->name); in rockchip_interrupts_register()
539 irq_domain_remove(bank->domain); in rockchip_interrupts_register()
540 return -EINVAL; in rockchip_interrupts_register()
543 gc = irq_get_domain_generic_chip(bank->domain, 0); in rockchip_interrupts_register()
544 if (bank->gpio_type == GPIO_TYPE_V2) { in rockchip_interrupts_register()
545 gc->reg_writel = gpio_writel_v2; in rockchip_interrupts_register()
546 gc->reg_readl = gpio_readl_v2; in rockchip_interrupts_register()
549 gc->reg_base = bank->reg_base; in rockchip_interrupts_register()
550 gc->private = bank; in rockchip_interrupts_register()
551 gc->chip_types[0].regs.mask = bank->gpio_regs->int_mask; in rockchip_interrupts_register()
552 gc->chip_types[0].regs.ack = bank->gpio_regs->port_eoi; in rockchip_interrupts_register()
553 gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; in rockchip_interrupts_register()
554 gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; in rockchip_interrupts_register()
555 gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; in rockchip_interrupts_register()
556 gc->chip_types[0].chip.irq_enable = rockchip_irq_enable; in rockchip_interrupts_register()
557 gc->chip_types[0].chip.irq_disable = rockchip_irq_disable; in rockchip_interrupts_register()
558 gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; in rockchip_interrupts_register()
559 gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend; in rockchip_interrupts_register()
560 gc->chip_types[0].chip.irq_resume = rockchip_irq_resume; in rockchip_interrupts_register()
561 gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; in rockchip_interrupts_register()
562 gc->chip_types[0].chip.irq_request_resources = rockchip_irq_reqres; in rockchip_interrupts_register()
563 gc->chip_types[0].chip.irq_release_resources = rockchip_irq_relres; in rockchip_interrupts_register()
564 gc->wake_enabled = IRQ_MSK(bank->nr_pins); in rockchip_interrupts_register()
571 rockchip_gpio_writel(bank, 0xffffffff, bank->gpio_regs->int_mask); in rockchip_interrupts_register()
572 rockchip_gpio_writel(bank, 0xffffffff, bank->gpio_regs->port_eoi); in rockchip_interrupts_register()
573 rockchip_gpio_writel(bank, 0xffffffff, bank->gpio_regs->int_en); in rockchip_interrupts_register()
574 gc->mask_cache = 0xffffffff; in rockchip_interrupts_register()
576 irq_set_chained_handler_and_data(bank->irq, in rockchip_interrupts_register()
577 rockchip_irq_demux, bank); in rockchip_interrupts_register()
582 static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank) in rockchip_gpiolib_register() argument
587 bank->gpio_chip = rockchip_gpiolib_chip; in rockchip_gpiolib_register()
589 gc = &bank->gpio_chip; in rockchip_gpiolib_register()
590 gc->base = bank->pin_base; in rockchip_gpiolib_register()
591 gc->ngpio = bank->nr_pins; in rockchip_gpiolib_register()
592 gc->label = bank->name; in rockchip_gpiolib_register()
593 gc->parent = bank->dev; in rockchip_gpiolib_register()
595 ret = gpiochip_add_data(gc, bank); in rockchip_gpiolib_register()
597 dev_err(bank->dev, "failed to add gpiochip %s, %d\n", in rockchip_gpiolib_register()
598 gc->label, ret); in rockchip_gpiolib_register()
603 * For DeviceTree-supported systems, the gpio core checks the in rockchip_gpiolib_register()
604 * pinctrl's device node for the "gpio-ranges" property. in rockchip_gpiolib_register()
609 * files which don't set the "gpio-ranges" property or systems that in rockchip_gpiolib_register()
612 if (!of_property_present(bank->of_node, "gpio-ranges")) { in rockchip_gpiolib_register()
613 struct device_node *pctlnp = of_get_parent(bank->of_node); in rockchip_gpiolib_register()
617 return -ENODATA; in rockchip_gpiolib_register()
622 return -ENODEV; in rockchip_gpiolib_register()
624 ret = gpiochip_add_pin_range(gc, dev_name(pctldev->dev), 0, in rockchip_gpiolib_register()
625 gc->base, gc->ngpio); in rockchip_gpiolib_register()
627 dev_err(bank->dev, "Failed to add pin range\n"); in rockchip_gpiolib_register()
632 ret = rockchip_interrupts_register(bank); in rockchip_gpiolib_register()
634 dev_err(bank->dev, "failed to register interrupt, %d\n", ret); in rockchip_gpiolib_register()
641 gpiochip_remove(&bank->gpio_chip); in rockchip_gpiolib_register()
646 static int rockchip_get_bank_data(struct rockchip_pin_bank *bank) in rockchip_get_bank_data() argument
651 if (of_address_to_resource(bank->of_node, 0, &res)) { in rockchip_get_bank_data()
652 dev_err(bank->dev, "cannot find IO resource for bank\n"); in rockchip_get_bank_data()
653 return -ENOENT; in rockchip_get_bank_data()
656 bank->reg_base = devm_ioremap_resource(bank->dev, &res); in rockchip_get_bank_data()
657 if (IS_ERR(bank->reg_base)) in rockchip_get_bank_data()
658 return PTR_ERR(bank->reg_base); in rockchip_get_bank_data()
660 bank->irq = irq_of_parse_and_map(bank->of_node, 0); in rockchip_get_bank_data()
661 if (!bank->irq) in rockchip_get_bank_data()
662 return -EINVAL; in rockchip_get_bank_data()
664 bank->clk = of_clk_get(bank->of_node, 0); in rockchip_get_bank_data()
665 if (IS_ERR(bank->clk)) in rockchip_get_bank_data()
666 return PTR_ERR(bank->clk); in rockchip_get_bank_data()
668 clk_prepare_enable(bank->clk); in rockchip_get_bank_data()
669 id = readl(bank->reg_base + gpio_regs_v2.version_id); in rockchip_get_bank_data()
675 bank->gpio_regs = &gpio_regs_v2; in rockchip_get_bank_data()
676 bank->gpio_type = GPIO_TYPE_V2; in rockchip_get_bank_data()
677 bank->db_clk = of_clk_get(bank->of_node, 1); in rockchip_get_bank_data()
678 if (IS_ERR(bank->db_clk)) { in rockchip_get_bank_data()
679 dev_err(bank->dev, "cannot find debounce clk\n"); in rockchip_get_bank_data()
680 clk_disable_unprepare(bank->clk); in rockchip_get_bank_data()
681 return -EINVAL; in rockchip_get_bank_data()
685 bank->gpio_regs = &gpio_regs_v1; in rockchip_get_bank_data()
686 bank->gpio_type = GPIO_TYPE_V1; in rockchip_get_bank_data()
689 dev_err(bank->dev, "unsupported version ID: 0x%08x\n", id); in rockchip_get_bank_data()
690 return -ENODEV; in rockchip_get_bank_data()
700 struct rockchip_pin_bank *bank; in rockchip_gpio_find_bank() local
704 bank = info->ctrl->pin_banks; in rockchip_gpio_find_bank()
705 for (i = 0; i < info->ctrl->nr_banks; i++, bank++) { in rockchip_gpio_find_bank()
706 if (bank->bank_num == id) { in rockchip_gpio_find_bank()
712 return found ? bank : NULL; in rockchip_gpio_find_bank()
717 struct device *dev = &pdev->dev; in rockchip_gpio_probe()
718 struct device_node *np = dev->of_node; in rockchip_gpio_probe()
721 struct rockchip_pin_bank *bank = NULL; in rockchip_gpio_probe() local
723 static int gpio; in rockchip_gpio_probe() local
727 return -ENODEV; in rockchip_gpio_probe()
732 return -EPROBE_DEFER; in rockchip_gpio_probe()
734 id = of_alias_get_id(np, "gpio"); in rockchip_gpio_probe()
736 id = gpio++; in rockchip_gpio_probe()
738 bank = rockchip_gpio_find_bank(pctldev, id); in rockchip_gpio_probe()
739 if (!bank) in rockchip_gpio_probe()
740 return -EINVAL; in rockchip_gpio_probe()
742 bank->dev = dev; in rockchip_gpio_probe()
743 bank->of_node = np; in rockchip_gpio_probe()
745 raw_spin_lock_init(&bank->slock); in rockchip_gpio_probe()
747 ret = rockchip_get_bank_data(bank); in rockchip_gpio_probe()
755 mutex_lock(&bank->deferred_lock); in rockchip_gpio_probe()
757 ret = rockchip_gpiolib_register(bank); in rockchip_gpio_probe()
759 clk_disable_unprepare(bank->clk); in rockchip_gpio_probe()
760 mutex_unlock(&bank->deferred_lock); in rockchip_gpio_probe()
764 while (!list_empty(&bank->deferred_pins)) { in rockchip_gpio_probe()
765 cfg = list_first_entry(&bank->deferred_pins, in rockchip_gpio_probe()
767 list_del(&cfg->head); in rockchip_gpio_probe()
769 switch (cfg->param) { in rockchip_gpio_probe()
771 ret = rockchip_gpio_direction_output(&bank->gpio_chip, cfg->pin, cfg->arg); in rockchip_gpio_probe()
773 dev_warn(dev, "setting output pin %u to %u failed\n", cfg->pin, in rockchip_gpio_probe()
774 cfg->arg); in rockchip_gpio_probe()
777 ret = rockchip_gpio_direction_input(&bank->gpio_chip, cfg->pin); in rockchip_gpio_probe()
779 dev_warn(dev, "setting input pin %u failed\n", cfg->pin); in rockchip_gpio_probe()
782 dev_warn(dev, "unknown deferred config param %d\n", cfg->param); in rockchip_gpio_probe()
788 mutex_unlock(&bank->deferred_lock); in rockchip_gpio_probe()
790 platform_set_drvdata(pdev, bank); in rockchip_gpio_probe()
798 struct rockchip_pin_bank *bank = platform_get_drvdata(pdev); in rockchip_gpio_remove() local
800 clk_disable_unprepare(bank->clk); in rockchip_gpio_remove()
801 gpiochip_remove(&bank->gpio_chip); in rockchip_gpio_remove()
805 { .compatible = "rockchip,gpio-bank", },
806 { .compatible = "rockchip,rk3188-gpio-bank0" },
814 .name = "rockchip-gpio",
831 MODULE_DESCRIPTION("Rockchip gpio driver");
832 MODULE_ALIAS("platform:rockchip-gpio");