s5p_gpio.c 4.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 * (C) Copyright 2009 Samsung Electronics
 * Minkyu Kang <mk7.kang@samsung.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <asm/io.h>
23
#include <asm/gpio.h>
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

#define CON_MASK(x)		(0xf << ((x) << 2))
#define CON_SFR(x, v)		((v) << ((x) << 2))

#define DAT_MASK(x)		(0x1 << (x))
#define DAT_SET(x)		(0x1 << (x))

#define PULL_MASK(x)		(0x3 << ((x) << 1))
#define PULL_MODE(x, v)		((v) << ((x) << 1))

#define DRV_MASK(x)		(0x3 << ((x) << 1))
#define DRV_SET(x, m)		((m) << ((x) << 1))
#define RATE_MASK(x)		(0x1 << (x + 16))
#define RATE_SET(x)		(0x1 << (x + 16))

39
void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg)
40 41 42 43 44 45 46 47 48
{
	unsigned int value;

	value = readl(&bank->con);
	value &= ~CON_MASK(gpio);
	value |= CON_SFR(gpio, cfg);
	writel(value, &bank->con);
}

49
void s5p_gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int en)
50 51 52
{
	unsigned int value;

53
	s5p_gpio_cfg_pin(bank, gpio, GPIO_OUTPUT);
54 55 56 57 58 59 60 61

	value = readl(&bank->dat);
	value &= ~DAT_MASK(gpio);
	if (en)
		value |= DAT_SET(gpio);
	writel(value, &bank->dat);
}

62
void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, int gpio)
63
{
64
	s5p_gpio_cfg_pin(bank, gpio, GPIO_INPUT);
65 66
}

67
void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en)
68 69 70 71 72 73 74 75 76 77
{
	unsigned int value;

	value = readl(&bank->dat);
	value &= ~DAT_MASK(gpio);
	if (en)
		value |= DAT_SET(gpio);
	writel(value, &bank->dat);
}

78
unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, int gpio)
79 80 81 82 83 84 85
{
	unsigned int value;

	value = readl(&bank->dat);
	return !!(value & DAT_MASK(gpio));
}

86
void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode)
87 88 89 90 91 92 93 94 95 96 97 98
{
	unsigned int value;

	value = readl(&bank->pull);
	value &= ~PULL_MASK(gpio);

	switch (mode) {
	case GPIO_PULL_DOWN:
	case GPIO_PULL_UP:
		value |= PULL_MODE(gpio, mode);
		break;
	default:
99
		break;
100 101 102 103 104
	}

	writel(value, &bank->pull);
}

105
void s5p_gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode)
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
{
	unsigned int value;

	value = readl(&bank->drv);
	value &= ~DRV_MASK(gpio);

	switch (mode) {
	case GPIO_DRV_1X:
	case GPIO_DRV_2X:
	case GPIO_DRV_3X:
	case GPIO_DRV_4X:
		value |= DRV_SET(gpio, mode);
		break;
	default:
		return;
	}

	writel(value, &bank->drv);
}

126
void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
{
	unsigned int value;

	value = readl(&bank->drv);
	value &= ~RATE_MASK(gpio);

	switch (mode) {
	case GPIO_DRV_FAST:
	case GPIO_DRV_SLOW:
		value |= RATE_SET(gpio);
		break;
	default:
		return;
	}

	writel(value, &bank->drv);
}
144

145
struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned gpio)
146
{
147
	int bank = gpio / GPIO_PER_BANK;
148 149
	bank *= sizeof(struct s5p_gpio_bank);

150
	return (struct s5p_gpio_bank *) (s5p_gpio_base(gpio) + bank);
151 152
}

153
int s5p_gpio_get_pin(unsigned gpio)
154
{
155
	return gpio % GPIO_PER_BANK;
156 157
}

158 159 160
/* Common GPIO API */

int gpio_request(unsigned gpio, const char *label)
161 162 163 164
{
	return 0;
}

165
int gpio_free(unsigned gpio)
166 167 168 169
{
	return 0;
}

170
int gpio_direction_input(unsigned gpio)
171
{
172 173
	s5p_gpio_direction_input(s5p_gpio_get_bank(gpio),
				s5p_gpio_get_pin(gpio));
174 175 176
	return 0;
}

177
int gpio_direction_output(unsigned gpio, int value)
178
{
179 180 181
	s5p_gpio_direction_output(s5p_gpio_get_bank(gpio),
				 s5p_gpio_get_pin(gpio), value);
	return 0;
182 183
}

184
int gpio_get_value(unsigned gpio)
185
{
186 187 188 189 190 191 192 193 194 195
	return (int) s5p_gpio_get_value(s5p_gpio_get_bank(gpio),
				       s5p_gpio_get_pin(gpio));
}

int gpio_set_value(unsigned gpio, int value)
{
	s5p_gpio_set_value(s5p_gpio_get_bank(gpio),
			  s5p_gpio_get_pin(gpio), value);

	return 0;
196
}