• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* linux/arch/arm/plat-s3c24xx/gpiolib.c
2  *
3  * Copyright (c) 2008 Simtec Electronics
4  *	http://armlinux.simtec.co.uk/
5  *	Ben Dooks <ben@simtec.co.uk>
6  *
7  * S3C24XX GPIOlib support
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License.
12 */
13 
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/module.h>
17 #include <linux/interrupt.h>
18 #include <linux/ioport.h>
19 #include <linux/io.h>
20 #include <linux/gpio.h>
21 
22 #include <plat/gpio-core.h>
23 #include <mach/hardware.h>
24 #include <asm/irq.h>
25 
26 #include <mach/regs-gpio.h>
27 
s3c24xx_gpiolib_banka_input(struct gpio_chip * chip,unsigned offset)28 static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
29 {
30 	return -EINVAL;
31 }
32 
s3c24xx_gpiolib_banka_output(struct gpio_chip * chip,unsigned offset,int value)33 static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
34 					unsigned offset, int value)
35 {
36 	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
37 	void __iomem *base = ourchip->base;
38 	unsigned long flags;
39 	unsigned long dat;
40 	unsigned long con;
41 
42 	local_irq_save(flags);
43 
44 	con = __raw_readl(base + 0x00);
45 	dat = __raw_readl(base + 0x04);
46 
47 	dat &= ~(1 << offset);
48 	if (value)
49 		dat |= 1 << offset;
50 
51 	__raw_writel(dat, base + 0x04);
52 
53 	con &= ~(1 << offset);
54 
55 	__raw_writel(con, base + 0x00);
56 	__raw_writel(dat, base + 0x04);
57 
58 	local_irq_restore(flags);
59 	return 0;
60 }
61 
s3c24xx_gpiolib_bankf_toirq(struct gpio_chip * chip,unsigned offset)62 static int s3c24xx_gpiolib_bankf_toirq(struct gpio_chip *chip, unsigned offset)
63 {
64 	if (offset < 4)
65 		return IRQ_EINT0 + offset;
66 
67 	if (offset < 8)
68 		return IRQ_EINT4 + offset - 4;
69 
70 	return -EINVAL;
71 }
72 
s3c24xx_gpiolib_bankg_toirq(struct gpio_chip * chip,unsigned offset)73 static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset)
74 {
75 	return IRQ_EINT8 + offset;
76 }
77 
78 struct s3c_gpio_chip s3c24xx_gpios[] = {
79 	[0] = {
80 		.base	= S3C24XX_GPIO_BASE(S3C2410_GPA0),
81 		.chip	= {
82 			.base			= S3C2410_GPA0,
83 			.owner			= THIS_MODULE,
84 			.label			= "GPIOA",
85 			.ngpio			= 24,
86 			.direction_input	= s3c24xx_gpiolib_banka_input,
87 			.direction_output	= s3c24xx_gpiolib_banka_output,
88 		},
89 	},
90 	[1] = {
91 		.base	= S3C24XX_GPIO_BASE(S3C2410_GPB0),
92 		.chip	= {
93 			.base			= S3C2410_GPB0,
94 			.owner			= THIS_MODULE,
95 			.label			= "GPIOB",
96 			.ngpio			= 16,
97 		},
98 	},
99 	[2] = {
100 		.base	= S3C24XX_GPIO_BASE(S3C2410_GPC0),
101 		.chip	= {
102 			.base			= S3C2410_GPC0,
103 			.owner			= THIS_MODULE,
104 			.label			= "GPIOC",
105 			.ngpio			= 16,
106 		},
107 	},
108 	[3] = {
109 		.base	= S3C24XX_GPIO_BASE(S3C2410_GPD0),
110 		.chip	= {
111 			.base			= S3C2410_GPD0,
112 			.owner			= THIS_MODULE,
113 			.label			= "GPIOD",
114 			.ngpio			= 16,
115 		},
116 	},
117 	[4] = {
118 		.base	= S3C24XX_GPIO_BASE(S3C2410_GPE0),
119 		.chip	= {
120 			.base			= S3C2410_GPE0,
121 			.label			= "GPIOE",
122 			.owner			= THIS_MODULE,
123 			.ngpio			= 16,
124 		},
125 	},
126 	[5] = {
127 		.base	= S3C24XX_GPIO_BASE(S3C2410_GPF0),
128 		.chip	= {
129 			.base			= S3C2410_GPF0,
130 			.owner			= THIS_MODULE,
131 			.label			= "GPIOF",
132 			.ngpio			= 8,
133 			.to_irq			= s3c24xx_gpiolib_bankf_toirq,
134 		},
135 	},
136 	[6] = {
137 		.base	= S3C24XX_GPIO_BASE(S3C2410_GPG0),
138 		.chip	= {
139 			.base			= S3C2410_GPG0,
140 			.owner			= THIS_MODULE,
141 			.label			= "GPIOG",
142 			.ngpio			= 10,
143 			.to_irq			= s3c24xx_gpiolib_bankg_toirq,
144 		},
145 	},
146 };
147 
s3c24xx_gpiolib_init(void)148 static __init int s3c24xx_gpiolib_init(void)
149 {
150 	struct s3c_gpio_chip *chip = s3c24xx_gpios;
151 	int gpn;
152 
153 	for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++)
154 		s3c_gpiolib_add(chip);
155 
156 	return 0;
157 }
158 
159 arch_initcall(s3c24xx_gpiolib_init);
160