Lines Matching +full:imx35 +full:- +full:gpio
1 // SPDX-License-Identifier: GPL-2.0+
3 // MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
8 // Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
22 #include <linux/gpio/driver.h>
81 .edge_sel_reg = -EINVAL,
96 .edge_sel_reg = -EINVAL,
121 #define GPIO_DR (mxc_gpio_hwdata->dr_reg)
122 #define GPIO_GDIR (mxc_gpio_hwdata->gdir_reg)
123 #define GPIO_PSR (mxc_gpio_hwdata->psr_reg)
124 #define GPIO_ICR1 (mxc_gpio_hwdata->icr1_reg)
125 #define GPIO_ICR2 (mxc_gpio_hwdata->icr2_reg)
126 #define GPIO_IMR (mxc_gpio_hwdata->imr_reg)
127 #define GPIO_ISR (mxc_gpio_hwdata->isr_reg)
128 #define GPIO_EDGE_SEL (mxc_gpio_hwdata->edge_sel_reg)
130 #define GPIO_INT_LOW_LEV (mxc_gpio_hwdata->low_level)
131 #define GPIO_INT_HIGH_LEV (mxc_gpio_hwdata->high_level)
132 #define GPIO_INT_RISE_EDGE (mxc_gpio_hwdata->rise_edge)
133 #define GPIO_INT_FALL_EDGE (mxc_gpio_hwdata->fall_edge)
138 .name = "imx1-gpio",
141 .name = "imx21-gpio",
144 .name = "imx31-gpio",
147 .name = "imx35-gpio",
155 { .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], },
156 { .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], },
157 { .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], },
158 { .compatible = "fsl,imx35-gpio", .data = &mxc_gpio_devtype[IMX35_GPIO], },
159 { .compatible = "fsl,imx7d-gpio", .data = &mxc_gpio_devtype[IMX35_GPIO], },
165 * MX2 has one interrupt *for all* gpio ports. The list is used
176 struct mxc_gpio_port *port = gc->private; in gpio_set_irq_type()
178 u32 gpio_idx = d->hwirq; in gpio_set_irq_type()
180 void __iomem *reg = port->base; in gpio_set_irq_type()
182 port->both_edges &= ~(1 << gpio_idx); in gpio_set_irq_type()
194 val = port->gc.get(&port->gc, gpio_idx); in gpio_set_irq_type()
197 pr_debug("mxc: set GPIO %d to low trigger\n", gpio_idx); in gpio_set_irq_type()
200 pr_debug("mxc: set GPIO %d to high trigger\n", gpio_idx); in gpio_set_irq_type()
202 port->both_edges |= 1 << gpio_idx; in gpio_set_irq_type()
212 return -EINVAL; in gpio_set_irq_type()
216 val = readl(port->base + GPIO_EDGE_SEL); in gpio_set_irq_type()
219 port->base + GPIO_EDGE_SEL); in gpio_set_irq_type()
222 port->base + GPIO_EDGE_SEL); in gpio_set_irq_type()
232 writel(1 << gpio_idx, port->base + GPIO_ISR); in gpio_set_irq_type()
237 static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) in mxc_flip_edge() argument
239 void __iomem *reg = port->base; in mxc_flip_edge()
243 reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ in mxc_flip_edge()
244 bit = gpio & 0xf; in mxc_flip_edge()
250 pr_debug("mxc: switch GPIO %d to low trigger\n", gpio); in mxc_flip_edge()
253 pr_debug("mxc: switch GPIO %d to high trigger\n", gpio); in mxc_flip_edge()
255 pr_err("mxc: invalid configuration for GPIO %d: %x\n", in mxc_flip_edge()
256 gpio, edge); in mxc_flip_edge()
266 int irqoffset = fls(irq_stat) - 1; in mxc_gpio_irq_handler()
268 if (port->both_edges & (1 << irqoffset)) in mxc_gpio_irq_handler()
271 generic_handle_irq(irq_find_mapping(port->domain, irqoffset)); in mxc_gpio_irq_handler()
277 /* MX1 and MX3 has one interrupt *per* gpio port */
286 irq_stat = readl(port->base + GPIO_ISR) & readl(port->base + GPIO_IMR); in mx3_gpio_irq_handler()
293 /* MX2 has one interrupt *for all* gpio ports */
304 irq_msk = readl(port->base + GPIO_IMR); in mx2_gpio_irq_handler()
308 irq_stat = readl(port->base + GPIO_ISR) & irq_msk; in mx2_gpio_irq_handler()
316 * Set interrupt number "irq" in the GPIO as a wake-up source.
317 * While system is running, all registered GPIO interrupts need to have
318 * wake-up enabled. When system is suspended, only selected GPIO interrupts
319 * need to have wake-up enabled.
321 * @param enable enable as wake-up if equal to non-zero
327 struct mxc_gpio_port *port = gc->private; in gpio_set_wake_irq()
328 u32 gpio_idx = d->hwirq; in gpio_set_wake_irq()
332 if (port->irq_high && (gpio_idx >= 16)) in gpio_set_wake_irq()
333 ret = enable_irq_wake(port->irq_high); in gpio_set_wake_irq()
335 ret = enable_irq_wake(port->irq); in gpio_set_wake_irq()
337 if (port->irq_high && (gpio_idx >= 16)) in gpio_set_wake_irq()
338 ret = disable_irq_wake(port->irq_high); in gpio_set_wake_irq()
340 ret = disable_irq_wake(port->irq); in gpio_set_wake_irq()
352 gc = devm_irq_alloc_generic_chip(port->dev, "gpio-mxc", 1, irq_base, in mxc_gpio_init_gc()
353 port->base, handle_level_irq); in mxc_gpio_init_gc()
355 return -ENOMEM; in mxc_gpio_init_gc()
356 gc->private = port; in mxc_gpio_init_gc()
358 ct = gc->chip_types; in mxc_gpio_init_gc()
359 ct->chip.irq_ack = irq_gc_ack_set_bit; in mxc_gpio_init_gc()
360 ct->chip.irq_mask = irq_gc_mask_clr_bit; in mxc_gpio_init_gc()
361 ct->chip.irq_unmask = irq_gc_mask_set_bit; in mxc_gpio_init_gc()
362 ct->chip.irq_set_type = gpio_set_irq_type; in mxc_gpio_init_gc()
363 ct->chip.irq_set_wake = gpio_set_wake_irq; in mxc_gpio_init_gc()
364 ct->chip.flags = IRQCHIP_MASK_ON_SUSPEND; in mxc_gpio_init_gc()
365 ct->regs.ack = GPIO_ISR; in mxc_gpio_init_gc()
366 ct->regs.mask = GPIO_IMR; in mxc_gpio_init_gc()
368 rv = devm_irq_setup_generic_chip(port->dev, gc, IRQ_MSK(32), in mxc_gpio_init_gc()
378 of_match_device(mxc_gpio_dt_ids, &pdev->dev); in mxc_gpio_get_hw()
382 pdev->id_entry = of_id->data; in mxc_gpio_get_hw()
383 hwtype = pdev->id_entry->driver_data; in mxc_gpio_get_hw()
388 * that is all gpio ports must be the same type when in mxc_gpio_get_hw()
409 return irq_find_mapping(port->domain, offset); in mxc_gpio_to_irq()
414 struct device_node *np = pdev->dev.of_node; in mxc_gpio_probe()
422 port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL); in mxc_gpio_probe()
424 return -ENOMEM; in mxc_gpio_probe()
426 port->dev = &pdev->dev; in mxc_gpio_probe()
428 port->base = devm_platform_ioremap_resource(pdev, 0); in mxc_gpio_probe()
429 if (IS_ERR(port->base)) in mxc_gpio_probe()
430 return PTR_ERR(port->base); in mxc_gpio_probe()
437 port->irq_high = platform_get_irq(pdev, 1); in mxc_gpio_probe()
438 if (port->irq_high < 0) in mxc_gpio_probe()
439 port->irq_high = 0; in mxc_gpio_probe()
442 port->irq = platform_get_irq(pdev, 0); in mxc_gpio_probe()
443 if (port->irq < 0) in mxc_gpio_probe()
444 return port->irq; in mxc_gpio_probe()
447 port->clk = devm_clk_get_optional(&pdev->dev, NULL); in mxc_gpio_probe()
448 if (IS_ERR(port->clk)) in mxc_gpio_probe()
449 return PTR_ERR(port->clk); in mxc_gpio_probe()
451 err = clk_prepare_enable(port->clk); in mxc_gpio_probe()
453 dev_err(&pdev->dev, "Unable to enable clock.\n"); in mxc_gpio_probe()
457 if (of_device_is_compatible(np, "fsl,imx7d-gpio")) in mxc_gpio_probe()
458 port->power_off = true; in mxc_gpio_probe()
461 writel(0, port->base + GPIO_IMR); in mxc_gpio_probe()
462 writel(~0, port->base + GPIO_ISR); in mxc_gpio_probe()
466 * Setup one handler for all GPIO interrupts. Actually setting in mxc_gpio_probe()
470 irq_set_chained_handler(port->irq, mx2_gpio_irq_handler); in mxc_gpio_probe()
473 irq_set_chained_handler_and_data(port->irq, in mxc_gpio_probe()
475 if (port->irq_high > 0) in mxc_gpio_probe()
476 /* setup handler for GPIO 16 to 31 */ in mxc_gpio_probe()
477 irq_set_chained_handler_and_data(port->irq_high, in mxc_gpio_probe()
482 err = bgpio_init(&port->gc, &pdev->dev, 4, in mxc_gpio_probe()
483 port->base + GPIO_PSR, in mxc_gpio_probe()
484 port->base + GPIO_DR, NULL, in mxc_gpio_probe()
485 port->base + GPIO_GDIR, NULL, in mxc_gpio_probe()
490 port->gc.request = gpiochip_generic_request; in mxc_gpio_probe()
491 port->gc.free = gpiochip_generic_free; in mxc_gpio_probe()
492 port->gc.to_irq = mxc_gpio_to_irq; in mxc_gpio_probe()
493 port->gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 : in mxc_gpio_probe()
494 pdev->id * 32; in mxc_gpio_probe()
496 err = devm_gpiochip_add_data(&pdev->dev, &port->gc, port); in mxc_gpio_probe()
500 irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, 32, numa_node_id()); in mxc_gpio_probe()
506 port->domain = irq_domain_add_legacy(np, 32, irq_base, 0, in mxc_gpio_probe()
508 if (!port->domain) { in mxc_gpio_probe()
509 err = -ENODEV; in mxc_gpio_probe()
513 /* gpio-mxc can be a generic irq chip */ in mxc_gpio_probe()
518 list_add_tail(&port->node, &mxc_gpio_ports); in mxc_gpio_probe()
525 irq_domain_remove(port->domain); in mxc_gpio_probe()
527 clk_disable_unprepare(port->clk); in mxc_gpio_probe()
528 dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err); in mxc_gpio_probe()
534 if (!port->power_off) in mxc_gpio_save_regs()
537 port->gpio_saved_reg.icr1 = readl(port->base + GPIO_ICR1); in mxc_gpio_save_regs()
538 port->gpio_saved_reg.icr2 = readl(port->base + GPIO_ICR2); in mxc_gpio_save_regs()
539 port->gpio_saved_reg.imr = readl(port->base + GPIO_IMR); in mxc_gpio_save_regs()
540 port->gpio_saved_reg.gdir = readl(port->base + GPIO_GDIR); in mxc_gpio_save_regs()
541 port->gpio_saved_reg.edge_sel = readl(port->base + GPIO_EDGE_SEL); in mxc_gpio_save_regs()
542 port->gpio_saved_reg.dr = readl(port->base + GPIO_DR); in mxc_gpio_save_regs()
547 if (!port->power_off) in mxc_gpio_restore_regs()
550 writel(port->gpio_saved_reg.icr1, port->base + GPIO_ICR1); in mxc_gpio_restore_regs()
551 writel(port->gpio_saved_reg.icr2, port->base + GPIO_ICR2); in mxc_gpio_restore_regs()
552 writel(port->gpio_saved_reg.imr, port->base + GPIO_IMR); in mxc_gpio_restore_regs()
553 writel(port->gpio_saved_reg.gdir, port->base + GPIO_GDIR); in mxc_gpio_restore_regs()
554 writel(port->gpio_saved_reg.edge_sel, port->base + GPIO_EDGE_SEL); in mxc_gpio_restore_regs()
555 writel(port->gpio_saved_reg.dr, port->base + GPIO_DR); in mxc_gpio_restore_regs()
565 clk_disable_unprepare(port->clk); in mxc_gpio_syscore_suspend()
578 ret = clk_prepare_enable(port->clk); in mxc_gpio_syscore_resume()
580 pr_err("mxc: failed to enable gpio clock %d\n", ret); in mxc_gpio_syscore_resume()
594 .name = "gpio-mxc",
611 MODULE_DESCRIPTION("i.MX GPIO Driver");