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