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/irq.h>
15#include <linux/io.h>
16#include <linux/gpio.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
40static 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
55static 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
68static 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
101static 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
131static 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
166static 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
184static 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
199static 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
245static 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
263static 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
307static 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
326static 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
376static 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
398static 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
433static void samsung_gpiolib_set(struct gpio_chip *chip,
434				unsigned offset, 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
452static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
453{
454	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
455	unsigned long val;
456
457	val = __raw_readl(ourchip->base + 0x04);
458	val >>= offset;
459	val &= 1;
460
461	return val;
462}
463
464/*
465 * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
466 * for use with the configuration calls, and other parts of the s3c gpiolib
467 * support code.
468 *
469 * Not all s3c support code will need this, as some configurations of cpu
470 * may only support one or two different configuration options and have an
471 * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
472 * the machine support file should provide its own samsung_gpiolib_getchip()
473 * and any other necessary functions.
474 */
475
476#ifdef CONFIG_S3C_GPIO_TRACK
477struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
478
479static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
480{
481	unsigned int gpn;
482	int i;
483
484	gpn = chip->chip.base;
485	for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
486		BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
487		s3c_gpios[gpn] = chip;
488	}
489}
490#endif /* CONFIG_S3C_GPIO_TRACK */
491
492/*
493 * samsung_gpiolib_add() - add the Samsung gpio_chip.
494 * @chip: The chip to register
495 *
496 * This is a wrapper to gpiochip_add() that takes our specific gpio chip
497 * information and makes the necessary alterations for the platform and
498 * notes the information for use with the configuration systems and any
499 * other parts of the system.
500 */
501
502static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
503{
504	struct gpio_chip *gc = &chip->chip;
505	int ret;
506
507	BUG_ON(!chip->base);
508	BUG_ON(!gc->label);
509	BUG_ON(!gc->ngpio);
510
511	spin_lock_init(&chip->lock);
512
513	if (!gc->direction_input)
514		gc->direction_input = samsung_gpiolib_2bit_input;
515	if (!gc->direction_output)
516		gc->direction_output = samsung_gpiolib_2bit_output;
517	if (!gc->set)
518		gc->set = samsung_gpiolib_set;
519	if (!gc->get)
520		gc->get = samsung_gpiolib_get;
521
522#ifdef CONFIG_PM
523	if (chip->pm != NULL) {
524		if (!chip->pm->save || !chip->pm->resume)
525			pr_err("gpio: %s has missing PM functions\n",
526			       gc->label);
527	} else
528		pr_err("gpio: %s has no PM function\n", gc->label);
529#endif
530
531	/* gpiochip_add() prints own failure message on error. */
532	ret = gpiochip_add_data(gc, chip);
533	if (ret >= 0)
534		s3c_gpiolib_track(chip);
535}
536
537static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
538						  int nr_chips, void __iomem *base,
539						  unsigned int offset)
540{
541	int i;
542
543	for (i = 0 ; i < nr_chips; i++, chip++) {
544		chip->chip.direction_input = samsung_gpiolib_2bit_input;
545		chip->chip.direction_output = samsung_gpiolib_2bit_output;
546
547		if (!chip->config)
548			chip->config = &samsung_gpio_cfgs[7];
549		if (!chip->pm)
550			chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
551		if ((base != NULL) && (chip->base == NULL))
552			chip->base = base + ((i) * offset);
553
554		samsung_gpiolib_add(chip);
555	}
556}
557
558/*
559 * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
560 * @chip: The gpio chip that is being configured.
561 * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
562 *
563 * This helper deal with the GPIO cases where the control register has 4 bits
564 * of control per GPIO, generally in the form of:
565 * 0000 = Input
566 * 0001 = Output
567 * others = Special functions (dependent on bank)
568 *
569 * Note, since the code to deal with the case where there are two control
570 * registers instead of one, we do not have a separate set of function
571 * (samsung_gpiolib_add_4bit2_chips)for each case.
572 */
573
574static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
575						  int nr_chips, void __iomem *base)
576{
577	int i;
578
579	for (i = 0 ; i < nr_chips; i++, chip++) {
580		chip->chip.direction_input = samsung_gpiolib_4bit_input;
581		chip->chip.direction_output = samsung_gpiolib_4bit_output;
582
583		if (!chip->config)
584			chip->config = &samsung_gpio_cfgs[2];
585		if (!chip->pm)
586			chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
587		if ((base != NULL) && (chip->base == NULL))
588			chip->base = base + ((i) * 0x20);
589
590		chip->bitmap_gpio_int = 0;
591
592		samsung_gpiolib_add(chip);
593	}
594}
595
596static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
597						   int nr_chips)
598{
599	for (; nr_chips > 0; nr_chips--, chip++) {
600		chip->chip.direction_input = samsung_gpiolib_4bit2_input;
601		chip->chip.direction_output = samsung_gpiolib_4bit2_output;
602
603		if (!chip->config)
604			chip->config = &samsung_gpio_cfgs[2];
605		if (!chip->pm)
606			chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
607
608		samsung_gpiolib_add(chip);
609	}
610}
611
612int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
613{
614	struct samsung_gpio_chip *samsung_chip = gpiochip_get_data(chip);
615
616	return samsung_chip->irq_base + offset;
617}
618
619static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
620{
621	return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
622}
623
624static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
625{
626	return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
627}
628
629/*
630 * GPIO bank summary:
631 *
632 * Bank	GPIOs	Style	SlpCon	ExtInt Group
633 * A	8	4Bit	Yes	1
634 * B	7	4Bit	Yes	1
635 * C	8	4Bit	Yes	2
636 * D	5	4Bit	Yes	3
637 * E	5	4Bit	Yes	None
638 * F	16	2Bit	Yes	4 [1]
639 * G	7	4Bit	Yes	5
640 * H	10	4Bit[2]	Yes	6
641 * I	16	2Bit	Yes	None
642 * J	12	2Bit	Yes	None
643 * K	16	4Bit[2]	No	None
644 * L	15	4Bit[2] No	None
645 * M	6	4Bit	No	IRQ_EINT
646 * N	16	2Bit	No	IRQ_EINT
647 * O	16	2Bit	Yes	7
648 * P	15	2Bit	Yes	8
649 * Q	9	2Bit	Yes	9
650 *
651 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
652 * [2] BANK has two control registers, GPxCON0 and GPxCON1
653 */
654
655static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
656	{
657		.chip	= {
658			.base	= S3C64XX_GPA(0),
659			.ngpio	= S3C64XX_GPIO_A_NR,
660			.label	= "GPA",
661		},
662	}, {
663		.chip	= {
664			.base	= S3C64XX_GPB(0),
665			.ngpio	= S3C64XX_GPIO_B_NR,
666			.label	= "GPB",
667		},
668	}, {
669		.chip	= {
670			.base	= S3C64XX_GPC(0),
671			.ngpio	= S3C64XX_GPIO_C_NR,
672			.label	= "GPC",
673		},
674	}, {
675		.chip	= {
676			.base	= S3C64XX_GPD(0),
677			.ngpio	= S3C64XX_GPIO_D_NR,
678			.label	= "GPD",
679		},
680	}, {
681		.config	= &samsung_gpio_cfgs[0],
682		.chip	= {
683			.base	= S3C64XX_GPE(0),
684			.ngpio	= S3C64XX_GPIO_E_NR,
685			.label	= "GPE",
686		},
687	}, {
688		.base	= S3C64XX_GPG_BASE,
689		.chip	= {
690			.base	= S3C64XX_GPG(0),
691			.ngpio	= S3C64XX_GPIO_G_NR,
692			.label	= "GPG",
693		},
694	}, {
695		.base	= S3C64XX_GPM_BASE,
696		.config	= &samsung_gpio_cfgs[1],
697		.chip	= {
698			.base	= S3C64XX_GPM(0),
699			.ngpio	= S3C64XX_GPIO_M_NR,
700			.label	= "GPM",
701			.to_irq = s3c64xx_gpiolib_mbank_to_irq,
702		},
703	},
704};
705
706static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
707	{
708		.base	= S3C64XX_GPH_BASE + 0x4,
709		.chip	= {
710			.base	= S3C64XX_GPH(0),
711			.ngpio	= S3C64XX_GPIO_H_NR,
712			.label	= "GPH",
713		},
714	}, {
715		.base	= S3C64XX_GPK_BASE + 0x4,
716		.config	= &samsung_gpio_cfgs[0],
717		.chip	= {
718			.base	= S3C64XX_GPK(0),
719			.ngpio	= S3C64XX_GPIO_K_NR,
720			.label	= "GPK",
721		},
722	}, {
723		.base	= S3C64XX_GPL_BASE + 0x4,
724		.config	= &samsung_gpio_cfgs[1],
725		.chip	= {
726			.base	= S3C64XX_GPL(0),
727			.ngpio	= S3C64XX_GPIO_L_NR,
728			.label	= "GPL",
729			.to_irq = s3c64xx_gpiolib_lbank_to_irq,
730		},
731	},
732};
733
734static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
735	{
736		.base	= S3C64XX_GPF_BASE,
737		.config	= &samsung_gpio_cfgs[6],
738		.chip	= {
739			.base	= S3C64XX_GPF(0),
740			.ngpio	= S3C64XX_GPIO_F_NR,
741			.label	= "GPF",
742		},
743	}, {
744		.config	= &samsung_gpio_cfgs[7],
745		.chip	= {
746			.base	= S3C64XX_GPI(0),
747			.ngpio	= S3C64XX_GPIO_I_NR,
748			.label	= "GPI",
749		},
750	}, {
751		.config	= &samsung_gpio_cfgs[7],
752		.chip	= {
753			.base	= S3C64XX_GPJ(0),
754			.ngpio	= S3C64XX_GPIO_J_NR,
755			.label	= "GPJ",
756		},
757	}, {
758		.config	= &samsung_gpio_cfgs[6],
759		.chip	= {
760			.base	= S3C64XX_GPO(0),
761			.ngpio	= S3C64XX_GPIO_O_NR,
762			.label	= "GPO",
763		},
764	}, {
765		.config	= &samsung_gpio_cfgs[6],
766		.chip	= {
767			.base	= S3C64XX_GPP(0),
768			.ngpio	= S3C64XX_GPIO_P_NR,
769			.label	= "GPP",
770		},
771	}, {
772		.config	= &samsung_gpio_cfgs[6],
773		.chip	= {
774			.base	= S3C64XX_GPQ(0),
775			.ngpio	= S3C64XX_GPIO_Q_NR,
776			.label	= "GPQ",
777		},
778	}, {
779		.base	= S3C64XX_GPN_BASE,
780		.irq_base = IRQ_EINT(0),
781		.config	= &samsung_gpio_cfgs[5],
782		.chip	= {
783			.base	= S3C64XX_GPN(0),
784			.ngpio	= S3C64XX_GPIO_N_NR,
785			.label	= "GPN",
786			.to_irq = samsung_gpiolib_to_irq,
787		},
788	},
789};
790
791/* TODO: cleanup soc_is_* */
792static __init int samsung_gpiolib_init(void)
793{
794	/*
795	 * Currently there are two drivers that can provide GPIO support for
796	 * Samsung SoCs. For device tree enabled platforms, the new
797	 * pinctrl-samsung driver is used, providing both GPIO and pin control
798	 * interfaces. For legacy (non-DT) platforms this driver is used.
799	 */
800	if (of_have_populated_dt())
801		return 0;
802
803	if (soc_is_s3c64xx()) {
804		samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
805				ARRAY_SIZE(samsung_gpio_cfgs));
806		samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
807				ARRAY_SIZE(s3c64xx_gpios_2bit),
808				S3C64XX_VA_GPIO + 0xE0, 0x20);
809		samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
810				ARRAY_SIZE(s3c64xx_gpios_4bit),
811				S3C64XX_VA_GPIO);
812		samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
813				ARRAY_SIZE(s3c64xx_gpios_4bit2));
814	}
815
816	return 0;
817}
818core_initcall(samsung_gpiolib_init);
819
820int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
821{
822	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
823	unsigned long flags;
824	int offset;
825	int ret;
826
827	if (!chip)
828		return -EINVAL;
829
830	offset = pin - chip->chip.base;
831
832	samsung_gpio_lock(chip, flags);
833	ret = samsung_gpio_do_setcfg(chip, offset, config);
834	samsung_gpio_unlock(chip, flags);
835
836	return ret;
837}
838EXPORT_SYMBOL(s3c_gpio_cfgpin);
839
840int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
841			  unsigned int cfg)
842{
843	int ret;
844
845	for (; nr > 0; nr--, start++) {
846		ret = s3c_gpio_cfgpin(start, cfg);
847		if (ret != 0)
848			return ret;
849	}
850
851	return 0;
852}
853EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
854
855int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
856			  unsigned int cfg, samsung_gpio_pull_t pull)
857{
858	int ret;
859
860	for (; nr > 0; nr--, start++) {
861		s3c_gpio_setpull(start, pull);
862		ret = s3c_gpio_cfgpin(start, cfg);
863		if (ret != 0)
864			return ret;
865	}
866
867	return 0;
868}
869EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
870
871int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
872{
873	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
874	unsigned long flags;
875	int offset, ret;
876
877	if (!chip)
878		return -EINVAL;
879
880	offset = pin - chip->chip.base;
881
882	samsung_gpio_lock(chip, flags);
883	ret = samsung_gpio_do_setpull(chip, offset, pull);
884	samsung_gpio_unlock(chip, flags);
885
886	return ret;
887}
888EXPORT_SYMBOL(s3c_gpio_setpull);
889