Lines Matching +full:gpio +full:- +full:cfg
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"
29 #define GPIO_TYPE_V1 (0) /* GPIO Version ID reserved */
30 #define GPIO_TYPE_V2 (0x01000C2B) /* GPIO Version ID 0x01000C2B */
31 #define GPIO_TYPE_V2_1 (0x0101157C) /* GPIO Version ID 0x0101157C */
79 void __iomem *reg = bank->reg_base + offset; in rockchip_gpio_writel()
81 if (bank->gpio_type == GPIO_TYPE_V2) in rockchip_gpio_writel()
90 void __iomem *reg = bank->reg_base + offset; in rockchip_gpio_readl()
93 if (bank->gpio_type == GPIO_TYPE_V2) in rockchip_gpio_readl()
105 void __iomem *reg = bank->reg_base + offset; in rockchip_gpio_writel_bit()
108 if (bank->gpio_type == GPIO_TYPE_V2) { in rockchip_gpio_writel_bit()
126 void __iomem *reg = bank->reg_base + offset; in rockchip_gpio_readl_bit()
129 if (bank->gpio_type == GPIO_TYPE_V2) { in rockchip_gpio_readl_bit()
146 data = rockchip_gpio_readl_bit(bank, offset, bank->gpio_regs->port_ddr); in rockchip_gpio_get_direction()
166 raw_spin_lock_irqsave(&bank->slock, flags); in rockchip_gpio_set_direction()
167 rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr); in rockchip_gpio_set_direction()
168 raw_spin_unlock_irqrestore(&bank->slock, flags); in rockchip_gpio_set_direction()
179 raw_spin_lock_irqsave(&bank->slock, flags); in rockchip_gpio_set()
180 rockchip_gpio_writel_bit(bank, offset, value, bank->gpio_regs->port_dr); in rockchip_gpio_set()
181 raw_spin_unlock_irqrestore(&bank->slock, flags); in rockchip_gpio_set()
189 data = readl(bank->reg_base + bank->gpio_regs->ext_port); in rockchip_gpio_get()
201 const struct rockchip_gpio_regs *reg = bank->gpio_regs; in rockchip_gpio_set_debounce()
207 if (bank->gpio_type == GPIO_TYPE_V2 && !IS_ERR(bank->db_clk)) { in rockchip_gpio_set_debounce()
209 freq = clk_get_rate(bank->db_clk); in rockchip_gpio_set_debounce()
212 return -EINVAL; in rockchip_gpio_set_debounce()
215 div_reg = DIV_ROUND_CLOSEST_ULL(div, 2 * USEC_PER_SEC) - 1; in rockchip_gpio_set_debounce()
220 raw_spin_lock_irqsave(&bank->slock, flags); in rockchip_gpio_set_debounce()
226 cur_div_reg = readl(bank->reg_base + in rockchip_gpio_set_debounce()
227 reg->dbclk_div_con); in rockchip_gpio_set_debounce()
229 writel(div_reg, bank->reg_base + in rockchip_gpio_set_debounce()
230 reg->dbclk_div_con); in rockchip_gpio_set_debounce()
232 reg->dbclk_div_en); in rockchip_gpio_set_debounce()
235 rockchip_gpio_writel_bit(bank, offset, 1, reg->debounce); in rockchip_gpio_set_debounce()
239 reg->dbclk_div_en); in rockchip_gpio_set_debounce()
241 rockchip_gpio_writel_bit(bank, offset, 0, reg->debounce); in rockchip_gpio_set_debounce()
244 raw_spin_unlock_irqrestore(&bank->slock, flags); in rockchip_gpio_set_debounce()
249 clk_prepare_enable(bank->db_clk); in rockchip_gpio_set_debounce()
251 clk_disable_unprepare(bank->db_clk); in rockchip_gpio_set_debounce()
273 * mux function as 'gpio output' will be handled by the pinctrl subsystem
285 * Rockchip's gpio could only support up to one period in rockchip_gpio_set_config()
291 * if the gpio is conguired as wakeup interrupt source. Let's in rockchip_gpio_set_config()
292 * still return -ENOTSUPP as before, to make sure the caller in rockchip_gpio_set_config()
295 return -ENOTSUPP; in rockchip_gpio_set_config()
297 return -ENOTSUPP; in rockchip_gpio_set_config()
302 * gpiod_to_irq() callback function. Creates a mapping between a GPIO pin
310 if (!bank->domain) in rockchip_gpio_to_irq()
311 return -ENXIO; in rockchip_gpio_to_irq()
313 virq = irq_create_mapping(bank->domain, offset); in rockchip_gpio_to_irq()
315 return (virq) ? : -ENXIO; in rockchip_gpio_to_irq()
338 dev_dbg(bank->dev, "got irq for bank %s\n", bank->name); in rockchip_irq_demux()
342 pending = readl_relaxed(bank->reg_base + bank->gpio_regs->int_status); in rockchip_irq_demux()
344 dev_dbg(bank->dev, "handling irq %d\n", irq); in rockchip_irq_demux()
350 if (bank->toggle_edge_mode & BIT(irq)) { in rockchip_irq_demux()
354 data = readl_relaxed(bank->reg_base + in rockchip_irq_demux()
355 bank->gpio_regs->ext_port); in rockchip_irq_demux()
357 raw_spin_lock_irqsave(&bank->slock, flags); in rockchip_irq_demux()
359 polarity = readl_relaxed(bank->reg_base + in rockchip_irq_demux()
360 bank->gpio_regs->int_polarity); in rockchip_irq_demux()
366 bank->reg_base + in rockchip_irq_demux()
367 bank->gpio_regs->int_polarity); in rockchip_irq_demux()
369 raw_spin_unlock_irqrestore(&bank->slock, flags); in rockchip_irq_demux()
372 data = readl_relaxed(bank->reg_base + in rockchip_irq_demux()
373 bank->gpio_regs->ext_port); in rockchip_irq_demux()
377 generic_handle_domain_irq(bank->domain, irq); in rockchip_irq_demux()
386 struct rockchip_pin_bank *bank = gc->private; in rockchip_irq_set_type()
387 u32 mask = BIT(d->hwirq); in rockchip_irq_set_type()
394 raw_spin_lock_irqsave(&bank->slock, flags); in rockchip_irq_set_type()
396 rockchip_gpio_writel_bit(bank, d->hwirq, 0, in rockchip_irq_set_type()
397 bank->gpio_regs->port_ddr); in rockchip_irq_set_type()
399 raw_spin_unlock_irqrestore(&bank->slock, flags); in rockchip_irq_set_type()
406 raw_spin_lock_irqsave(&bank->slock, flags); in rockchip_irq_set_type()
408 level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type); in rockchip_irq_set_type()
409 polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity); in rockchip_irq_set_type()
412 if (bank->gpio_type == GPIO_TYPE_V2) { in rockchip_irq_set_type()
413 rockchip_gpio_writel_bit(bank, d->hwirq, 1, in rockchip_irq_set_type()
414 bank->gpio_regs->int_bothedge); in rockchip_irq_set_type()
417 bank->toggle_edge_mode |= mask; in rockchip_irq_set_type()
421 * Determine gpio state. If 1 next interrupt should be in rockchip_irq_set_type()
424 data = readl(bank->reg_base + bank->gpio_regs->ext_port); in rockchip_irq_set_type()
431 if (bank->gpio_type == GPIO_TYPE_V2) { in rockchip_irq_set_type()
432 rockchip_gpio_writel_bit(bank, d->hwirq, 0, in rockchip_irq_set_type()
433 bank->gpio_regs->int_bothedge); in rockchip_irq_set_type()
435 bank->toggle_edge_mode &= ~mask; in rockchip_irq_set_type()
455 ret = -EINVAL; in rockchip_irq_set_type()
460 rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type); in rockchip_irq_set_type()
461 rockchip_gpio_writel(bank, polarity, bank->gpio_regs->int_polarity); in rockchip_irq_set_type()
463 raw_spin_unlock_irqrestore(&bank->slock, flags); in rockchip_irq_set_type()
471 struct rockchip_pin_bank *bank = gc->private; in rockchip_irq_reqres()
473 return gpiochip_reqres_irq(&bank->gpio_chip, d->hwirq); in rockchip_irq_reqres()
479 struct rockchip_pin_bank *bank = gc->private; in rockchip_irq_relres()
481 gpiochip_relres_irq(&bank->gpio_chip, d->hwirq); in rockchip_irq_relres()
487 struct rockchip_pin_bank *bank = gc->private; in rockchip_irq_suspend()
489 bank->saved_masks = irq_reg_readl(gc, bank->gpio_regs->int_mask); in rockchip_irq_suspend()
490 irq_reg_writel(gc, ~gc->wake_active, bank->gpio_regs->int_mask); in rockchip_irq_suspend()
496 struct rockchip_pin_bank *bank = gc->private; in rockchip_irq_resume()
498 irq_reg_writel(gc, bank->saved_masks, bank->gpio_regs->int_mask); in rockchip_irq_resume()
517 bank->domain = irq_domain_add_linear(bank->of_node, 32, in rockchip_interrupts_register()
519 if (!bank->domain) { in rockchip_interrupts_register()
520 dev_warn(bank->dev, "could not init irq domain for bank %s\n", in rockchip_interrupts_register()
521 bank->name); in rockchip_interrupts_register()
522 return -EINVAL; in rockchip_interrupts_register()
525 ret = irq_alloc_domain_generic_chips(bank->domain, 32, 1, in rockchip_interrupts_register()
530 dev_err(bank->dev, "could not alloc generic chips for bank %s\n", in rockchip_interrupts_register()
531 bank->name); in rockchip_interrupts_register()
532 irq_domain_remove(bank->domain); in rockchip_interrupts_register()
533 return -EINVAL; in rockchip_interrupts_register()
536 gc = irq_get_domain_generic_chip(bank->domain, 0); in rockchip_interrupts_register()
537 if (bank->gpio_type == GPIO_TYPE_V2) { in rockchip_interrupts_register()
538 gc->reg_writel = gpio_writel_v2; in rockchip_interrupts_register()
539 gc->reg_readl = gpio_readl_v2; in rockchip_interrupts_register()
542 gc->reg_base = bank->reg_base; in rockchip_interrupts_register()
543 gc->private = bank; in rockchip_interrupts_register()
544 gc->chip_types[0].regs.mask = bank->gpio_regs->int_mask; in rockchip_interrupts_register()
545 gc->chip_types[0].regs.ack = bank->gpio_regs->port_eoi; in rockchip_interrupts_register()
546 gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; in rockchip_interrupts_register()
547 gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; in rockchip_interrupts_register()
548 gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; in rockchip_interrupts_register()
549 gc->chip_types[0].chip.irq_enable = rockchip_irq_enable; in rockchip_interrupts_register()
550 gc->chip_types[0].chip.irq_disable = rockchip_irq_disable; in rockchip_interrupts_register()
551 gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; in rockchip_interrupts_register()
552 gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend; in rockchip_interrupts_register()
553 gc->chip_types[0].chip.irq_resume = rockchip_irq_resume; in rockchip_interrupts_register()
554 gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; in rockchip_interrupts_register()
555 gc->chip_types[0].chip.irq_request_resources = rockchip_irq_reqres; in rockchip_interrupts_register()
556 gc->chip_types[0].chip.irq_release_resources = rockchip_irq_relres; in rockchip_interrupts_register()
557 gc->wake_enabled = IRQ_MSK(bank->nr_pins); in rockchip_interrupts_register()
564 rockchip_gpio_writel(bank, 0xffffffff, bank->gpio_regs->int_mask); in rockchip_interrupts_register()
565 rockchip_gpio_writel(bank, 0xffffffff, bank->gpio_regs->port_eoi); in rockchip_interrupts_register()
566 rockchip_gpio_writel(bank, 0xffffffff, bank->gpio_regs->int_en); in rockchip_interrupts_register()
567 gc->mask_cache = 0xffffffff; in rockchip_interrupts_register()
569 irq_set_chained_handler_and_data(bank->irq, in rockchip_interrupts_register()
580 bank->gpio_chip = rockchip_gpiolib_chip; in rockchip_gpiolib_register()
582 gc = &bank->gpio_chip; in rockchip_gpiolib_register()
583 gc->base = bank->pin_base; in rockchip_gpiolib_register()
584 gc->ngpio = bank->nr_pins; in rockchip_gpiolib_register()
585 gc->label = bank->name; in rockchip_gpiolib_register()
586 gc->parent = bank->dev; in rockchip_gpiolib_register()
590 dev_err(bank->dev, "failed to add gpiochip %s, %d\n", in rockchip_gpiolib_register()
591 gc->label, ret); in rockchip_gpiolib_register()
596 * For DeviceTree-supported systems, the gpio core checks the in rockchip_gpiolib_register()
597 * pinctrl's device node for the "gpio-ranges" property. in rockchip_gpiolib_register()
602 * files which don't set the "gpio-ranges" property or systems that in rockchip_gpiolib_register()
605 if (!of_property_read_bool(bank->of_node, "gpio-ranges")) { in rockchip_gpiolib_register()
606 struct device_node *pctlnp = of_get_parent(bank->of_node); in rockchip_gpiolib_register()
610 return -ENODATA; in rockchip_gpiolib_register()
615 return -ENODEV; in rockchip_gpiolib_register()
617 ret = gpiochip_add_pin_range(gc, dev_name(pctldev->dev), 0, in rockchip_gpiolib_register()
618 gc->base, gc->ngpio); in rockchip_gpiolib_register()
620 dev_err(bank->dev, "Failed to add pin range\n"); in rockchip_gpiolib_register()
627 dev_err(bank->dev, "failed to register interrupt, %d\n", ret); in rockchip_gpiolib_register()
634 gpiochip_remove(&bank->gpio_chip); in rockchip_gpiolib_register()
644 if (of_address_to_resource(bank->of_node, 0, &res)) { in rockchip_get_bank_data()
645 dev_err(bank->dev, "cannot find IO resource for bank\n"); in rockchip_get_bank_data()
646 return -ENOENT; in rockchip_get_bank_data()
649 bank->reg_base = devm_ioremap_resource(bank->dev, &res); in rockchip_get_bank_data()
650 if (IS_ERR(bank->reg_base)) in rockchip_get_bank_data()
651 return PTR_ERR(bank->reg_base); in rockchip_get_bank_data()
653 bank->irq = irq_of_parse_and_map(bank->of_node, 0); in rockchip_get_bank_data()
654 if (!bank->irq) in rockchip_get_bank_data()
655 return -EINVAL; in rockchip_get_bank_data()
657 bank->clk = of_clk_get(bank->of_node, 0); in rockchip_get_bank_data()
658 if (IS_ERR(bank->clk)) in rockchip_get_bank_data()
659 return PTR_ERR(bank->clk); in rockchip_get_bank_data()
661 clk_prepare_enable(bank->clk); in rockchip_get_bank_data()
662 id = readl(bank->reg_base + gpio_regs_v2.version_id); in rockchip_get_bank_data()
664 /* If not gpio v2, that is default to v1. */ in rockchip_get_bank_data()
666 bank->gpio_regs = &gpio_regs_v2; in rockchip_get_bank_data()
667 bank->gpio_type = GPIO_TYPE_V2; in rockchip_get_bank_data()
668 bank->db_clk = of_clk_get(bank->of_node, 1); in rockchip_get_bank_data()
669 if (IS_ERR(bank->db_clk)) { in rockchip_get_bank_data()
670 dev_err(bank->dev, "cannot find debounce clk\n"); in rockchip_get_bank_data()
671 clk_disable_unprepare(bank->clk); in rockchip_get_bank_data()
672 return -EINVAL; in rockchip_get_bank_data()
675 bank->gpio_regs = &gpio_regs_v1; in rockchip_get_bank_data()
676 bank->gpio_type = GPIO_TYPE_V1; in rockchip_get_bank_data()
690 bank = info->ctrl->pin_banks; in rockchip_gpio_find_bank()
691 for (i = 0; i < info->ctrl->nr_banks; i++, bank++) { in rockchip_gpio_find_bank()
692 if (bank->bank_num == id) { in rockchip_gpio_find_bank()
703 struct device *dev = &pdev->dev; in rockchip_gpio_probe()
704 struct device_node *np = dev->of_node; in rockchip_gpio_probe()
708 struct rockchip_pin_deferred *cfg; in rockchip_gpio_probe() local
709 static int gpio; in rockchip_gpio_probe() local
713 return -ENODEV; in rockchip_gpio_probe()
718 return -EPROBE_DEFER; in rockchip_gpio_probe()
720 id = of_alias_get_id(np, "gpio"); in rockchip_gpio_probe()
722 id = gpio++; in rockchip_gpio_probe()
726 return -EINVAL; in rockchip_gpio_probe()
728 bank->dev = dev; in rockchip_gpio_probe()
729 bank->of_node = np; in rockchip_gpio_probe()
731 raw_spin_lock_init(&bank->slock); in rockchip_gpio_probe()
741 mutex_lock(&bank->deferred_lock); in rockchip_gpio_probe()
745 clk_disable_unprepare(bank->clk); in rockchip_gpio_probe()
746 mutex_unlock(&bank->deferred_lock); in rockchip_gpio_probe()
750 while (!list_empty(&bank->deferred_pins)) { in rockchip_gpio_probe()
751 cfg = list_first_entry(&bank->deferred_pins, in rockchip_gpio_probe()
753 list_del(&cfg->head); in rockchip_gpio_probe()
755 switch (cfg->param) { in rockchip_gpio_probe()
757 ret = rockchip_gpio_direction_output(&bank->gpio_chip, cfg->pin, cfg->arg); in rockchip_gpio_probe()
759 dev_warn(dev, "setting output pin %u to %u failed\n", cfg->pin, in rockchip_gpio_probe()
760 cfg->arg); in rockchip_gpio_probe()
763 ret = rockchip_gpio_direction_input(&bank->gpio_chip, cfg->pin); in rockchip_gpio_probe()
765 dev_warn(dev, "setting input pin %u failed\n", cfg->pin); in rockchip_gpio_probe()
768 dev_warn(dev, "unknown deferred config param %d\n", cfg->param); in rockchip_gpio_probe()
771 kfree(cfg); in rockchip_gpio_probe()
774 mutex_unlock(&bank->deferred_lock); in rockchip_gpio_probe()
786 clk_disable_unprepare(bank->clk); in rockchip_gpio_remove()
787 gpiochip_remove(&bank->gpio_chip); in rockchip_gpio_remove()
791 { .compatible = "rockchip,gpio-bank", },
792 { .compatible = "rockchip,rk3188-gpio-bank0" },
800 .name = "rockchip-gpio",
817 MODULE_DESCRIPTION("Rockchip gpio driver");
818 MODULE_ALIAS("platform:rockchip-gpio");