1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * MPC52xx gpio driver
4  *
5  * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
6  */
7 
8 #include <linux/of.h>
9 #include <linux/kernel.h>
10 #include <linux/slab.h>
11 #include <linux/gpio/legacy-of-mm-gpiochip.h>
12 #include <linux/io.h>
13 #include <linux/platform_device.h>
14 #include <linux/module.h>
15 
16 #include <asm/mpc52xx.h>
17 #include <sysdev/fsl_soc.h>
18 
19 static DEFINE_SPINLOCK(gpio_lock);
20 
21 struct mpc52xx_gpiochip {
22 	struct of_mm_gpio_chip mmchip;
23 	unsigned int shadow_dvo;
24 	unsigned int shadow_gpioe;
25 	unsigned int shadow_ddr;
26 };
27 
28 /*
29  * GPIO LIB API implementation for wakeup GPIOs.
30  *
31  * There's a maximum of 8 wakeup GPIOs. Which of these are available
32  * for use depends on your board setup.
33  *
34  * 0 -> GPIO_WKUP_7
35  * 1 -> GPIO_WKUP_6
36  * 2 -> PSC6_1
37  * 3 -> PSC6_0
38  * 4 -> ETH_17
39  * 5 -> PSC3_9
40  * 6 -> PSC2_4
41  * 7 -> PSC1_4
42  *
43  */
mpc52xx_wkup_gpio_get(struct gpio_chip * gc,unsigned int gpio)44 static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio)
45 {
46 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
47 	struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
48 	unsigned int ret;
49 
50 	ret = (in_8(&regs->wkup_ival) >> (7 - gpio)) & 1;
51 
52 	pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret);
53 
54 	return ret;
55 }
56 
57 static inline void
__mpc52xx_wkup_gpio_set(struct gpio_chip * gc,unsigned int gpio,int val)58 __mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
59 {
60 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
61 	struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
62 	struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
63 
64 	if (val)
65 		chip->shadow_dvo |= 1 << (7 - gpio);
66 	else
67 		chip->shadow_dvo &= ~(1 << (7 - gpio));
68 
69 	out_8(&regs->wkup_dvo, chip->shadow_dvo);
70 }
71 
72 static void
mpc52xx_wkup_gpio_set(struct gpio_chip * gc,unsigned int gpio,int val)73 mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
74 {
75 	unsigned long flags;
76 
77 	spin_lock_irqsave(&gpio_lock, flags);
78 
79 	__mpc52xx_wkup_gpio_set(gc, gpio, val);
80 
81 	spin_unlock_irqrestore(&gpio_lock, flags);
82 
83 	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
84 }
85 
mpc52xx_wkup_gpio_dir_in(struct gpio_chip * gc,unsigned int gpio)86 static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
87 {
88 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
89 	struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
90 	struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
91 	unsigned long flags;
92 
93 	spin_lock_irqsave(&gpio_lock, flags);
94 
95 	/* set the direction */
96 	chip->shadow_ddr &= ~(1 << (7 - gpio));
97 	out_8(&regs->wkup_ddr, chip->shadow_ddr);
98 
99 	/* and enable the pin */
100 	chip->shadow_gpioe |= 1 << (7 - gpio);
101 	out_8(&regs->wkup_gpioe, chip->shadow_gpioe);
102 
103 	spin_unlock_irqrestore(&gpio_lock, flags);
104 
105 	return 0;
106 }
107 
108 static int
mpc52xx_wkup_gpio_dir_out(struct gpio_chip * gc,unsigned int gpio,int val)109 mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
110 {
111 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
112 	struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
113 	struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
114 	unsigned long flags;
115 
116 	spin_lock_irqsave(&gpio_lock, flags);
117 
118 	__mpc52xx_wkup_gpio_set(gc, gpio, val);
119 
120 	/* Then set direction */
121 	chip->shadow_ddr |= 1 << (7 - gpio);
122 	out_8(&regs->wkup_ddr, chip->shadow_ddr);
123 
124 	/* Finally enable the pin */
125 	chip->shadow_gpioe |= 1 << (7 - gpio);
126 	out_8(&regs->wkup_gpioe, chip->shadow_gpioe);
127 
128 	spin_unlock_irqrestore(&gpio_lock, flags);
129 
130 	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
131 
132 	return 0;
133 }
134 
mpc52xx_wkup_gpiochip_probe(struct platform_device * ofdev)135 static int mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev)
136 {
137 	struct mpc52xx_gpiochip *chip;
138 	struct mpc52xx_gpio_wkup __iomem *regs;
139 	struct gpio_chip *gc;
140 	int ret;
141 
142 	chip = devm_kzalloc(&ofdev->dev, sizeof(*chip), GFP_KERNEL);
143 	if (!chip)
144 		return -ENOMEM;
145 
146 	platform_set_drvdata(ofdev, chip);
147 
148 	gc = &chip->mmchip.gc;
149 
150 	gc->ngpio            = 8;
151 	gc->direction_input  = mpc52xx_wkup_gpio_dir_in;
152 	gc->direction_output = mpc52xx_wkup_gpio_dir_out;
153 	gc->get              = mpc52xx_wkup_gpio_get;
154 	gc->set              = mpc52xx_wkup_gpio_set;
155 
156 	ret = of_mm_gpiochip_add_data(ofdev->dev.of_node, &chip->mmchip, chip);
157 	if (ret)
158 		return ret;
159 
160 	regs = chip->mmchip.regs;
161 	chip->shadow_gpioe = in_8(&regs->wkup_gpioe);
162 	chip->shadow_ddr = in_8(&regs->wkup_ddr);
163 	chip->shadow_dvo = in_8(&regs->wkup_dvo);
164 
165 	return 0;
166 }
167 
mpc52xx_gpiochip_remove(struct platform_device * ofdev)168 static void mpc52xx_gpiochip_remove(struct platform_device *ofdev)
169 {
170 	struct mpc52xx_gpiochip *chip = platform_get_drvdata(ofdev);
171 
172 	of_mm_gpiochip_remove(&chip->mmchip);
173 }
174 
175 static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = {
176 	{ .compatible = "fsl,mpc5200-gpio-wkup", },
177 	{}
178 };
179 
180 static struct platform_driver mpc52xx_wkup_gpiochip_driver = {
181 	.driver = {
182 		.name = "mpc5200-gpio-wkup",
183 		.of_match_table = mpc52xx_wkup_gpiochip_match,
184 	},
185 	.probe = mpc52xx_wkup_gpiochip_probe,
186 	.remove_new = mpc52xx_gpiochip_remove,
187 };
188 
189 /*
190  * GPIO LIB API implementation for simple GPIOs
191  *
192  * There's a maximum of 32 simple GPIOs. Which of these are available
193  * for use depends on your board setup.
194  * The numbering reflects the bit numbering in the port registers:
195  *
196  *  0..1  > reserved
197  *  2..3  > IRDA
198  *  4..7  > ETHR
199  *  8..11 > reserved
200  * 12..15 > USB
201  * 16..17 > reserved
202  * 18..23 > PSC3
203  * 24..27 > PSC2
204  * 28..31 > PSC1
205  */
mpc52xx_simple_gpio_get(struct gpio_chip * gc,unsigned int gpio)206 static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio)
207 {
208 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
209 	struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
210 	unsigned int ret;
211 
212 	ret = (in_be32(&regs->simple_ival) >> (31 - gpio)) & 1;
213 
214 	return ret;
215 }
216 
217 static inline void
__mpc52xx_simple_gpio_set(struct gpio_chip * gc,unsigned int gpio,int val)218 __mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
219 {
220 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
221 	struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
222 	struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
223 
224 	if (val)
225 		chip->shadow_dvo |= 1 << (31 - gpio);
226 	else
227 		chip->shadow_dvo &= ~(1 << (31 - gpio));
228 	out_be32(&regs->simple_dvo, chip->shadow_dvo);
229 }
230 
231 static void
mpc52xx_simple_gpio_set(struct gpio_chip * gc,unsigned int gpio,int val)232 mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
233 {
234 	unsigned long flags;
235 
236 	spin_lock_irqsave(&gpio_lock, flags);
237 
238 	__mpc52xx_simple_gpio_set(gc, gpio, val);
239 
240 	spin_unlock_irqrestore(&gpio_lock, flags);
241 
242 	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
243 }
244 
mpc52xx_simple_gpio_dir_in(struct gpio_chip * gc,unsigned int gpio)245 static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
246 {
247 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
248 	struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
249 	struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
250 	unsigned long flags;
251 
252 	spin_lock_irqsave(&gpio_lock, flags);
253 
254 	/* set the direction */
255 	chip->shadow_ddr &= ~(1 << (31 - gpio));
256 	out_be32(&regs->simple_ddr, chip->shadow_ddr);
257 
258 	/* and enable the pin */
259 	chip->shadow_gpioe |= 1 << (31 - gpio);
260 	out_be32(&regs->simple_gpioe, chip->shadow_gpioe);
261 
262 	spin_unlock_irqrestore(&gpio_lock, flags);
263 
264 	return 0;
265 }
266 
267 static int
mpc52xx_simple_gpio_dir_out(struct gpio_chip * gc,unsigned int gpio,int val)268 mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
269 {
270 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
271 	struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
272 	struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
273 	unsigned long flags;
274 
275 	spin_lock_irqsave(&gpio_lock, flags);
276 
277 	/* First set initial value */
278 	__mpc52xx_simple_gpio_set(gc, gpio, val);
279 
280 	/* Then set direction */
281 	chip->shadow_ddr |= 1 << (31 - gpio);
282 	out_be32(&regs->simple_ddr, chip->shadow_ddr);
283 
284 	/* Finally enable the pin */
285 	chip->shadow_gpioe |= 1 << (31 - gpio);
286 	out_be32(&regs->simple_gpioe, chip->shadow_gpioe);
287 
288 	spin_unlock_irqrestore(&gpio_lock, flags);
289 
290 	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
291 
292 	return 0;
293 }
294 
mpc52xx_simple_gpiochip_probe(struct platform_device * ofdev)295 static int mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev)
296 {
297 	struct mpc52xx_gpiochip *chip;
298 	struct gpio_chip *gc;
299 	struct mpc52xx_gpio __iomem *regs;
300 	int ret;
301 
302 	chip = devm_kzalloc(&ofdev->dev, sizeof(*chip), GFP_KERNEL);
303 	if (!chip)
304 		return -ENOMEM;
305 
306 	platform_set_drvdata(ofdev, chip);
307 
308 	gc = &chip->mmchip.gc;
309 
310 	gc->ngpio            = 32;
311 	gc->direction_input  = mpc52xx_simple_gpio_dir_in;
312 	gc->direction_output = mpc52xx_simple_gpio_dir_out;
313 	gc->get              = mpc52xx_simple_gpio_get;
314 	gc->set              = mpc52xx_simple_gpio_set;
315 
316 	ret = of_mm_gpiochip_add_data(ofdev->dev.of_node, &chip->mmchip, chip);
317 	if (ret)
318 		return ret;
319 
320 	regs = chip->mmchip.regs;
321 	chip->shadow_gpioe = in_be32(&regs->simple_gpioe);
322 	chip->shadow_ddr = in_be32(&regs->simple_ddr);
323 	chip->shadow_dvo = in_be32(&regs->simple_dvo);
324 
325 	return 0;
326 }
327 
328 static const struct of_device_id mpc52xx_simple_gpiochip_match[] = {
329 	{ .compatible = "fsl,mpc5200-gpio", },
330 	{}
331 };
332 
333 static struct platform_driver mpc52xx_simple_gpiochip_driver = {
334 	.driver = {
335 		.name = "mpc5200-gpio",
336 		.of_match_table = mpc52xx_simple_gpiochip_match,
337 	},
338 	.probe = mpc52xx_simple_gpiochip_probe,
339 	.remove_new = mpc52xx_gpiochip_remove,
340 };
341 
342 static struct platform_driver * const drivers[] = {
343 	&mpc52xx_wkup_gpiochip_driver,
344 	&mpc52xx_simple_gpiochip_driver,
345 };
346 
mpc52xx_gpio_init(void)347 static int __init mpc52xx_gpio_init(void)
348 {
349 	return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
350 }
351 
352 /* Make sure we get initialised before anyone else tries to use us */
353 subsys_initcall(mpc52xx_gpio_init);
354 
mpc52xx_gpio_exit(void)355 static void __exit mpc52xx_gpio_exit(void)
356 {
357 	platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
358 }
359 module_exit(mpc52xx_gpio_exit);
360 
361 MODULE_DESCRIPTION("Freescale MPC52xx gpio driver");
362 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
363 MODULE_LICENSE("GPL v2");
364 
365