• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/of_gpio.h>
12 #include <linux/io.h>
13 #include <linux/of_platform.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 int 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 	return 0;
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 void
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 
mpc52xx_simple_gpio_dir_in(struct gpio_chip * gc,unsigned int gpio)247 static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
248 {
249 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
250 	struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
251 	struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
252 	unsigned long flags;
253 
254 	spin_lock_irqsave(&gpio_lock, flags);
255 
256 	/* set the direction */
257 	chip->shadow_ddr &= ~(1 << (31 - gpio));
258 	out_be32(&regs->simple_ddr, chip->shadow_ddr);
259 
260 	/* and enable the pin */
261 	chip->shadow_gpioe |= 1 << (31 - gpio);
262 	out_be32(&regs->simple_gpioe, chip->shadow_gpioe);
263 
264 	spin_unlock_irqrestore(&gpio_lock, flags);
265 
266 	return 0;
267 }
268 
269 static int
mpc52xx_simple_gpio_dir_out(struct gpio_chip * gc,unsigned int gpio,int val)270 mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
271 {
272 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
273 	struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc);
274 	struct mpc52xx_gpio __iomem *regs = mm_gc->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 mpc52xx_gpiochip *chip;
300 	struct gpio_chip *gc;
301 	struct mpc52xx_gpio __iomem *regs;
302 	int ret;
303 
304 	chip = devm_kzalloc(&ofdev->dev, sizeof(*chip), GFP_KERNEL);
305 	if (!chip)
306 		return -ENOMEM;
307 
308 	platform_set_drvdata(ofdev, chip);
309 
310 	gc = &chip->mmchip.gc;
311 
312 	gc->ngpio            = 32;
313 	gc->direction_input  = mpc52xx_simple_gpio_dir_in;
314 	gc->direction_output = mpc52xx_simple_gpio_dir_out;
315 	gc->get              = mpc52xx_simple_gpio_get;
316 	gc->set              = mpc52xx_simple_gpio_set;
317 
318 	ret = of_mm_gpiochip_add_data(ofdev->dev.of_node, &chip->mmchip, chip);
319 	if (ret)
320 		return ret;
321 
322 	regs = chip->mmchip.regs;
323 	chip->shadow_gpioe = in_be32(&regs->simple_gpioe);
324 	chip->shadow_ddr = in_be32(&regs->simple_ddr);
325 	chip->shadow_dvo = in_be32(&regs->simple_dvo);
326 
327 	return 0;
328 }
329 
330 static const struct of_device_id mpc52xx_simple_gpiochip_match[] = {
331 	{ .compatible = "fsl,mpc5200-gpio", },
332 	{}
333 };
334 
335 static struct platform_driver mpc52xx_simple_gpiochip_driver = {
336 	.driver = {
337 		.name = "mpc5200-gpio",
338 		.of_match_table = mpc52xx_simple_gpiochip_match,
339 	},
340 	.probe = mpc52xx_simple_gpiochip_probe,
341 	.remove = mpc52xx_gpiochip_remove,
342 };
343 
344 static struct platform_driver * const drivers[] = {
345 	&mpc52xx_wkup_gpiochip_driver,
346 	&mpc52xx_simple_gpiochip_driver,
347 };
348 
mpc52xx_gpio_init(void)349 static int __init mpc52xx_gpio_init(void)
350 {
351 	return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
352 }
353 
354 /* Make sure we get initialised before anyone else tries to use us */
355 subsys_initcall(mpc52xx_gpio_init);
356 
mpc52xx_gpio_exit(void)357 static void __exit mpc52xx_gpio_exit(void)
358 {
359 	platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
360 }
361 module_exit(mpc52xx_gpio_exit);
362 
363 MODULE_DESCRIPTION("Freescale MPC52xx gpio driver");
364 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
365 MODULE_LICENSE("GPL v2");
366 
367