xref: /linux/arch/arm/mach-s3c/gpio-samsung.c (revision 500af1defbcbb6113c9a958b791517d0562b8d6d)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
4 //		http://www.samsung.com/
5 //
6 // Copyright 2008 Openmoko, Inc.
7 // Copyright 2008 Simtec Electronics
8 //      Ben Dooks <ben@simtec.co.uk>
9 //      http://armlinux.simtec.co.uk/
10 //
11 // Samsung - GPIOlib support
12 
13 #include <linux/kernel.h>
14 #include <linux/gpio/driver.h>
15 #include <linux/irq.h>
16 #include <linux/io.h>
17 #include <linux/init.h>
18 #include <linux/spinlock.h>
19 #include <linux/module.h>
20 #include <linux/interrupt.h>
21 #include <linux/device.h>
22 #include <linux/ioport.h>
23 #include <linux/of.h>
24 #include <linux/slab.h>
25 #include <linux/of_address.h>
26 
27 #include <asm/irq.h>
28 
29 #include "irqs.h"
30 #include "map.h"
31 #include "regs-gpio.h"
32 #include "gpio-samsung.h"
33 
34 #include "cpu.h"
35 #include "gpio-core.h"
36 #include "gpio-cfg.h"
37 #include "gpio-cfg-helpers.h"
38 #include "pm.h"
39 
samsung_gpio_setpull_updown(struct samsung_gpio_chip * chip,unsigned int off,samsung_gpio_pull_t pull)40 static int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
41 				unsigned int off, samsung_gpio_pull_t pull)
42 {
43 	void __iomem *reg = chip->base + 0x08;
44 	int shift = off * 2;
45 	u32 pup;
46 
47 	pup = __raw_readl(reg);
48 	pup &= ~(3 << shift);
49 	pup |= pull << shift;
50 	__raw_writel(pup, reg);
51 
52 	return 0;
53 }
54 
samsung_gpio_getpull_updown(struct samsung_gpio_chip * chip,unsigned int off)55 static samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
56 						unsigned int off)
57 {
58 	void __iomem *reg = chip->base + 0x08;
59 	int shift = off * 2;
60 	u32 pup = __raw_readl(reg);
61 
62 	pup >>= shift;
63 	pup &= 0x3;
64 
65 	return (__force samsung_gpio_pull_t)pup;
66 }
67 
samsung_gpio_setcfg_2bit(struct samsung_gpio_chip * chip,unsigned int off,unsigned int cfg)68 static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
69 				    unsigned int off, unsigned int cfg)
70 {
71 	void __iomem *reg = chip->base;
72 	unsigned int shift = off * 2;
73 	u32 con;
74 
75 	if (samsung_gpio_is_cfg_special(cfg)) {
76 		cfg &= 0xf;
77 		if (cfg > 3)
78 			return -EINVAL;
79 
80 		cfg <<= shift;
81 	}
82 
83 	con = __raw_readl(reg);
84 	con &= ~(0x3 << shift);
85 	con |= cfg;
86 	__raw_writel(con, reg);
87 
88 	return 0;
89 }
90 
91 /*
92  * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
93  * @chip: The gpio chip that is being configured.
94  * @off: The offset for the GPIO being configured.
95  *
96  * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which
97  * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
98  * S3C_GPIO_SPECIAL() macro.
99  */
100 
samsung_gpio_getcfg_2bit(struct samsung_gpio_chip * chip,unsigned int off)101 static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
102 					     unsigned int off)
103 {
104 	u32 con;
105 
106 	con = __raw_readl(chip->base);
107 	con >>= off * 2;
108 	con &= 3;
109 
110 	/* this conversion works for IN and OUT as well as special mode */
111 	return S3C_GPIO_SPECIAL(con);
112 }
113 
114 /*
115  * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
116  * @chip: The gpio chip that is being configured.
117  * @off: The offset for the GPIO being configured.
118  * @cfg: The configuration value to set.
119  *
120  * This helper deal with the GPIO cases where the control register has 4 bits
121  * of control per GPIO, generally in the form of:
122  *	0000 = Input
123  *	0001 = Output
124  *	others = Special functions (dependent on bank)
125  *
126  * Note, since the code to deal with the case where there are two control
127  * registers instead of one, we do not have a separate set of functions for
128  * each case.
129  */
130 
samsung_gpio_setcfg_4bit(struct samsung_gpio_chip * chip,unsigned int off,unsigned int cfg)131 static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
132 				    unsigned int off, unsigned int cfg)
133 {
134 	void __iomem *reg = chip->base;
135 	unsigned int shift = (off & 7) * 4;
136 	u32 con;
137 
138 	if (off < 8 && chip->chip.ngpio > 8)
139 		reg -= 4;
140 
141 	if (samsung_gpio_is_cfg_special(cfg)) {
142 		cfg &= 0xf;
143 		cfg <<= shift;
144 	}
145 
146 	con = __raw_readl(reg);
147 	con &= ~(0xf << shift);
148 	con |= cfg;
149 	__raw_writel(con, reg);
150 
151 	return 0;
152 }
153 
154 /*
155  * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
156  * @chip: The gpio chip that is being configured.
157  * @off: The offset for the GPIO being configured.
158  *
159  * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
160  * register setting into a value the software can use, such as could be passed
161  * to samsung_gpio_setcfg_4bit().
162  *
163  * @sa samsung_gpio_getcfg_2bit
164  */
165 
samsung_gpio_getcfg_4bit(struct samsung_gpio_chip * chip,unsigned int off)166 static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
167 					 unsigned int off)
168 {
169 	void __iomem *reg = chip->base;
170 	unsigned int shift = (off & 7) * 4;
171 	u32 con;
172 
173 	if (off < 8 && chip->chip.ngpio > 8)
174 		reg -= 4;
175 
176 	con = __raw_readl(reg);
177 	con >>= shift;
178 	con &= 0xf;
179 
180 	/* this conversion works for IN and OUT as well as special mode */
181 	return S3C_GPIO_SPECIAL(con);
182 }
183 
samsung_gpiolib_set_cfg(struct samsung_gpio_cfg * chipcfg,int nr_chips)184 static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
185 					   int nr_chips)
186 {
187 	for (; nr_chips > 0; nr_chips--, chipcfg++) {
188 		if (!chipcfg->set_config)
189 			chipcfg->set_config = samsung_gpio_setcfg_4bit;
190 		if (!chipcfg->get_config)
191 			chipcfg->get_config = samsung_gpio_getcfg_4bit;
192 		if (!chipcfg->set_pull)
193 			chipcfg->set_pull = samsung_gpio_setpull_updown;
194 		if (!chipcfg->get_pull)
195 			chipcfg->get_pull = samsung_gpio_getpull_updown;
196 	}
197 }
198 
199 static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
200 	[0] = {
201 		.cfg_eint	= 0x0,
202 	},
203 	[1] = {
204 		.cfg_eint	= 0x3,
205 	},
206 	[2] = {
207 		.cfg_eint	= 0x7,
208 	},
209 	[3] = {
210 		.cfg_eint	= 0xF,
211 	},
212 	[4] = {
213 		.cfg_eint	= 0x0,
214 		.set_config	= samsung_gpio_setcfg_2bit,
215 		.get_config	= samsung_gpio_getcfg_2bit,
216 	},
217 	[5] = {
218 		.cfg_eint	= 0x2,
219 		.set_config	= samsung_gpio_setcfg_2bit,
220 		.get_config	= samsung_gpio_getcfg_2bit,
221 	},
222 	[6] = {
223 		.cfg_eint	= 0x3,
224 		.set_config	= samsung_gpio_setcfg_2bit,
225 		.get_config	= samsung_gpio_getcfg_2bit,
226 	},
227 	[7] = {
228 		.set_config	= samsung_gpio_setcfg_2bit,
229 		.get_config	= samsung_gpio_getcfg_2bit,
230 	},
231 };
232 
233 /*
234  * Default routines for controlling GPIO, based on the original S3C24XX
235  * GPIO functions which deal with the case where each gpio bank of the
236  * chip is as following:
237  *
238  * base + 0x00: Control register, 2 bits per gpio
239  *	        gpio n: 2 bits starting at (2*n)
240  *		00 = input, 01 = output, others mean special-function
241  * base + 0x04: Data register, 1 bit per gpio
242  *		bit n: data bit n
243 */
244 
samsung_gpiolib_2bit_input(struct gpio_chip * chip,unsigned offset)245 static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
246 {
247 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
248 	void __iomem *base = ourchip->base;
249 	unsigned long flags;
250 	unsigned long con;
251 
252 	samsung_gpio_lock(ourchip, flags);
253 
254 	con = __raw_readl(base + 0x00);
255 	con &= ~(3 << (offset * 2));
256 
257 	__raw_writel(con, base + 0x00);
258 
259 	samsung_gpio_unlock(ourchip, flags);
260 	return 0;
261 }
262 
samsung_gpiolib_2bit_output(struct gpio_chip * chip,unsigned offset,int value)263 static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
264 				       unsigned offset, int value)
265 {
266 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
267 	void __iomem *base = ourchip->base;
268 	unsigned long flags;
269 	unsigned long dat;
270 	unsigned long con;
271 
272 	samsung_gpio_lock(ourchip, flags);
273 
274 	dat = __raw_readl(base + 0x04);
275 	dat &= ~(1 << offset);
276 	if (value)
277 		dat |= 1 << offset;
278 	__raw_writel(dat, base + 0x04);
279 
280 	con = __raw_readl(base + 0x00);
281 	con &= ~(3 << (offset * 2));
282 	con |= 1 << (offset * 2);
283 
284 	__raw_writel(con, base + 0x00);
285 	__raw_writel(dat, base + 0x04);
286 
287 	samsung_gpio_unlock(ourchip, flags);
288 	return 0;
289 }
290 
291 /*
292  * The samsung_gpiolib_4bit routines are to control the gpio banks where
293  * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
294  * following example:
295  *
296  * base + 0x00: Control register, 4 bits per gpio
297  *		gpio n: 4 bits starting at (4*n)
298  *		0000 = input, 0001 = output, others mean special-function
299  * base + 0x04: Data register, 1 bit per gpio
300  *		bit n: data bit n
301  *
302  * Note, since the data register is one bit per gpio and is at base + 0x4
303  * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
304  * state of the output.
305  */
306 
samsung_gpiolib_4bit_input(struct gpio_chip * chip,unsigned int offset)307 static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
308 				      unsigned int offset)
309 {
310 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
311 	void __iomem *base = ourchip->base;
312 	unsigned long con;
313 
314 	con = __raw_readl(base + GPIOCON_OFF);
315 	if (ourchip->bitmap_gpio_int & BIT(offset))
316 		con |= 0xf << con_4bit_shift(offset);
317 	else
318 		con &= ~(0xf << con_4bit_shift(offset));
319 	__raw_writel(con, base + GPIOCON_OFF);
320 
321 	pr_debug("%s: %p: CON now %08lx\n", __func__, base, con);
322 
323 	return 0;
324 }
325 
samsung_gpiolib_4bit_output(struct gpio_chip * chip,unsigned int offset,int value)326 static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
327 				       unsigned int offset, int value)
328 {
329 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
330 	void __iomem *base = ourchip->base;
331 	unsigned long con;
332 	unsigned long dat;
333 
334 	con = __raw_readl(base + GPIOCON_OFF);
335 	con &= ~(0xf << con_4bit_shift(offset));
336 	con |= 0x1 << con_4bit_shift(offset);
337 
338 	dat = __raw_readl(base + GPIODAT_OFF);
339 
340 	if (value)
341 		dat |= 1 << offset;
342 	else
343 		dat &= ~(1 << offset);
344 
345 	__raw_writel(dat, base + GPIODAT_OFF);
346 	__raw_writel(con, base + GPIOCON_OFF);
347 	__raw_writel(dat, base + GPIODAT_OFF);
348 
349 	pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
350 
351 	return 0;
352 }
353 
354 /*
355  * The next set of routines are for the case where the GPIO configuration
356  * registers are 4 bits per GPIO but there is more than one register (the
357  * bank has more than 8 GPIOs.
358  *
359  * This case is the similar to the 4 bit case, but the registers are as
360  * follows:
361  *
362  * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
363  *		gpio n: 4 bits starting at (4*n)
364  *		0000 = input, 0001 = output, others mean special-function
365  * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
366  *		gpio n: 4 bits starting at (4*n)
367  *		0000 = input, 0001 = output, others mean special-function
368  * base + 0x08: Data register, 1 bit per gpio
369  *		bit n: data bit n
370  *
371  * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
372  * routines we store the 'base + 0x4' address so that these routines see
373  * the data register at ourchip->base + 0x04.
374  */
375 
samsung_gpiolib_4bit2_input(struct gpio_chip * chip,unsigned int offset)376 static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
377 				       unsigned int offset)
378 {
379 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
380 	void __iomem *base = ourchip->base;
381 	void __iomem *regcon = base;
382 	unsigned long con;
383 
384 	if (offset > 7)
385 		offset -= 8;
386 	else
387 		regcon -= 4;
388 
389 	con = __raw_readl(regcon);
390 	con &= ~(0xf << con_4bit_shift(offset));
391 	__raw_writel(con, regcon);
392 
393 	pr_debug("%s: %p: CON %08lx\n", __func__, base, con);
394 
395 	return 0;
396 }
397 
samsung_gpiolib_4bit2_output(struct gpio_chip * chip,unsigned int offset,int value)398 static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
399 					unsigned int offset, int value)
400 {
401 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
402 	void __iomem *base = ourchip->base;
403 	void __iomem *regcon = base;
404 	unsigned long con;
405 	unsigned long dat;
406 	unsigned con_offset = offset;
407 
408 	if (con_offset > 7)
409 		con_offset -= 8;
410 	else
411 		regcon -= 4;
412 
413 	con = __raw_readl(regcon);
414 	con &= ~(0xf << con_4bit_shift(con_offset));
415 	con |= 0x1 << con_4bit_shift(con_offset);
416 
417 	dat = __raw_readl(base + GPIODAT_OFF);
418 
419 	if (value)
420 		dat |= 1 << offset;
421 	else
422 		dat &= ~(1 << offset);
423 
424 	__raw_writel(dat, base + GPIODAT_OFF);
425 	__raw_writel(con, regcon);
426 	__raw_writel(dat, base + GPIODAT_OFF);
427 
428 	pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
429 
430 	return 0;
431 }
432 
samsung_gpiolib_set(struct gpio_chip * chip,unsigned int offset,int value)433 static int samsung_gpiolib_set(struct gpio_chip *chip, unsigned int offset,
434 			       int value)
435 {
436 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
437 	void __iomem *base = ourchip->base;
438 	unsigned long flags;
439 	unsigned long dat;
440 
441 	samsung_gpio_lock(ourchip, flags);
442 
443 	dat = __raw_readl(base + 0x04);
444 	dat &= ~(1 << offset);
445 	if (value)
446 		dat |= 1 << offset;
447 	__raw_writel(dat, base + 0x04);
448 
449 	samsung_gpio_unlock(ourchip, flags);
450 
451 	return 0;
452 }
453 
samsung_gpiolib_get(struct gpio_chip * chip,unsigned offset)454 static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
455 {
456 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
457 	unsigned long val;
458 
459 	val = __raw_readl(ourchip->base + 0x04);
460 	val >>= offset;
461 	val &= 1;
462 
463 	return val;
464 }
465 
466 /*
467  * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
468  * for use with the configuration calls, and other parts of the s3c gpiolib
469  * support code.
470  *
471  * Not all s3c support code will need this, as some configurations of cpu
472  * may only support one or two different configuration options and have an
473  * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
474  * the machine support file should provide its own samsung_gpiolib_getchip()
475  * and any other necessary functions.
476  */
477 
478 #ifdef CONFIG_S3C_GPIO_TRACK
479 struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
480 
s3c_gpiolib_track(struct samsung_gpio_chip * chip)481 static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
482 {
483 	unsigned int gpn;
484 	int i;
485 
486 	gpn = chip->chip.base;
487 	for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
488 		BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
489 		s3c_gpios[gpn] = chip;
490 	}
491 }
492 #endif /* CONFIG_S3C_GPIO_TRACK */
493 
494 /*
495  * samsung_gpiolib_add() - add the Samsung gpio_chip.
496  * @chip: The chip to register
497  *
498  * This is a wrapper to gpiochip_add() that takes our specific gpio chip
499  * information and makes the necessary alterations for the platform and
500  * notes the information for use with the configuration systems and any
501  * other parts of the system.
502  */
503 
samsung_gpiolib_add(struct samsung_gpio_chip * chip)504 static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
505 {
506 	struct gpio_chip *gc = &chip->chip;
507 	int ret;
508 
509 	BUG_ON(!chip->base);
510 	BUG_ON(!gc->label);
511 	BUG_ON(!gc->ngpio);
512 
513 	spin_lock_init(&chip->lock);
514 
515 	if (!gc->direction_input)
516 		gc->direction_input = samsung_gpiolib_2bit_input;
517 	if (!gc->direction_output)
518 		gc->direction_output = samsung_gpiolib_2bit_output;
519 	if (!gc->set)
520 		gc->set_rv = samsung_gpiolib_set;
521 	if (!gc->get)
522 		gc->get = samsung_gpiolib_get;
523 
524 #ifdef CONFIG_PM
525 	if (chip->pm != NULL) {
526 		if (!chip->pm->save || !chip->pm->resume)
527 			pr_err("gpio: %s has missing PM functions\n",
528 			       gc->label);
529 	} else
530 		pr_err("gpio: %s has no PM function\n", gc->label);
531 #endif
532 
533 	/* gpiochip_add() prints own failure message on error. */
534 	ret = gpiochip_add_data(gc, chip);
535 	if (ret >= 0)
536 		s3c_gpiolib_track(chip);
537 }
538 
samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip * chip,int nr_chips,void __iomem * base,unsigned int offset)539 static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
540 						  int nr_chips, void __iomem *base,
541 						  unsigned int offset)
542 {
543 	int i;
544 
545 	for (i = 0 ; i < nr_chips; i++, chip++) {
546 		chip->chip.direction_input = samsung_gpiolib_2bit_input;
547 		chip->chip.direction_output = samsung_gpiolib_2bit_output;
548 
549 		if (!chip->config)
550 			chip->config = &samsung_gpio_cfgs[7];
551 		if (!chip->pm)
552 			chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
553 		if ((base != NULL) && (chip->base == NULL))
554 			chip->base = base + ((i) * offset);
555 
556 		samsung_gpiolib_add(chip);
557 	}
558 }
559 
560 /*
561  * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
562  * @chip: The gpio chip that is being configured.
563  * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
564  *
565  * This helper deal with the GPIO cases where the control register has 4 bits
566  * of control per GPIO, generally in the form of:
567  * 0000 = Input
568  * 0001 = Output
569  * others = Special functions (dependent on bank)
570  *
571  * Note, since the code to deal with the case where there are two control
572  * registers instead of one, we do not have a separate set of function
573  * (samsung_gpiolib_add_4bit2_chips)for each case.
574  */
575 
samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip * chip,int nr_chips,void __iomem * base)576 static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
577 						  int nr_chips, void __iomem *base)
578 {
579 	int i;
580 
581 	for (i = 0 ; i < nr_chips; i++, chip++) {
582 		chip->chip.direction_input = samsung_gpiolib_4bit_input;
583 		chip->chip.direction_output = samsung_gpiolib_4bit_output;
584 
585 		if (!chip->config)
586 			chip->config = &samsung_gpio_cfgs[2];
587 		if (!chip->pm)
588 			chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
589 		if ((base != NULL) && (chip->base == NULL))
590 			chip->base = base + ((i) * 0x20);
591 
592 		chip->bitmap_gpio_int = 0;
593 
594 		samsung_gpiolib_add(chip);
595 	}
596 }
597 
samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip * chip,int nr_chips)598 static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
599 						   int nr_chips)
600 {
601 	for (; nr_chips > 0; nr_chips--, chip++) {
602 		chip->chip.direction_input = samsung_gpiolib_4bit2_input;
603 		chip->chip.direction_output = samsung_gpiolib_4bit2_output;
604 
605 		if (!chip->config)
606 			chip->config = &samsung_gpio_cfgs[2];
607 		if (!chip->pm)
608 			chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
609 
610 		samsung_gpiolib_add(chip);
611 	}
612 }
613 
samsung_gpiolib_to_irq(struct gpio_chip * chip,unsigned int offset)614 int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
615 {
616 	struct samsung_gpio_chip *samsung_chip = gpiochip_get_data(chip);
617 
618 	return samsung_chip->irq_base + offset;
619 }
620 
s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip * chip,unsigned pin)621 static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
622 {
623 	return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
624 }
625 
s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip * chip,unsigned pin)626 static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
627 {
628 	return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
629 }
630 
631 /*
632  * GPIO bank summary:
633  *
634  * Bank	GPIOs	Style	SlpCon	ExtInt Group
635  * A	8	4Bit	Yes	1
636  * B	7	4Bit	Yes	1
637  * C	8	4Bit	Yes	2
638  * D	5	4Bit	Yes	3
639  * E	5	4Bit	Yes	None
640  * F	16	2Bit	Yes	4 [1]
641  * G	7	4Bit	Yes	5
642  * H	10	4Bit[2]	Yes	6
643  * I	16	2Bit	Yes	None
644  * J	12	2Bit	Yes	None
645  * K	16	4Bit[2]	No	None
646  * L	15	4Bit[2] No	None
647  * M	6	4Bit	No	IRQ_EINT
648  * N	16	2Bit	No	IRQ_EINT
649  * O	16	2Bit	Yes	7
650  * P	15	2Bit	Yes	8
651  * Q	9	2Bit	Yes	9
652  *
653  * [1] BANKF pins 14,15 do not form part of the external interrupt sources
654  * [2] BANK has two control registers, GPxCON0 and GPxCON1
655  */
656 
657 static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
658 	{
659 		.chip	= {
660 			.base	= S3C64XX_GPA(0),
661 			.ngpio	= S3C64XX_GPIO_A_NR,
662 			.label	= "GPA",
663 		},
664 	}, {
665 		.chip	= {
666 			.base	= S3C64XX_GPB(0),
667 			.ngpio	= S3C64XX_GPIO_B_NR,
668 			.label	= "GPB",
669 		},
670 	}, {
671 		.chip	= {
672 			.base	= S3C64XX_GPC(0),
673 			.ngpio	= S3C64XX_GPIO_C_NR,
674 			.label	= "GPC",
675 		},
676 	}, {
677 		.chip	= {
678 			.base	= S3C64XX_GPD(0),
679 			.ngpio	= S3C64XX_GPIO_D_NR,
680 			.label	= "GPD",
681 		},
682 	}, {
683 		.config	= &samsung_gpio_cfgs[0],
684 		.chip	= {
685 			.base	= S3C64XX_GPE(0),
686 			.ngpio	= S3C64XX_GPIO_E_NR,
687 			.label	= "GPE",
688 		},
689 	}, {
690 		.base	= S3C64XX_GPG_BASE,
691 		.chip	= {
692 			.base	= S3C64XX_GPG(0),
693 			.ngpio	= S3C64XX_GPIO_G_NR,
694 			.label	= "GPG",
695 		},
696 	}, {
697 		.base	= S3C64XX_GPM_BASE,
698 		.config	= &samsung_gpio_cfgs[1],
699 		.chip	= {
700 			.base	= S3C64XX_GPM(0),
701 			.ngpio	= S3C64XX_GPIO_M_NR,
702 			.label	= "GPM",
703 			.to_irq = s3c64xx_gpiolib_mbank_to_irq,
704 		},
705 	},
706 };
707 
708 static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
709 	{
710 		.base	= S3C64XX_GPH_BASE + 0x4,
711 		.chip	= {
712 			.base	= S3C64XX_GPH(0),
713 			.ngpio	= S3C64XX_GPIO_H_NR,
714 			.label	= "GPH",
715 		},
716 	}, {
717 		.base	= S3C64XX_GPK_BASE + 0x4,
718 		.config	= &samsung_gpio_cfgs[0],
719 		.chip	= {
720 			.base	= S3C64XX_GPK(0),
721 			.ngpio	= S3C64XX_GPIO_K_NR,
722 			.label	= "GPK",
723 		},
724 	}, {
725 		.base	= S3C64XX_GPL_BASE + 0x4,
726 		.config	= &samsung_gpio_cfgs[1],
727 		.chip	= {
728 			.base	= S3C64XX_GPL(0),
729 			.ngpio	= S3C64XX_GPIO_L_NR,
730 			.label	= "GPL",
731 			.to_irq = s3c64xx_gpiolib_lbank_to_irq,
732 		},
733 	},
734 };
735 
736 static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
737 	{
738 		.base	= S3C64XX_GPF_BASE,
739 		.config	= &samsung_gpio_cfgs[6],
740 		.chip	= {
741 			.base	= S3C64XX_GPF(0),
742 			.ngpio	= S3C64XX_GPIO_F_NR,
743 			.label	= "GPF",
744 		},
745 	}, {
746 		.config	= &samsung_gpio_cfgs[7],
747 		.chip	= {
748 			.base	= S3C64XX_GPI(0),
749 			.ngpio	= S3C64XX_GPIO_I_NR,
750 			.label	= "GPI",
751 		},
752 	}, {
753 		.config	= &samsung_gpio_cfgs[7],
754 		.chip	= {
755 			.base	= S3C64XX_GPJ(0),
756 			.ngpio	= S3C64XX_GPIO_J_NR,
757 			.label	= "GPJ",
758 		},
759 	}, {
760 		.config	= &samsung_gpio_cfgs[6],
761 		.chip	= {
762 			.base	= S3C64XX_GPO(0),
763 			.ngpio	= S3C64XX_GPIO_O_NR,
764 			.label	= "GPO",
765 		},
766 	}, {
767 		.config	= &samsung_gpio_cfgs[6],
768 		.chip	= {
769 			.base	= S3C64XX_GPP(0),
770 			.ngpio	= S3C64XX_GPIO_P_NR,
771 			.label	= "GPP",
772 		},
773 	}, {
774 		.config	= &samsung_gpio_cfgs[6],
775 		.chip	= {
776 			.base	= S3C64XX_GPQ(0),
777 			.ngpio	= S3C64XX_GPIO_Q_NR,
778 			.label	= "GPQ",
779 		},
780 	}, {
781 		.base	= S3C64XX_GPN_BASE,
782 		.irq_base = IRQ_EINT(0),
783 		.config	= &samsung_gpio_cfgs[5],
784 		.chip	= {
785 			.base	= S3C64XX_GPN(0),
786 			.ngpio	= S3C64XX_GPIO_N_NR,
787 			.label	= "GPN",
788 			.to_irq = samsung_gpiolib_to_irq,
789 		},
790 	},
791 };
792 
793 /* TODO: cleanup soc_is_* */
samsung_gpiolib_init(void)794 static __init int samsung_gpiolib_init(void)
795 {
796 	/*
797 	 * Currently there are two drivers that can provide GPIO support for
798 	 * Samsung SoCs. For device tree enabled platforms, the new
799 	 * pinctrl-samsung driver is used, providing both GPIO and pin control
800 	 * interfaces. For legacy (non-DT) platforms this driver is used.
801 	 */
802 	if (of_have_populated_dt())
803 		return 0;
804 
805 	if (soc_is_s3c64xx()) {
806 		samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
807 				ARRAY_SIZE(samsung_gpio_cfgs));
808 		samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
809 				ARRAY_SIZE(s3c64xx_gpios_2bit),
810 				S3C64XX_VA_GPIO + 0xE0, 0x20);
811 		samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
812 				ARRAY_SIZE(s3c64xx_gpios_4bit),
813 				S3C64XX_VA_GPIO);
814 		samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
815 				ARRAY_SIZE(s3c64xx_gpios_4bit2));
816 	}
817 
818 	return 0;
819 }
820 core_initcall(samsung_gpiolib_init);
821 
s3c_gpio_cfgpin(unsigned int pin,unsigned int config)822 int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
823 {
824 	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
825 	unsigned long flags;
826 	int offset;
827 	int ret;
828 
829 	if (!chip)
830 		return -EINVAL;
831 
832 	offset = pin - chip->chip.base;
833 
834 	samsung_gpio_lock(chip, flags);
835 	ret = samsung_gpio_do_setcfg(chip, offset, config);
836 	samsung_gpio_unlock(chip, flags);
837 
838 	return ret;
839 }
840 EXPORT_SYMBOL(s3c_gpio_cfgpin);
841 
s3c_gpio_cfgpin_range(unsigned int start,unsigned int nr,unsigned int cfg)842 int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
843 			  unsigned int cfg)
844 {
845 	int ret;
846 
847 	for (; nr > 0; nr--, start++) {
848 		ret = s3c_gpio_cfgpin(start, cfg);
849 		if (ret != 0)
850 			return ret;
851 	}
852 
853 	return 0;
854 }
855 EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
856 
s3c_gpio_cfgall_range(unsigned int start,unsigned int nr,unsigned int cfg,samsung_gpio_pull_t pull)857 int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
858 			  unsigned int cfg, samsung_gpio_pull_t pull)
859 {
860 	int ret;
861 
862 	for (; nr > 0; nr--, start++) {
863 		s3c_gpio_setpull(start, pull);
864 		ret = s3c_gpio_cfgpin(start, cfg);
865 		if (ret != 0)
866 			return ret;
867 	}
868 
869 	return 0;
870 }
871 EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
872 
s3c_gpio_setpull(unsigned int pin,samsung_gpio_pull_t pull)873 int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
874 {
875 	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
876 	unsigned long flags;
877 	int offset, ret;
878 
879 	if (!chip)
880 		return -EINVAL;
881 
882 	offset = pin - chip->chip.base;
883 
884 	samsung_gpio_lock(chip, flags);
885 	ret = samsung_gpio_do_setpull(chip, offset, pull);
886 	samsung_gpio_unlock(chip, flags);
887 
888 	return ret;
889 }
890 EXPORT_SYMBOL(s3c_gpio_setpull);
891