1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * RDA Micro GPIO driver |
4 | * |
5 | * Copyright (C) 2012 RDA Micro Inc. |
6 | * Copyright (C) 2019 Manivannan Sadhasivam |
7 | */ |
8 | |
9 | #include <linux/bitops.h> |
10 | #include <linux/gpio/driver.h> |
11 | #include <linux/kernel.h> |
12 | #include <linux/module.h> |
13 | #include <linux/platform_device.h> |
14 | #include <linux/spinlock.h> |
15 | |
16 | #define RDA_GPIO_OEN_VAL 0x00 |
17 | #define RDA_GPIO_OEN_SET_OUT 0x04 |
18 | #define RDA_GPIO_OEN_SET_IN 0x08 |
19 | #define RDA_GPIO_VAL 0x0c |
20 | #define RDA_GPIO_SET 0x10 |
21 | #define RDA_GPIO_CLR 0x14 |
22 | #define RDA_GPIO_INT_CTRL_SET 0x18 |
23 | #define RDA_GPIO_INT_CTRL_CLR 0x1c |
24 | #define RDA_GPIO_INT_CLR 0x20 |
25 | #define RDA_GPIO_INT_STATUS 0x24 |
26 | |
27 | #define RDA_GPIO_IRQ_RISE_SHIFT 0 |
28 | #define RDA_GPIO_IRQ_FALL_SHIFT 8 |
29 | #define RDA_GPIO_DEBOUCE_SHIFT 16 |
30 | #define RDA_GPIO_LEVEL_SHIFT 24 |
31 | |
32 | #define RDA_GPIO_IRQ_MASK 0xff |
33 | |
34 | /* Each bank consists of 32 GPIOs */ |
35 | #define RDA_GPIO_BANK_NR 32 |
36 | |
37 | struct rda_gpio { |
38 | struct gpio_chip chip; |
39 | void __iomem *base; |
40 | spinlock_t lock; |
41 | int irq; |
42 | }; |
43 | |
44 | static inline void rda_gpio_update(struct gpio_chip *chip, unsigned int offset, |
45 | u16 reg, int val) |
46 | { |
47 | struct rda_gpio *rda_gpio = gpiochip_get_data(gc: chip); |
48 | void __iomem *base = rda_gpio->base; |
49 | unsigned long flags; |
50 | u32 tmp; |
51 | |
52 | spin_lock_irqsave(&rda_gpio->lock, flags); |
53 | tmp = readl_relaxed(base + reg); |
54 | |
55 | if (val) |
56 | tmp |= BIT(offset); |
57 | else |
58 | tmp &= ~BIT(offset); |
59 | |
60 | writel_relaxed(tmp, base + reg); |
61 | spin_unlock_irqrestore(lock: &rda_gpio->lock, flags); |
62 | } |
63 | |
64 | static void rda_gpio_irq_mask(struct irq_data *data) |
65 | { |
66 | struct gpio_chip *chip = irq_data_get_irq_chip_data(d: data); |
67 | struct rda_gpio *rda_gpio = gpiochip_get_data(gc: chip); |
68 | void __iomem *base = rda_gpio->base; |
69 | u32 offset = irqd_to_hwirq(d: data); |
70 | u32 value; |
71 | |
72 | value = BIT(offset) << RDA_GPIO_IRQ_RISE_SHIFT; |
73 | value |= BIT(offset) << RDA_GPIO_IRQ_FALL_SHIFT; |
74 | |
75 | writel_relaxed(value, base + RDA_GPIO_INT_CTRL_CLR); |
76 | gpiochip_disable_irq(gc: chip, offset); |
77 | } |
78 | |
79 | static void rda_gpio_irq_ack(struct irq_data *data) |
80 | { |
81 | struct gpio_chip *chip = irq_data_get_irq_chip_data(d: data); |
82 | u32 offset = irqd_to_hwirq(d: data); |
83 | |
84 | rda_gpio_update(chip, offset, RDA_GPIO_INT_CLR, val: 1); |
85 | } |
86 | |
87 | static int rda_gpio_set_irq(struct gpio_chip *chip, u32 offset, |
88 | unsigned int flow_type) |
89 | { |
90 | struct rda_gpio *rda_gpio = gpiochip_get_data(gc: chip); |
91 | void __iomem *base = rda_gpio->base; |
92 | u32 value; |
93 | |
94 | switch (flow_type) { |
95 | case IRQ_TYPE_EDGE_RISING: |
96 | /* Set rising edge trigger */ |
97 | value = BIT(offset) << RDA_GPIO_IRQ_RISE_SHIFT; |
98 | writel_relaxed(value, base + RDA_GPIO_INT_CTRL_SET); |
99 | |
100 | /* Switch to edge trigger interrupt */ |
101 | value = BIT(offset) << RDA_GPIO_LEVEL_SHIFT; |
102 | writel_relaxed(value, base + RDA_GPIO_INT_CTRL_CLR); |
103 | break; |
104 | |
105 | case IRQ_TYPE_EDGE_FALLING: |
106 | /* Set falling edge trigger */ |
107 | value = BIT(offset) << RDA_GPIO_IRQ_FALL_SHIFT; |
108 | writel_relaxed(value, base + RDA_GPIO_INT_CTRL_SET); |
109 | |
110 | /* Switch to edge trigger interrupt */ |
111 | value = BIT(offset) << RDA_GPIO_LEVEL_SHIFT; |
112 | writel_relaxed(value, base + RDA_GPIO_INT_CTRL_CLR); |
113 | break; |
114 | |
115 | case IRQ_TYPE_EDGE_BOTH: |
116 | /* Set both edge trigger */ |
117 | value = BIT(offset) << RDA_GPIO_IRQ_RISE_SHIFT; |
118 | value |= BIT(offset) << RDA_GPIO_IRQ_FALL_SHIFT; |
119 | writel_relaxed(value, base + RDA_GPIO_INT_CTRL_SET); |
120 | |
121 | /* Switch to edge trigger interrupt */ |
122 | value = BIT(offset) << RDA_GPIO_LEVEL_SHIFT; |
123 | writel_relaxed(value, base + RDA_GPIO_INT_CTRL_CLR); |
124 | break; |
125 | |
126 | case IRQ_TYPE_LEVEL_HIGH: |
127 | /* Set high level trigger */ |
128 | value = BIT(offset) << RDA_GPIO_IRQ_RISE_SHIFT; |
129 | |
130 | /* Switch to level trigger interrupt */ |
131 | value |= BIT(offset) << RDA_GPIO_LEVEL_SHIFT; |
132 | writel_relaxed(value, base + RDA_GPIO_INT_CTRL_SET); |
133 | break; |
134 | |
135 | case IRQ_TYPE_LEVEL_LOW: |
136 | /* Set low level trigger */ |
137 | value = BIT(offset) << RDA_GPIO_IRQ_FALL_SHIFT; |
138 | |
139 | /* Switch to level trigger interrupt */ |
140 | value |= BIT(offset) << RDA_GPIO_LEVEL_SHIFT; |
141 | writel_relaxed(value, base + RDA_GPIO_INT_CTRL_SET); |
142 | break; |
143 | |
144 | default: |
145 | return -EINVAL; |
146 | } |
147 | |
148 | return 0; |
149 | } |
150 | |
151 | static void rda_gpio_irq_unmask(struct irq_data *data) |
152 | { |
153 | struct gpio_chip *chip = irq_data_get_irq_chip_data(d: data); |
154 | u32 offset = irqd_to_hwirq(d: data); |
155 | u32 trigger = irqd_get_trigger_type(d: data); |
156 | |
157 | gpiochip_enable_irq(gc: chip, offset); |
158 | rda_gpio_set_irq(chip, offset, flow_type: trigger); |
159 | } |
160 | |
161 | static int rda_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type) |
162 | { |
163 | struct gpio_chip *chip = irq_data_get_irq_chip_data(d: data); |
164 | u32 offset = irqd_to_hwirq(d: data); |
165 | int ret; |
166 | |
167 | ret = rda_gpio_set_irq(chip, offset, flow_type); |
168 | if (ret) |
169 | return ret; |
170 | |
171 | if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) |
172 | irq_set_handler_locked(data, handler: handle_level_irq); |
173 | else if (flow_type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) |
174 | irq_set_handler_locked(data, handler: handle_edge_irq); |
175 | |
176 | return 0; |
177 | } |
178 | |
179 | static void rda_gpio_irq_handler(struct irq_desc *desc) |
180 | { |
181 | struct gpio_chip *chip = irq_desc_get_handler_data(desc); |
182 | struct irq_chip *ic = irq_desc_get_chip(desc); |
183 | struct rda_gpio *rda_gpio = gpiochip_get_data(gc: chip); |
184 | unsigned long status; |
185 | u32 n; |
186 | |
187 | chained_irq_enter(chip: ic, desc); |
188 | |
189 | status = readl_relaxed(rda_gpio->base + RDA_GPIO_INT_STATUS); |
190 | /* Only lower 8 bits are capable of generating interrupts */ |
191 | status &= RDA_GPIO_IRQ_MASK; |
192 | |
193 | for_each_set_bit(n, &status, RDA_GPIO_BANK_NR) |
194 | generic_handle_domain_irq(domain: chip->irq.domain, hwirq: n); |
195 | |
196 | chained_irq_exit(chip: ic, desc); |
197 | } |
198 | |
199 | static const struct irq_chip rda_gpio_irq_chip = { |
200 | .name = "rda-gpio" , |
201 | .irq_ack = rda_gpio_irq_ack, |
202 | .irq_mask = rda_gpio_irq_mask, |
203 | .irq_unmask = rda_gpio_irq_unmask, |
204 | .irq_set_type = rda_gpio_irq_set_type, |
205 | .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE, |
206 | GPIOCHIP_IRQ_RESOURCE_HELPERS, |
207 | }; |
208 | |
209 | static int rda_gpio_probe(struct platform_device *pdev) |
210 | { |
211 | struct device *dev = &pdev->dev; |
212 | struct gpio_irq_chip *girq; |
213 | struct rda_gpio *rda_gpio; |
214 | u32 ngpios; |
215 | int ret; |
216 | |
217 | rda_gpio = devm_kzalloc(dev, size: sizeof(*rda_gpio), GFP_KERNEL); |
218 | if (!rda_gpio) |
219 | return -ENOMEM; |
220 | |
221 | ret = device_property_read_u32(dev, propname: "ngpios" , val: &ngpios); |
222 | if (ret < 0) |
223 | return ret; |
224 | |
225 | /* |
226 | * Not all ports have interrupt capability. For instance, on |
227 | * RDA8810PL, GPIOC doesn't support interrupt. So we must handle |
228 | * those also. |
229 | */ |
230 | rda_gpio->irq = platform_get_irq(pdev, 0); |
231 | |
232 | rda_gpio->base = devm_platform_ioremap_resource(pdev, index: 0); |
233 | if (IS_ERR(ptr: rda_gpio->base)) |
234 | return PTR_ERR(ptr: rda_gpio->base); |
235 | |
236 | spin_lock_init(&rda_gpio->lock); |
237 | |
238 | ret = bgpio_init(gc: &rda_gpio->chip, dev, sz: 4, |
239 | dat: rda_gpio->base + RDA_GPIO_VAL, |
240 | set: rda_gpio->base + RDA_GPIO_SET, |
241 | clr: rda_gpio->base + RDA_GPIO_CLR, |
242 | dirout: rda_gpio->base + RDA_GPIO_OEN_SET_OUT, |
243 | dirin: rda_gpio->base + RDA_GPIO_OEN_SET_IN, |
244 | BGPIOF_READ_OUTPUT_REG_SET); |
245 | if (ret) { |
246 | dev_err(dev, "bgpio_init failed\n" ); |
247 | return ret; |
248 | } |
249 | |
250 | rda_gpio->chip.label = dev_name(dev); |
251 | rda_gpio->chip.ngpio = ngpios; |
252 | rda_gpio->chip.base = -1; |
253 | |
254 | if (rda_gpio->irq >= 0) { |
255 | girq = &rda_gpio->chip.irq; |
256 | gpio_irq_chip_set_chip(girq, chip: &rda_gpio_irq_chip); |
257 | girq->handler = handle_bad_irq; |
258 | girq->default_type = IRQ_TYPE_NONE; |
259 | girq->parent_handler = rda_gpio_irq_handler; |
260 | girq->parent_handler_data = rda_gpio; |
261 | girq->num_parents = 1; |
262 | girq->parents = devm_kcalloc(dev, n: 1, |
263 | size: sizeof(*girq->parents), |
264 | GFP_KERNEL); |
265 | if (!girq->parents) |
266 | return -ENOMEM; |
267 | girq->parents[0] = rda_gpio->irq; |
268 | } |
269 | |
270 | platform_set_drvdata(pdev, data: rda_gpio); |
271 | |
272 | return devm_gpiochip_add_data(dev, &rda_gpio->chip, rda_gpio); |
273 | } |
274 | |
275 | static const struct of_device_id rda_gpio_of_match[] = { |
276 | { .compatible = "rda,8810pl-gpio" , }, |
277 | { /* sentinel */ } |
278 | }; |
279 | MODULE_DEVICE_TABLE(of, rda_gpio_of_match); |
280 | |
281 | static struct platform_driver rda_gpio_driver = { |
282 | .probe = rda_gpio_probe, |
283 | .driver = { |
284 | .name = "rda-gpio" , |
285 | .of_match_table = rda_gpio_of_match, |
286 | }, |
287 | }; |
288 | |
289 | module_platform_driver_probe(rda_gpio_driver, rda_gpio_probe); |
290 | |
291 | MODULE_DESCRIPTION("RDA Micro GPIO driver" ); |
292 | MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>" ); |
293 | |