• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/arm/mach-s3c64xx/
1/* arch/arm/plat-s3c64xx/gpiolib.c
2 *
3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008 Simtec Electronics
5 *      Ben Dooks <ben@simtec.co.uk>
6 *      http://armlinux.simtec.co.uk/
7 *
8 * S3C64XX - GPIOlib support
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/irq.h>
17#include <linux/io.h>
18#include <linux/gpio.h>
19
20#include <mach/map.h>
21
22#include <plat/gpio-core.h>
23#include <plat/gpio-cfg.h>
24#include <plat/gpio-cfg-helpers.h>
25#include <mach/regs-gpio.h>
26
27/* GPIO bank summary:
28 *
29 * Bank	GPIOs	Style	SlpCon	ExtInt Group
30 * A	8	4Bit	Yes	1
31 * B	7	4Bit	Yes	1
32 * C	8	4Bit	Yes	2
33 * D	5	4Bit	Yes	3
34 * E	5	4Bit	Yes	None
35 * F	16	2Bit	Yes	4 [1]
36 * G	7	4Bit	Yes	5
37 * H	10	4Bit[2]	Yes	6
38 * I	16	2Bit	Yes	None
39 * J	12	2Bit	Yes	None
40 * K	16	4Bit[2]	No	None
41 * L	15	4Bit[2] No	None
42 * M	6	4Bit	No	IRQ_EINT
43 * N	16	2Bit	No	IRQ_EINT
44 * O	16	2Bit	Yes	7
45 * P	15	2Bit	Yes	8
46 * Q	9	2Bit	Yes	9
47 *
48 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
49 * [2] BANK has two control registers, GPxCON0 and GPxCON1
50 */
51
52static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
53	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
54	.get_config	= s3c_gpio_getcfg_s3c64xx_4bit,
55	.set_pull	= s3c_gpio_setpull_updown,
56	.get_pull	= s3c_gpio_getpull_updown,
57};
58
59static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
60	.cfg_eint	= 7,
61	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
62	.get_config	= s3c_gpio_getcfg_s3c64xx_4bit,
63	.set_pull	= s3c_gpio_setpull_updown,
64	.get_pull	= s3c_gpio_getpull_updown,
65};
66
67static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
68	.cfg_eint	= 3,
69	.get_config	= s3c_gpio_getcfg_s3c64xx_4bit,
70	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
71	.set_pull	= s3c_gpio_setpull_updown,
72	.get_pull	= s3c_gpio_getpull_updown,
73};
74
75int s3c64xx_gpio2int_gpm(struct gpio_chip *chip, unsigned pin)
76{
77	return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
78}
79
80static struct s3c_gpio_chip gpio_4bit[] = {
81	{
82		.base	= S3C64XX_GPA_BASE,
83		.config	= &gpio_4bit_cfg_eint0111,
84		.chip	= {
85			.base	= S3C64XX_GPA(0),
86			.ngpio	= S3C64XX_GPIO_A_NR,
87			.label	= "GPA",
88		},
89	}, {
90		.base	= S3C64XX_GPB_BASE,
91		.config	= &gpio_4bit_cfg_eint0111,
92		.chip	= {
93			.base	= S3C64XX_GPB(0),
94			.ngpio	= S3C64XX_GPIO_B_NR,
95			.label	= "GPB",
96		},
97	}, {
98		.base	= S3C64XX_GPC_BASE,
99		.config	= &gpio_4bit_cfg_eint0111,
100		.chip	= {
101			.base	= S3C64XX_GPC(0),
102			.ngpio	= S3C64XX_GPIO_C_NR,
103			.label	= "GPC",
104		},
105	}, {
106		.base	= S3C64XX_GPD_BASE,
107		.config	= &gpio_4bit_cfg_eint0111,
108		.chip	= {
109			.base	= S3C64XX_GPD(0),
110			.ngpio	= S3C64XX_GPIO_D_NR,
111			.label	= "GPD",
112		},
113	}, {
114		.base	= S3C64XX_GPE_BASE,
115		.config	= &gpio_4bit_cfg_noint,
116		.chip	= {
117			.base	= S3C64XX_GPE(0),
118			.ngpio	= S3C64XX_GPIO_E_NR,
119			.label	= "GPE",
120		},
121	}, {
122		.base	= S3C64XX_GPG_BASE,
123		.config	= &gpio_4bit_cfg_eint0111,
124		.chip	= {
125			.base	= S3C64XX_GPG(0),
126			.ngpio	= S3C64XX_GPIO_G_NR,
127			.label	= "GPG",
128		},
129	}, {
130		.base	= S3C64XX_GPM_BASE,
131		.config	= &gpio_4bit_cfg_eint0011,
132		.chip	= {
133			.base	= S3C64XX_GPM(0),
134			.ngpio	= S3C64XX_GPIO_M_NR,
135			.label	= "GPM",
136			.to_irq = s3c64xx_gpio2int_gpm,
137		},
138	},
139};
140
141int s3c64xx_gpio2int_gpl(struct gpio_chip *chip, unsigned pin)
142{
143	return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
144}
145
146static struct s3c_gpio_chip gpio_4bit2[] = {
147	{
148		.base	= S3C64XX_GPH_BASE + 0x4,
149		.config	= &gpio_4bit_cfg_eint0111,
150		.chip	= {
151			.base	= S3C64XX_GPH(0),
152			.ngpio	= S3C64XX_GPIO_H_NR,
153			.label	= "GPH",
154		},
155	}, {
156		.base	= S3C64XX_GPK_BASE + 0x4,
157		.config	= &gpio_4bit_cfg_noint,
158		.chip	= {
159			.base	= S3C64XX_GPK(0),
160			.ngpio	= S3C64XX_GPIO_K_NR,
161			.label	= "GPK",
162		},
163	}, {
164		.base	= S3C64XX_GPL_BASE + 0x4,
165		.config	= &gpio_4bit_cfg_eint0011,
166		.chip	= {
167			.base	= S3C64XX_GPL(0),
168			.ngpio	= S3C64XX_GPIO_L_NR,
169			.label	= "GPL",
170			.to_irq = s3c64xx_gpio2int_gpl,
171		},
172	},
173};
174
175static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
176	.set_config	= s3c_gpio_setcfg_s3c24xx,
177	.get_config	= s3c_gpio_getcfg_s3c24xx,
178	.set_pull	= s3c_gpio_setpull_updown,
179	.get_pull	= s3c_gpio_getpull_updown,
180};
181
182static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
183	.cfg_eint	= 2,
184	.set_config	= s3c_gpio_setcfg_s3c24xx,
185	.get_config	= s3c_gpio_getcfg_s3c24xx,
186	.set_pull	= s3c_gpio_setpull_updown,
187	.get_pull	= s3c_gpio_getpull_updown,
188};
189
190static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
191	.cfg_eint	= 3,
192	.set_config	= s3c_gpio_setcfg_s3c24xx,
193	.get_config	= s3c_gpio_getcfg_s3c24xx,
194	.set_pull	= s3c_gpio_setpull_updown,
195	.get_pull	= s3c_gpio_getpull_updown,
196};
197
198int s3c64xx_gpio2int_gpn(struct gpio_chip *chip, unsigned pin)
199{
200	return IRQ_EINT(0) + pin;
201}
202
203static struct s3c_gpio_chip gpio_2bit[] = {
204	{
205		.base	= S3C64XX_GPF_BASE,
206		.config	= &gpio_2bit_cfg_eint11,
207		.chip	= {
208			.base	= S3C64XX_GPF(0),
209			.ngpio	= S3C64XX_GPIO_F_NR,
210			.label	= "GPF",
211		},
212	}, {
213		.base	= S3C64XX_GPI_BASE,
214		.config	= &gpio_2bit_cfg_noint,
215		.chip	= {
216			.base	= S3C64XX_GPI(0),
217			.ngpio	= S3C64XX_GPIO_I_NR,
218			.label	= "GPI",
219		},
220	}, {
221		.base	= S3C64XX_GPJ_BASE,
222		.config	= &gpio_2bit_cfg_noint,
223		.chip	= {
224			.base	= S3C64XX_GPJ(0),
225			.ngpio	= S3C64XX_GPIO_J_NR,
226			.label	= "GPJ",
227		},
228	}, {
229		.base	= S3C64XX_GPN_BASE,
230		.config	= &gpio_2bit_cfg_eint10,
231		.chip	= {
232			.base	= S3C64XX_GPN(0),
233			.ngpio	= S3C64XX_GPIO_N_NR,
234			.label	= "GPN",
235			.to_irq = s3c64xx_gpio2int_gpn,
236		},
237	}, {
238		.base	= S3C64XX_GPO_BASE,
239		.config	= &gpio_2bit_cfg_eint11,
240		.chip	= {
241			.base	= S3C64XX_GPO(0),
242			.ngpio	= S3C64XX_GPIO_O_NR,
243			.label	= "GPO",
244		},
245	}, {
246		.base	= S3C64XX_GPP_BASE,
247		.config	= &gpio_2bit_cfg_eint11,
248		.chip	= {
249			.base	= S3C64XX_GPP(0),
250			.ngpio	= S3C64XX_GPIO_P_NR,
251			.label	= "GPP",
252		},
253	}, {
254		.base	= S3C64XX_GPQ_BASE,
255		.config	= &gpio_2bit_cfg_eint11,
256		.chip	= {
257			.base	= S3C64XX_GPQ(0),
258			.ngpio	= S3C64XX_GPIO_Q_NR,
259			.label	= "GPQ",
260		},
261	},
262};
263
264static __init void s3c64xx_gpiolib_add_2bit(struct s3c_gpio_chip *chip)
265{
266	chip->pm = __gpio_pm(&s3c_gpio_pm_2bit);
267}
268
269static __init void s3c64xx_gpiolib_add(struct s3c_gpio_chip *chips,
270				       int nr_chips,
271				       void (*fn)(struct s3c_gpio_chip *))
272{
273	for (; nr_chips > 0; nr_chips--, chips++) {
274		if (fn)
275			(fn)(chips);
276		s3c_gpiolib_add(chips);
277	}
278}
279
280static __init int s3c64xx_gpiolib_init(void)
281{
282	s3c64xx_gpiolib_add(gpio_4bit, ARRAY_SIZE(gpio_4bit),
283			    samsung_gpiolib_add_4bit);
284
285	s3c64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2),
286			    samsung_gpiolib_add_4bit2);
287
288	s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit),
289			    s3c64xx_gpiolib_add_2bit);
290
291	return 0;
292}
293
294core_initcall(s3c64xx_gpiolib_init);
295