Lines Matching +full:gemini +full:- +full:gpio
1 // SPDX-License-Identifier: GPL-2.0
6 * Based on arch/arm/mach-gemini/gpio.c:
7 * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
9 * Based on plat-mxc/gpio.c:
10 * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
13 #include <linux/gpio/driver.h>
20 /* GPIO registers definition */
41 * struct ftgpio_gpio - Gemini GPIO state container
44 * @base: remapped I/O-memory base
59 writel(BIT(irqd_to_hwirq(d)), g->base + GPIO_INT_CLR); in ftgpio_gpio_ack_irq()
68 val = readl(g->base + GPIO_INT_EN); in ftgpio_gpio_mask_irq()
70 writel(val, g->base + GPIO_INT_EN); in ftgpio_gpio_mask_irq()
81 val = readl(g->base + GPIO_INT_EN); in ftgpio_gpio_unmask_irq()
83 writel(val, g->base + GPIO_INT_EN); in ftgpio_gpio_unmask_irq()
93 reg_type = readl(g->base + GPIO_INT_TYPE); in ftgpio_gpio_set_irq_type()
94 reg_level = readl(g->base + GPIO_INT_LEVEL); in ftgpio_gpio_set_irq_type()
95 reg_both = readl(g->base + GPIO_INT_BOTH_EDGE); in ftgpio_gpio_set_irq_type()
127 return -EINVAL; in ftgpio_gpio_set_irq_type()
130 writel(reg_type, g->base + GPIO_INT_TYPE); in ftgpio_gpio_set_irq_type()
131 writel(reg_level, g->base + GPIO_INT_LEVEL); in ftgpio_gpio_set_irq_type()
132 writel(reg_both, g->base + GPIO_INT_BOTH_EDGE); in ftgpio_gpio_set_irq_type()
149 stat = readl(g->base + GPIO_INT_STAT_RAW); in ftgpio_gpio_irq_handler()
151 for_each_set_bit(offset, &stat, gc->ngpio) in ftgpio_gpio_irq_handler()
152 generic_handle_domain_irq(gc->irq.domain, offset); in ftgpio_gpio_irq_handler()
168 return -ENOTSUPP; in ftgpio_gpio_set_config()
181 pclk_freq = clk_get_rate(g->clk); in ftgpio_gpio_set_config()
186 return -ENOTSUPP; in ftgpio_gpio_set_config()
188 dev_dbg(g->dev, "prescale divisor: %08x, resulting frequency %lu Hz\n", in ftgpio_gpio_set_config()
191 val = readl(g->base + GPIO_DEBOUNCE_PRESCALE); in ftgpio_gpio_set_config()
196 * debounce on this GPIO line and return. This happens more in ftgpio_gpio_set_config()
197 * often than you think, for example when all GPIO keys in ftgpio_gpio_set_config()
200 val = readl(g->base + GPIO_DEBOUNCE_EN); in ftgpio_gpio_set_config()
202 writel(val, g->base + GPIO_DEBOUNCE_EN); in ftgpio_gpio_set_config()
206 val = readl(g->base + GPIO_DEBOUNCE_EN); in ftgpio_gpio_set_config()
212 return -ENOTSUPP; in ftgpio_gpio_set_config()
216 writel(deb_div, g->base + GPIO_DEBOUNCE_PRESCALE); in ftgpio_gpio_set_config()
219 writel(val, g->base + GPIO_DEBOUNCE_EN); in ftgpio_gpio_set_config()
236 struct device *dev = &pdev->dev; in ftgpio_gpio_probe()
244 return -ENOMEM; in ftgpio_gpio_probe()
246 g->dev = dev; in ftgpio_gpio_probe()
248 g->base = devm_platform_ioremap_resource(pdev, 0); in ftgpio_gpio_probe()
249 if (IS_ERR(g->base)) in ftgpio_gpio_probe()
250 return PTR_ERR(g->base); in ftgpio_gpio_probe()
256 g->clk = devm_clk_get(dev, NULL); in ftgpio_gpio_probe()
257 if (!IS_ERR(g->clk)) { in ftgpio_gpio_probe()
258 ret = clk_prepare_enable(g->clk); in ftgpio_gpio_probe()
261 } else if (PTR_ERR(g->clk) == -EPROBE_DEFER) { in ftgpio_gpio_probe()
266 return PTR_ERR(g->clk); in ftgpio_gpio_probe()
269 ret = bgpio_init(&g->gc, dev, 4, in ftgpio_gpio_probe()
270 g->base + GPIO_DATA_IN, in ftgpio_gpio_probe()
271 g->base + GPIO_DATA_SET, in ftgpio_gpio_probe()
272 g->base + GPIO_DATA_CLR, in ftgpio_gpio_probe()
273 g->base + GPIO_DIR, in ftgpio_gpio_probe()
277 dev_err(dev, "unable to init generic GPIO\n"); in ftgpio_gpio_probe()
280 g->gc.label = dev_name(dev); in ftgpio_gpio_probe()
281 g->gc.base = -1; in ftgpio_gpio_probe()
282 g->gc.parent = dev; in ftgpio_gpio_probe()
283 g->gc.owner = THIS_MODULE; in ftgpio_gpio_probe()
287 if (!IS_ERR(g->clk)) in ftgpio_gpio_probe()
288 g->gc.set_config = ftgpio_gpio_set_config; in ftgpio_gpio_probe()
290 girq = &g->gc.irq; in ftgpio_gpio_probe()
292 girq->parent_handler = ftgpio_gpio_irq_handler; in ftgpio_gpio_probe()
293 girq->num_parents = 1; in ftgpio_gpio_probe()
294 girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents), in ftgpio_gpio_probe()
296 if (!girq->parents) { in ftgpio_gpio_probe()
297 ret = -ENOMEM; in ftgpio_gpio_probe()
300 girq->default_type = IRQ_TYPE_NONE; in ftgpio_gpio_probe()
301 girq->handler = handle_bad_irq; in ftgpio_gpio_probe()
302 girq->parents[0] = irq; in ftgpio_gpio_probe()
305 writel(0x0, g->base + GPIO_INT_EN); in ftgpio_gpio_probe()
306 writel(0x0, g->base + GPIO_INT_MASK); in ftgpio_gpio_probe()
307 writel(~0x0, g->base + GPIO_INT_CLR); in ftgpio_gpio_probe()
310 writel(0x0, g->base + GPIO_DEBOUNCE_EN); in ftgpio_gpio_probe()
312 ret = devm_gpiochip_add_data(dev, &g->gc, g); in ftgpio_gpio_probe()
317 dev_info(dev, "FTGPIO010 @%p registered\n", g->base); in ftgpio_gpio_probe()
322 clk_disable_unprepare(g->clk); in ftgpio_gpio_probe()
331 clk_disable_unprepare(g->clk); in ftgpio_gpio_remove()
336 .compatible = "cortina,gemini-gpio",
339 .compatible = "moxa,moxart-gpio",
349 .name = "ftgpio010-gpio",