1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Faraday Technolog FTGPIO010 gpiochip and interrupt routines |
4 | * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> |
5 | * |
6 | * Based on arch/arm/mach-gemini/gpio.c: |
7 | * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> |
8 | * |
9 | * Based on plat-mxc/gpio.c: |
10 | * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de> |
11 | * Copyright 2008 Juergen Beisert, kernel@pengutronix.de |
12 | */ |
13 | #include <linux/gpio/driver.h> |
14 | #include <linux/io.h> |
15 | #include <linux/interrupt.h> |
16 | #include <linux/platform_device.h> |
17 | #include <linux/bitops.h> |
18 | #include <linux/clk.h> |
19 | |
20 | /* GPIO registers definition */ |
21 | #define GPIO_DATA_OUT 0x00 |
22 | #define GPIO_DATA_IN 0x04 |
23 | #define GPIO_DIR 0x08 |
24 | #define GPIO_BYPASS_IN 0x0C |
25 | #define GPIO_DATA_SET 0x10 |
26 | #define GPIO_DATA_CLR 0x14 |
27 | #define GPIO_PULL_EN 0x18 |
28 | #define GPIO_PULL_TYPE 0x1C |
29 | #define GPIO_INT_EN 0x20 |
30 | #define GPIO_INT_STAT_RAW 0x24 |
31 | #define GPIO_INT_STAT_MASKED 0x28 |
32 | #define GPIO_INT_MASK 0x2C |
33 | #define GPIO_INT_CLR 0x30 |
34 | #define GPIO_INT_TYPE 0x34 |
35 | #define GPIO_INT_BOTH_EDGE 0x38 |
36 | #define GPIO_INT_LEVEL 0x3C |
37 | #define GPIO_DEBOUNCE_EN 0x40 |
38 | #define GPIO_DEBOUNCE_PRESCALE 0x44 |
39 | |
40 | /** |
41 | * struct ftgpio_gpio - Gemini GPIO state container |
42 | * @dev: containing device for this instance |
43 | * @gc: gpiochip for this instance |
44 | * @base: remapped I/O-memory base |
45 | * @clk: silicon clock |
46 | */ |
47 | struct ftgpio_gpio { |
48 | struct device *dev; |
49 | struct gpio_chip gc; |
50 | void __iomem *base; |
51 | struct clk *clk; |
52 | }; |
53 | |
54 | static void ftgpio_gpio_ack_irq(struct irq_data *d) |
55 | { |
56 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
57 | struct ftgpio_gpio *g = gpiochip_get_data(gc); |
58 | |
59 | writel(BIT(irqd_to_hwirq(d)), addr: g->base + GPIO_INT_CLR); |
60 | } |
61 | |
62 | static void ftgpio_gpio_mask_irq(struct irq_data *d) |
63 | { |
64 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
65 | struct ftgpio_gpio *g = gpiochip_get_data(gc); |
66 | u32 val; |
67 | |
68 | val = readl(addr: g->base + GPIO_INT_EN); |
69 | val &= ~BIT(irqd_to_hwirq(d)); |
70 | writel(val, addr: g->base + GPIO_INT_EN); |
71 | gpiochip_disable_irq(gc, offset: irqd_to_hwirq(d)); |
72 | } |
73 | |
74 | static void ftgpio_gpio_unmask_irq(struct irq_data *d) |
75 | { |
76 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
77 | struct ftgpio_gpio *g = gpiochip_get_data(gc); |
78 | u32 val; |
79 | |
80 | gpiochip_enable_irq(gc, offset: irqd_to_hwirq(d)); |
81 | val = readl(addr: g->base + GPIO_INT_EN); |
82 | val |= BIT(irqd_to_hwirq(d)); |
83 | writel(val, addr: g->base + GPIO_INT_EN); |
84 | } |
85 | |
86 | static int ftgpio_gpio_set_irq_type(struct irq_data *d, unsigned int type) |
87 | { |
88 | struct gpio_chip *gc = irq_data_get_irq_chip_data(d); |
89 | struct ftgpio_gpio *g = gpiochip_get_data(gc); |
90 | u32 mask = BIT(irqd_to_hwirq(d)); |
91 | u32 reg_both, reg_level, reg_type; |
92 | |
93 | reg_type = readl(addr: g->base + GPIO_INT_TYPE); |
94 | reg_level = readl(addr: g->base + GPIO_INT_LEVEL); |
95 | reg_both = readl(addr: g->base + GPIO_INT_BOTH_EDGE); |
96 | |
97 | switch (type) { |
98 | case IRQ_TYPE_EDGE_BOTH: |
99 | irq_set_handler_locked(data: d, handler: handle_edge_irq); |
100 | reg_type &= ~mask; |
101 | reg_both |= mask; |
102 | break; |
103 | case IRQ_TYPE_EDGE_RISING: |
104 | irq_set_handler_locked(data: d, handler: handle_edge_irq); |
105 | reg_type &= ~mask; |
106 | reg_both &= ~mask; |
107 | reg_level &= ~mask; |
108 | break; |
109 | case IRQ_TYPE_EDGE_FALLING: |
110 | irq_set_handler_locked(data: d, handler: handle_edge_irq); |
111 | reg_type &= ~mask; |
112 | reg_both &= ~mask; |
113 | reg_level |= mask; |
114 | break; |
115 | case IRQ_TYPE_LEVEL_HIGH: |
116 | irq_set_handler_locked(data: d, handler: handle_level_irq); |
117 | reg_type |= mask; |
118 | reg_level &= ~mask; |
119 | break; |
120 | case IRQ_TYPE_LEVEL_LOW: |
121 | irq_set_handler_locked(data: d, handler: handle_level_irq); |
122 | reg_type |= mask; |
123 | reg_level |= mask; |
124 | break; |
125 | default: |
126 | irq_set_handler_locked(data: d, handler: handle_bad_irq); |
127 | return -EINVAL; |
128 | } |
129 | |
130 | writel(val: reg_type, addr: g->base + GPIO_INT_TYPE); |
131 | writel(val: reg_level, addr: g->base + GPIO_INT_LEVEL); |
132 | writel(val: reg_both, addr: g->base + GPIO_INT_BOTH_EDGE); |
133 | |
134 | ftgpio_gpio_ack_irq(d); |
135 | |
136 | return 0; |
137 | } |
138 | |
139 | static void ftgpio_gpio_irq_handler(struct irq_desc *desc) |
140 | { |
141 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); |
142 | struct ftgpio_gpio *g = gpiochip_get_data(gc); |
143 | struct irq_chip *irqchip = irq_desc_get_chip(desc); |
144 | int offset; |
145 | unsigned long stat; |
146 | |
147 | chained_irq_enter(chip: irqchip, desc); |
148 | |
149 | stat = readl(addr: g->base + GPIO_INT_STAT_RAW); |
150 | if (stat) |
151 | for_each_set_bit(offset, &stat, gc->ngpio) |
152 | generic_handle_domain_irq(domain: gc->irq.domain, hwirq: offset); |
153 | |
154 | chained_irq_exit(chip: irqchip, desc); |
155 | } |
156 | |
157 | static int ftgpio_gpio_set_config(struct gpio_chip *gc, unsigned int offset, |
158 | unsigned long config) |
159 | { |
160 | enum pin_config_param param = pinconf_to_config_param(config); |
161 | u32 arg = pinconf_to_config_argument(config); |
162 | struct ftgpio_gpio *g = gpiochip_get_data(gc); |
163 | unsigned long pclk_freq; |
164 | u32 deb_div; |
165 | u32 val; |
166 | |
167 | if (param != PIN_CONFIG_INPUT_DEBOUNCE) |
168 | return -ENOTSUPP; |
169 | |
170 | /* |
171 | * Debounce only works if interrupts are enabled. The manual |
172 | * states that if PCLK is 66 MHz, and this is set to 0x7D0, then |
173 | * PCLK is divided down to 33 kHz for the debounce timer. 0x7D0 is |
174 | * 2000 decimal, so what they mean is simply that the PCLK is |
175 | * divided by this value. |
176 | * |
177 | * As we get a debounce setting in microseconds, we calculate the |
178 | * desired period time and see if we can get a suitable debounce |
179 | * time. |
180 | */ |
181 | pclk_freq = clk_get_rate(clk: g->clk); |
182 | deb_div = DIV_ROUND_CLOSEST(pclk_freq, arg); |
183 | |
184 | /* This register is only 24 bits wide */ |
185 | if (deb_div > (1 << 24)) |
186 | return -ENOTSUPP; |
187 | |
188 | dev_dbg(g->dev, "prescale divisor: %08x, resulting frequency %lu Hz\n" , |
189 | deb_div, (pclk_freq/deb_div)); |
190 | |
191 | val = readl(addr: g->base + GPIO_DEBOUNCE_PRESCALE); |
192 | if (val == deb_div) { |
193 | /* |
194 | * The debounce timer happens to already be set to the |
195 | * desirable value, what a coincidence! We can just enable |
196 | * debounce on this GPIO line and return. This happens more |
197 | * often than you think, for example when all GPIO keys |
198 | * on a system are requesting the same debounce interval. |
199 | */ |
200 | val = readl(addr: g->base + GPIO_DEBOUNCE_EN); |
201 | val |= BIT(offset); |
202 | writel(val, addr: g->base + GPIO_DEBOUNCE_EN); |
203 | return 0; |
204 | } |
205 | |
206 | val = readl(addr: g->base + GPIO_DEBOUNCE_EN); |
207 | if (val) { |
208 | /* |
209 | * Oh no! Someone is already using the debounce with |
210 | * another setting than what we need. Bummer. |
211 | */ |
212 | return -ENOTSUPP; |
213 | } |
214 | |
215 | /* First come, first serve */ |
216 | writel(val: deb_div, addr: g->base + GPIO_DEBOUNCE_PRESCALE); |
217 | /* Enable debounce */ |
218 | val |= BIT(offset); |
219 | writel(val, addr: g->base + GPIO_DEBOUNCE_EN); |
220 | |
221 | return 0; |
222 | } |
223 | |
224 | static const struct irq_chip ftgpio_irq_chip = { |
225 | .name = "FTGPIO010" , |
226 | .irq_ack = ftgpio_gpio_ack_irq, |
227 | .irq_mask = ftgpio_gpio_mask_irq, |
228 | .irq_unmask = ftgpio_gpio_unmask_irq, |
229 | .irq_set_type = ftgpio_gpio_set_irq_type, |
230 | .flags = IRQCHIP_IMMUTABLE, |
231 | GPIOCHIP_IRQ_RESOURCE_HELPERS, |
232 | }; |
233 | |
234 | static int ftgpio_gpio_probe(struct platform_device *pdev) |
235 | { |
236 | struct device *dev = &pdev->dev; |
237 | struct ftgpio_gpio *g; |
238 | struct gpio_irq_chip *girq; |
239 | int irq; |
240 | int ret; |
241 | |
242 | g = devm_kzalloc(dev, size: sizeof(*g), GFP_KERNEL); |
243 | if (!g) |
244 | return -ENOMEM; |
245 | |
246 | g->dev = dev; |
247 | |
248 | g->base = devm_platform_ioremap_resource(pdev, index: 0); |
249 | if (IS_ERR(ptr: g->base)) |
250 | return PTR_ERR(ptr: g->base); |
251 | |
252 | irq = platform_get_irq(pdev, 0); |
253 | if (irq < 0) |
254 | return irq; |
255 | |
256 | g->clk = devm_clk_get(dev, NULL); |
257 | if (!IS_ERR(ptr: g->clk)) { |
258 | ret = clk_prepare_enable(clk: g->clk); |
259 | if (ret) |
260 | return ret; |
261 | } else if (PTR_ERR(ptr: g->clk) == -EPROBE_DEFER) { |
262 | /* |
263 | * Percolate deferrals, for anything else, |
264 | * just live without the clocking. |
265 | */ |
266 | return PTR_ERR(ptr: g->clk); |
267 | } |
268 | |
269 | ret = bgpio_init(gc: &g->gc, dev, sz: 4, |
270 | dat: g->base + GPIO_DATA_IN, |
271 | set: g->base + GPIO_DATA_SET, |
272 | clr: g->base + GPIO_DATA_CLR, |
273 | dirout: g->base + GPIO_DIR, |
274 | NULL, |
275 | flags: 0); |
276 | if (ret) { |
277 | dev_err(dev, "unable to init generic GPIO\n" ); |
278 | goto dis_clk; |
279 | } |
280 | g->gc.label = dev_name(dev); |
281 | g->gc.base = -1; |
282 | g->gc.parent = dev; |
283 | g->gc.owner = THIS_MODULE; |
284 | /* ngpio is set by bgpio_init() */ |
285 | |
286 | /* We need a silicon clock to do debounce */ |
287 | if (!IS_ERR(ptr: g->clk)) |
288 | g->gc.set_config = ftgpio_gpio_set_config; |
289 | |
290 | girq = &g->gc.irq; |
291 | gpio_irq_chip_set_chip(girq, chip: &ftgpio_irq_chip); |
292 | girq->parent_handler = ftgpio_gpio_irq_handler; |
293 | girq->num_parents = 1; |
294 | girq->parents = devm_kcalloc(dev, n: 1, size: sizeof(*girq->parents), |
295 | GFP_KERNEL); |
296 | if (!girq->parents) { |
297 | ret = -ENOMEM; |
298 | goto dis_clk; |
299 | } |
300 | girq->default_type = IRQ_TYPE_NONE; |
301 | girq->handler = handle_bad_irq; |
302 | girq->parents[0] = irq; |
303 | |
304 | /* Disable, unmask and clear all interrupts */ |
305 | writel(val: 0x0, addr: g->base + GPIO_INT_EN); |
306 | writel(val: 0x0, addr: g->base + GPIO_INT_MASK); |
307 | writel(val: ~0x0, addr: g->base + GPIO_INT_CLR); |
308 | |
309 | /* Clear any use of debounce */ |
310 | writel(val: 0x0, addr: g->base + GPIO_DEBOUNCE_EN); |
311 | |
312 | ret = devm_gpiochip_add_data(dev, &g->gc, g); |
313 | if (ret) |
314 | goto dis_clk; |
315 | |
316 | platform_set_drvdata(pdev, data: g); |
317 | dev_info(dev, "FTGPIO010 @%p registered\n" , g->base); |
318 | |
319 | return 0; |
320 | |
321 | dis_clk: |
322 | clk_disable_unprepare(clk: g->clk); |
323 | |
324 | return ret; |
325 | } |
326 | |
327 | static void ftgpio_gpio_remove(struct platform_device *pdev) |
328 | { |
329 | struct ftgpio_gpio *g = platform_get_drvdata(pdev); |
330 | |
331 | clk_disable_unprepare(clk: g->clk); |
332 | } |
333 | |
334 | static const struct of_device_id ftgpio_gpio_of_match[] = { |
335 | { |
336 | .compatible = "cortina,gemini-gpio" , |
337 | }, |
338 | { |
339 | .compatible = "moxa,moxart-gpio" , |
340 | }, |
341 | { |
342 | .compatible = "faraday,ftgpio010" , |
343 | }, |
344 | {}, |
345 | }; |
346 | |
347 | static struct platform_driver ftgpio_gpio_driver = { |
348 | .driver = { |
349 | .name = "ftgpio010-gpio" , |
350 | .of_match_table = ftgpio_gpio_of_match, |
351 | }, |
352 | .probe = ftgpio_gpio_probe, |
353 | .remove_new = ftgpio_gpio_remove, |
354 | }; |
355 | builtin_platform_driver(ftgpio_gpio_driver); |
356 | |