blob: a1bcddcf45583b9d97ef10973783e3d498016f6b [file] [log] [blame]
Minkyu Kangab693e92010-02-12 18:17:52 +09001/*
2 * (C) Copyright 2009 Samsung Electronics
3 * Minkyu Kang <mk7.kang@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
19 */
20
21#include <common.h>
22#include <asm/io.h>
23#include <asm/arch/gpio.h>
24
25#define CON_MASK(x) (0xf << ((x) << 2))
26#define CON_SFR(x, v) ((v) << ((x) << 2))
27
28#define DAT_MASK(x) (0x1 << (x))
29#define DAT_SET(x) (0x1 << (x))
30
31#define PULL_MASK(x) (0x3 << ((x) << 1))
32#define PULL_MODE(x, v) ((v) << ((x) << 1))
33
34#define DRV_MASK(x) (0x3 << ((x) << 1))
35#define DRV_SET(x, m) ((m) << ((x) << 1))
36#define RATE_MASK(x) (0x1 << (x + 16))
37#define RATE_SET(x) (0x1 << (x + 16))
38
Minkyu Kang3bb6b032010-03-24 15:31:06 +090039void gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg)
Minkyu Kangab693e92010-02-12 18:17:52 +090040{
41 unsigned int value;
42
43 value = readl(&bank->con);
44 value &= ~CON_MASK(gpio);
45 value |= CON_SFR(gpio, cfg);
46 writel(value, &bank->con);
47}
48
Minkyu Kang3bb6b032010-03-24 15:31:06 +090049void gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int en)
Minkyu Kangab693e92010-02-12 18:17:52 +090050{
51 unsigned int value;
52
53 gpio_cfg_pin(bank, gpio, GPIO_OUTPUT);
54
55 value = readl(&bank->dat);
56 value &= ~DAT_MASK(gpio);
57 if (en)
58 value |= DAT_SET(gpio);
59 writel(value, &bank->dat);
60}
61
Minkyu Kang3bb6b032010-03-24 15:31:06 +090062void gpio_direction_input(struct s5p_gpio_bank *bank, int gpio)
Minkyu Kangab693e92010-02-12 18:17:52 +090063{
64 gpio_cfg_pin(bank, gpio, GPIO_INPUT);
65}
66
Minkyu Kang3bb6b032010-03-24 15:31:06 +090067void gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en)
Minkyu Kangab693e92010-02-12 18:17:52 +090068{
69 unsigned int value;
70
71 value = readl(&bank->dat);
72 value &= ~DAT_MASK(gpio);
73 if (en)
74 value |= DAT_SET(gpio);
75 writel(value, &bank->dat);
76}
77
Minkyu Kang3bb6b032010-03-24 15:31:06 +090078unsigned int gpio_get_value(struct s5p_gpio_bank *bank, int gpio)
Minkyu Kangab693e92010-02-12 18:17:52 +090079{
80 unsigned int value;
81
82 value = readl(&bank->dat);
83 return !!(value & DAT_MASK(gpio));
84}
85
Minkyu Kang3bb6b032010-03-24 15:31:06 +090086void gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode)
Minkyu Kangab693e92010-02-12 18:17:52 +090087{
88 unsigned int value;
89
90 value = readl(&bank->pull);
91 value &= ~PULL_MASK(gpio);
92
93 switch (mode) {
94 case GPIO_PULL_DOWN:
95 case GPIO_PULL_UP:
96 value |= PULL_MODE(gpio, mode);
97 break;
98 default:
Minkyu Kangffb4b022010-05-28 12:34:29 +090099 break;
Minkyu Kangab693e92010-02-12 18:17:52 +0900100 }
101
102 writel(value, &bank->pull);
103}
104
Minkyu Kang3bb6b032010-03-24 15:31:06 +0900105void gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode)
Minkyu Kangab693e92010-02-12 18:17:52 +0900106{
107 unsigned int value;
108
109 value = readl(&bank->drv);
110 value &= ~DRV_MASK(gpio);
111
112 switch (mode) {
113 case GPIO_DRV_1X:
114 case GPIO_DRV_2X:
115 case GPIO_DRV_3X:
116 case GPIO_DRV_4X:
117 value |= DRV_SET(gpio, mode);
118 break;
119 default:
120 return;
121 }
122
123 writel(value, &bank->drv);
124}
125
Minkyu Kang3bb6b032010-03-24 15:31:06 +0900126void gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
Minkyu Kangab693e92010-02-12 18:17:52 +0900127{
128 unsigned int value;
129
130 value = readl(&bank->drv);
131 value &= ~RATE_MASK(gpio);
132
133 switch (mode) {
134 case GPIO_DRV_FAST:
135 case GPIO_DRV_SLOW:
136 value |= RATE_SET(gpio);
137 break;
138 default:
139 return;
140 }
141
142 writel(value, &bank->drv);
143}