xref: /linux/drivers/gpio/gpio-mpc5200.c (revision 417552999d0b6681ac30e117ae890828ca7e46b3)
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/driver.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 gpio_chip gc;
23 	void __iomem *regs;
24 	unsigned int shadow_dvo;
25 	unsigned int shadow_gpioe;
26 	unsigned int shadow_ddr;
27 };
28 
29 /*
30  * GPIO LIB API implementation for wakeup GPIOs.
31  *
32  * There's a maximum of 8 wakeup GPIOs. Which of these are available
33  * for use depends on your board setup.
34  *
35  * 0 -> GPIO_WKUP_7
36  * 1 -> GPIO_WKUP_6
37  * 2 -> PSC6_1
38  * 3 -> PSC6_0
39  * 4 -> ETH_17
40  * 5 -> PSC3_9
41  * 6 -> PSC2_4
42  * 7 -> PSC1_4
43  *
44  */
mpc52xx_wkup_gpio_get(struct gpio_chip * gc,unsigned int gpio)45 static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio)
46 {
47 	struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
48 	struct mpc52xx_gpio_wkup __iomem *regs = chip->regs;
49 	unsigned int ret;
50 
51 	ret = (in_8(&regs->wkup_ival) >> (7 - gpio)) & 1;
52 
53 	pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret);
54 
55 	return ret;
56 }
57 
58 static inline void
__mpc52xx_wkup_gpio_set(struct gpio_chip * gc,unsigned int gpio,int val)59 __mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
60 {
61 	struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
62 	struct mpc52xx_gpio_wkup __iomem *regs = chip->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 mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
91 	struct mpc52xx_gpio_wkup __iomem *regs = chip->regs;
92 	unsigned long flags;
93 
94 	spin_lock_irqsave(&gpio_lock, flags);
95 
96 	/* set the direction */
97 	chip->shadow_ddr &= ~(1 << (7 - gpio));
98 	out_8(&regs->wkup_ddr, chip->shadow_ddr);
99 
100 	/* and enable the pin */
101 	chip->shadow_gpioe |= 1 << (7 - gpio);
102 	out_8(&regs->wkup_gpioe, chip->shadow_gpioe);
103 
104 	spin_unlock_irqrestore(&gpio_lock, flags);
105 
106 	return 0;
107 }
108 
109 static int
mpc52xx_wkup_gpio_dir_out(struct gpio_chip * gc,unsigned int gpio,int val)110 mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
111 {
112 	struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
113 	struct mpc52xx_gpio_wkup __iomem *regs = chip->regs;
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 device *dev = &ofdev->dev;
138 	struct device_node *np = dev->of_node;
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(dev, sizeof(*chip), GFP_KERNEL);
145 	if (!chip)
146 		return -ENOMEM;
147 
148 	platform_set_drvdata(ofdev, chip);
149 
150 	gc = &chip->gc;
151 
152 	gc->base             = -1;
153 	gc->ngpio            = 8;
154 	gc->direction_input  = mpc52xx_wkup_gpio_dir_in;
155 	gc->direction_output = mpc52xx_wkup_gpio_dir_out;
156 	gc->get              = mpc52xx_wkup_gpio_get;
157 	gc->set              = mpc52xx_wkup_gpio_set;
158 
159 	gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np);
160 	if (!gc->label)
161 		return -ENOMEM;
162 
163 	chip->regs = devm_of_iomap(dev, np, 0, NULL);
164 	if (IS_ERR(chip->regs))
165 		return PTR_ERR(chip->regs);
166 
167 	ret = devm_gpiochip_add_data(dev, gc, chip);
168 	if (ret)
169 		return ret;
170 
171 	regs = chip->regs;
172 	chip->shadow_gpioe = in_8(&regs->wkup_gpioe);
173 	chip->shadow_ddr = in_8(&regs->wkup_ddr);
174 	chip->shadow_dvo = in_8(&regs->wkup_dvo);
175 
176 	return 0;
177 }
178 
179 static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = {
180 	{ .compatible = "fsl,mpc5200-gpio-wkup", },
181 	{}
182 };
183 
184 static struct platform_driver mpc52xx_wkup_gpiochip_driver = {
185 	.driver = {
186 		.name = "mpc5200-gpio-wkup",
187 		.of_match_table = mpc52xx_wkup_gpiochip_match,
188 	},
189 	.probe = mpc52xx_wkup_gpiochip_probe,
190 };
191 
192 /*
193  * GPIO LIB API implementation for simple GPIOs
194  *
195  * There's a maximum of 32 simple GPIOs. Which of these are available
196  * for use depends on your board setup.
197  * The numbering reflects the bit numbering in the port registers:
198  *
199  *  0..1  > reserved
200  *  2..3  > IRDA
201  *  4..7  > ETHR
202  *  8..11 > reserved
203  * 12..15 > USB
204  * 16..17 > reserved
205  * 18..23 > PSC3
206  * 24..27 > PSC2
207  * 28..31 > PSC1
208  */
mpc52xx_simple_gpio_get(struct gpio_chip * gc,unsigned int gpio)209 static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio)
210 {
211 	struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
212 	struct mpc52xx_gpio __iomem *regs = chip->regs;
213 	unsigned int ret;
214 
215 	ret = (in_be32(&regs->simple_ival) >> (31 - gpio)) & 1;
216 
217 	return ret;
218 }
219 
220 static inline void
__mpc52xx_simple_gpio_set(struct gpio_chip * gc,unsigned int gpio,int val)221 __mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
222 {
223 	struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
224 	struct mpc52xx_gpio __iomem *regs = chip->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 mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
252 	struct mpc52xx_gpio __iomem *regs = chip->regs;
253 	unsigned long flags;
254 
255 	spin_lock_irqsave(&gpio_lock, flags);
256 
257 	/* set the direction */
258 	chip->shadow_ddr &= ~(1 << (31 - gpio));
259 	out_be32(&regs->simple_ddr, chip->shadow_ddr);
260 
261 	/* and enable the pin */
262 	chip->shadow_gpioe |= 1 << (31 - gpio);
263 	out_be32(&regs->simple_gpioe, chip->shadow_gpioe);
264 
265 	spin_unlock_irqrestore(&gpio_lock, flags);
266 
267 	return 0;
268 }
269 
270 static int
mpc52xx_simple_gpio_dir_out(struct gpio_chip * gc,unsigned int gpio,int val)271 mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
272 {
273 	struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
274 	struct mpc52xx_gpio __iomem *regs = chip->regs;
275 	unsigned long flags;
276 
277 	spin_lock_irqsave(&gpio_lock, flags);
278 
279 	/* First set initial value */
280 	__mpc52xx_simple_gpio_set(gc, gpio, val);
281 
282 	/* Then set direction */
283 	chip->shadow_ddr |= 1 << (31 - gpio);
284 	out_be32(&regs->simple_ddr, chip->shadow_ddr);
285 
286 	/* Finally enable the pin */
287 	chip->shadow_gpioe |= 1 << (31 - gpio);
288 	out_be32(&regs->simple_gpioe, chip->shadow_gpioe);
289 
290 	spin_unlock_irqrestore(&gpio_lock, flags);
291 
292 	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
293 
294 	return 0;
295 }
296 
mpc52xx_simple_gpiochip_probe(struct platform_device * ofdev)297 static int mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev)
298 {
299 	struct device *dev = &ofdev->dev;
300 	struct device_node *np = dev->of_node;
301 	struct mpc52xx_gpiochip *chip;
302 	struct gpio_chip *gc;
303 	struct mpc52xx_gpio __iomem *regs;
304 	int ret;
305 
306 	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
307 	if (!chip)
308 		return -ENOMEM;
309 
310 	platform_set_drvdata(ofdev, chip);
311 
312 	gc = &chip->gc;
313 
314 	gc->base             = -1;
315 	gc->ngpio            = 32;
316 	gc->direction_input  = mpc52xx_simple_gpio_dir_in;
317 	gc->direction_output = mpc52xx_simple_gpio_dir_out;
318 	gc->get              = mpc52xx_simple_gpio_get;
319 	gc->set              = mpc52xx_simple_gpio_set;
320 
321 	gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np);
322 	if (!gc->label)
323 		return -ENOMEM;
324 
325 	chip->regs = devm_of_iomap(dev, np, 0, NULL);
326 	if (IS_ERR(chip->regs))
327 		return PTR_ERR(chip->regs);
328 
329 	ret = devm_gpiochip_add_data(dev, gc, chip);
330 	if (ret)
331 		return ret;
332 
333 	regs = chip->regs;
334 	chip->shadow_gpioe = in_be32(&regs->simple_gpioe);
335 	chip->shadow_ddr = in_be32(&regs->simple_ddr);
336 	chip->shadow_dvo = in_be32(&regs->simple_dvo);
337 
338 	return 0;
339 }
340 
341 static const struct of_device_id mpc52xx_simple_gpiochip_match[] = {
342 	{ .compatible = "fsl,mpc5200-gpio", },
343 	{}
344 };
345 
346 static struct platform_driver mpc52xx_simple_gpiochip_driver = {
347 	.driver = {
348 		.name = "mpc5200-gpio",
349 		.of_match_table = mpc52xx_simple_gpiochip_match,
350 	},
351 	.probe = mpc52xx_simple_gpiochip_probe,
352 };
353 
354 static struct platform_driver * const drivers[] = {
355 	&mpc52xx_wkup_gpiochip_driver,
356 	&mpc52xx_simple_gpiochip_driver,
357 };
358 
mpc52xx_gpio_init(void)359 static int __init mpc52xx_gpio_init(void)
360 {
361 	return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
362 }
363 
364 /* Make sure we get initialised before anyone else tries to use us */
365 subsys_initcall(mpc52xx_gpio_init);
366 
mpc52xx_gpio_exit(void)367 static void __exit mpc52xx_gpio_exit(void)
368 {
369 	platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
370 }
371 module_exit(mpc52xx_gpio_exit);
372 
373 MODULE_DESCRIPTION("Freescale MPC52xx gpio driver");
374 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
375 MODULE_LICENSE("GPL v2");
376 
377