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>
75 .edge_sel_reg = -EINVAL,
90 .edge_sel_reg = -EINVAL,
112 #define GPIO_DR (port->hwdata->dr_reg)
113 #define GPIO_GDIR (port->hwdata->gdir_reg)
114 #define GPIO_PSR (port->hwdata->psr_reg)
115 #define GPIO_ICR1 (port->hwdata->icr1_reg)
116 #define GPIO_ICR2 (port->hwdata->icr2_reg)
117 #define GPIO_IMR (port->hwdata->imr_reg)
118 #define GPIO_ISR (port->hwdata->isr_reg)
119 #define GPIO_EDGE_SEL (port->hwdata->edge_sel_reg)
121 #define GPIO_INT_LOW_LEV (port->hwdata->low_level)
122 #define GPIO_INT_HIGH_LEV (port->hwdata->high_level)
123 #define GPIO_INT_RISE_EDGE (port->hwdata->rise_edge)
124 #define GPIO_INT_FALL_EDGE (port->hwdata->fall_edge)
128 { .compatible = "fsl,imx1-gpio", .data = &imx1_imx21_gpio_hwdata },
129 { .compatible = "fsl,imx21-gpio", .data = &imx1_imx21_gpio_hwdata },
130 { .compatible = "fsl,imx31-gpio", .data = &imx31_gpio_hwdata },
131 { .compatible = "fsl,imx35-gpio", .data = &imx35_gpio_hwdata },
132 { .compatible = "fsl,imx7d-gpio", .data = &imx35_gpio_hwdata },
138 * MX2 has one interrupt *for all* gpio ports. The list is used
149 struct mxc_gpio_port *port = gc->private; in gpio_set_irq_type()
151 u32 gpio_idx = d->hwirq; in gpio_set_irq_type()
153 void __iomem *reg = port->base; in gpio_set_irq_type()
155 port->both_edges &= ~(1 << gpio_idx); in gpio_set_irq_type()
167 val = port->gc.get(&port->gc, gpio_idx); in gpio_set_irq_type()
170 pr_debug("mxc: set GPIO %d to low trigger\n", gpio_idx); in gpio_set_irq_type()
173 pr_debug("mxc: set GPIO %d to high trigger\n", gpio_idx); in gpio_set_irq_type()
175 port->both_edges |= 1 << gpio_idx; in gpio_set_irq_type()
185 return -EINVAL; in gpio_set_irq_type()
189 val = readl(port->base + GPIO_EDGE_SEL); in gpio_set_irq_type()
192 port->base + GPIO_EDGE_SEL); in gpio_set_irq_type()
195 port->base + GPIO_EDGE_SEL); in gpio_set_irq_type()
205 writel(1 << gpio_idx, port->base + GPIO_ISR); in gpio_set_irq_type()
210 static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) in mxc_flip_edge() argument
212 void __iomem *reg = port->base; in mxc_flip_edge()
216 reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ in mxc_flip_edge()
217 bit = gpio & 0xf; in mxc_flip_edge()
223 pr_debug("mxc: switch GPIO %d to low trigger\n", gpio); in mxc_flip_edge()
226 pr_debug("mxc: switch GPIO %d to high trigger\n", gpio); in mxc_flip_edge()
228 pr_err("mxc: invalid configuration for GPIO %d: %x\n", in mxc_flip_edge()
229 gpio, edge); in mxc_flip_edge()
239 int irqoffset = fls(irq_stat) - 1; in mxc_gpio_irq_handler()
241 if (port->both_edges & (1 << irqoffset)) in mxc_gpio_irq_handler()
244 generic_handle_domain_irq(port->domain, irqoffset); in mxc_gpio_irq_handler()
250 /* MX1 and MX3 has one interrupt *per* gpio port */
259 irq_stat = readl(port->base + GPIO_ISR) & readl(port->base + GPIO_IMR); in mx3_gpio_irq_handler()
266 /* MX2 has one interrupt *for all* gpio ports */
277 irq_msk = readl(port->base + GPIO_IMR); in mx2_gpio_irq_handler()
281 irq_stat = readl(port->base + GPIO_ISR) & irq_msk; in mx2_gpio_irq_handler()
289 * Set interrupt number "irq" in the GPIO as a wake-up source.
290 * While system is running, all registered GPIO interrupts need to have
291 * wake-up enabled. When system is suspended, only selected GPIO interrupts
292 * need to have wake-up enabled.
294 * @param enable enable as wake-up if equal to non-zero
300 struct mxc_gpio_port *port = gc->private; in gpio_set_wake_irq()
301 u32 gpio_idx = d->hwirq; in gpio_set_wake_irq()
305 if (port->irq_high && (gpio_idx >= 16)) in gpio_set_wake_irq()
306 ret = enable_irq_wake(port->irq_high); in gpio_set_wake_irq()
308 ret = enable_irq_wake(port->irq); in gpio_set_wake_irq()
310 if (port->irq_high && (gpio_idx >= 16)) in gpio_set_wake_irq()
311 ret = disable_irq_wake(port->irq_high); in gpio_set_wake_irq()
313 ret = disable_irq_wake(port->irq); in gpio_set_wake_irq()
325 gc = devm_irq_alloc_generic_chip(port->dev, "gpio-mxc", 1, irq_base, in mxc_gpio_init_gc()
326 port->base, handle_level_irq); in mxc_gpio_init_gc()
328 return -ENOMEM; in mxc_gpio_init_gc()
329 gc->private = port; in mxc_gpio_init_gc()
331 ct = gc->chip_types; in mxc_gpio_init_gc()
332 ct->chip.irq_ack = irq_gc_ack_set_bit; in mxc_gpio_init_gc()
333 ct->chip.irq_mask = irq_gc_mask_clr_bit; in mxc_gpio_init_gc()
334 ct->chip.irq_unmask = irq_gc_mask_set_bit; in mxc_gpio_init_gc()
335 ct->chip.irq_set_type = gpio_set_irq_type; in mxc_gpio_init_gc()
336 ct->chip.irq_set_wake = gpio_set_wake_irq; in mxc_gpio_init_gc()
337 ct->chip.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND; in mxc_gpio_init_gc()
338 ct->regs.ack = GPIO_ISR; in mxc_gpio_init_gc()
339 ct->regs.mask = GPIO_IMR; in mxc_gpio_init_gc()
341 rv = devm_irq_setup_generic_chip(port->dev, gc, IRQ_MSK(32), in mxc_gpio_init_gc()
352 return irq_find_mapping(port->domain, offset); in mxc_gpio_to_irq()
357 struct device_node *np = pdev->dev.of_node; in mxc_gpio_probe()
363 port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL); in mxc_gpio_probe()
365 return -ENOMEM; in mxc_gpio_probe()
367 port->dev = &pdev->dev; in mxc_gpio_probe()
369 port->hwdata = device_get_match_data(&pdev->dev); in mxc_gpio_probe()
371 port->base = devm_platform_ioremap_resource(pdev, 0); in mxc_gpio_probe()
372 if (IS_ERR(port->base)) in mxc_gpio_probe()
373 return PTR_ERR(port->base); in mxc_gpio_probe()
380 port->irq_high = platform_get_irq(pdev, 1); in mxc_gpio_probe()
381 if (port->irq_high < 0) in mxc_gpio_probe()
382 port->irq_high = 0; in mxc_gpio_probe()
385 port->irq = platform_get_irq(pdev, 0); in mxc_gpio_probe()
386 if (port->irq < 0) in mxc_gpio_probe()
387 return port->irq; in mxc_gpio_probe()
390 port->clk = devm_clk_get_optional(&pdev->dev, NULL); in mxc_gpio_probe()
391 if (IS_ERR(port->clk)) in mxc_gpio_probe()
392 return PTR_ERR(port->clk); in mxc_gpio_probe()
394 err = clk_prepare_enable(port->clk); in mxc_gpio_probe()
396 dev_err(&pdev->dev, "Unable to enable clock.\n"); in mxc_gpio_probe()
400 if (of_device_is_compatible(np, "fsl,imx7d-gpio")) in mxc_gpio_probe()
401 port->power_off = true; in mxc_gpio_probe()
404 writel(0, port->base + GPIO_IMR); in mxc_gpio_probe()
405 writel(~0, port->base + GPIO_ISR); in mxc_gpio_probe()
407 if (of_device_is_compatible(np, "fsl,imx21-gpio")) { in mxc_gpio_probe()
409 * Setup one handler for all GPIO interrupts. Actually setting in mxc_gpio_probe()
413 irq_set_chained_handler(port->irq, mx2_gpio_irq_handler); in mxc_gpio_probe()
416 irq_set_chained_handler_and_data(port->irq, in mxc_gpio_probe()
418 if (port->irq_high > 0) in mxc_gpio_probe()
419 /* setup handler for GPIO 16 to 31 */ in mxc_gpio_probe()
420 irq_set_chained_handler_and_data(port->irq_high, in mxc_gpio_probe()
425 err = bgpio_init(&port->gc, &pdev->dev, 4, in mxc_gpio_probe()
426 port->base + GPIO_PSR, in mxc_gpio_probe()
427 port->base + GPIO_DR, NULL, in mxc_gpio_probe()
428 port->base + GPIO_GDIR, NULL, in mxc_gpio_probe()
433 port->gc.request = gpiochip_generic_request; in mxc_gpio_probe()
434 port->gc.free = gpiochip_generic_free; in mxc_gpio_probe()
435 port->gc.to_irq = mxc_gpio_to_irq; in mxc_gpio_probe()
436 port->gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 : in mxc_gpio_probe()
437 pdev->id * 32; in mxc_gpio_probe()
439 err = devm_gpiochip_add_data(&pdev->dev, &port->gc, port); in mxc_gpio_probe()
443 irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, 32, numa_node_id()); in mxc_gpio_probe()
449 port->domain = irq_domain_add_legacy(np, 32, irq_base, 0, in mxc_gpio_probe()
451 if (!port->domain) { in mxc_gpio_probe()
452 err = -ENODEV; in mxc_gpio_probe()
456 /* gpio-mxc can be a generic irq chip */ in mxc_gpio_probe()
461 list_add_tail(&port->node, &mxc_gpio_ports); in mxc_gpio_probe()
468 irq_domain_remove(port->domain); in mxc_gpio_probe()
470 clk_disable_unprepare(port->clk); in mxc_gpio_probe()
471 dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err); in mxc_gpio_probe()
477 if (!port->power_off) in mxc_gpio_save_regs()
480 port->gpio_saved_reg.icr1 = readl(port->base + GPIO_ICR1); in mxc_gpio_save_regs()
481 port->gpio_saved_reg.icr2 = readl(port->base + GPIO_ICR2); in mxc_gpio_save_regs()
482 port->gpio_saved_reg.imr = readl(port->base + GPIO_IMR); in mxc_gpio_save_regs()
483 port->gpio_saved_reg.gdir = readl(port->base + GPIO_GDIR); in mxc_gpio_save_regs()
484 port->gpio_saved_reg.edge_sel = readl(port->base + GPIO_EDGE_SEL); in mxc_gpio_save_regs()
485 port->gpio_saved_reg.dr = readl(port->base + GPIO_DR); in mxc_gpio_save_regs()
490 if (!port->power_off) in mxc_gpio_restore_regs()
493 writel(port->gpio_saved_reg.icr1, port->base + GPIO_ICR1); in mxc_gpio_restore_regs()
494 writel(port->gpio_saved_reg.icr2, port->base + GPIO_ICR2); in mxc_gpio_restore_regs()
495 writel(port->gpio_saved_reg.imr, port->base + GPIO_IMR); in mxc_gpio_restore_regs()
496 writel(port->gpio_saved_reg.gdir, port->base + GPIO_GDIR); in mxc_gpio_restore_regs()
497 writel(port->gpio_saved_reg.edge_sel, port->base + GPIO_EDGE_SEL); in mxc_gpio_restore_regs()
498 writel(port->gpio_saved_reg.dr, port->base + GPIO_DR); in mxc_gpio_restore_regs()
508 clk_disable_unprepare(port->clk); in mxc_gpio_syscore_suspend()
521 ret = clk_prepare_enable(port->clk); in mxc_gpio_syscore_resume()
523 pr_err("mxc: failed to enable gpio clock %d\n", ret); in mxc_gpio_syscore_resume()
537 .name = "gpio-mxc",
553 MODULE_DESCRIPTION("i.MX GPIO Driver");