xref: /rk3399_rockchip-uboot/drivers/gpio/s5p_gpio.c (revision 9f15bc0c1cc1a88ee655ea2dc3dd56caf8e5de79)
13bb6b037SMinkyu Kang /*
23bb6b037SMinkyu Kang  * (C) Copyright 2009 Samsung Electronics
33bb6b037SMinkyu Kang  * Minkyu Kang <mk7.kang@samsung.com>
43bb6b037SMinkyu Kang  *
53bb6b037SMinkyu Kang  * This program is free software; you can redistribute it and/or
63bb6b037SMinkyu Kang  * modify it under the terms of the GNU General Public License as
73bb6b037SMinkyu Kang  * published by the Free Software Foundation; either version 2 of
83bb6b037SMinkyu Kang  * the License, or (at your option) any later version.
93bb6b037SMinkyu Kang  *
103bb6b037SMinkyu Kang  * This program is distributed in the hope that it will be useful,
113bb6b037SMinkyu Kang  * but WITHOUT ANY WARRANTY; without even the implied warranty of
123bb6b037SMinkyu Kang  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
133bb6b037SMinkyu Kang  * GNU General Public License for more details.
143bb6b037SMinkyu Kang  *
153bb6b037SMinkyu Kang  * You should have received a copy of the GNU General Public License
163bb6b037SMinkyu Kang  * along with this program; if not, write to the Free Software
173bb6b037SMinkyu Kang  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
183bb6b037SMinkyu Kang  * MA 02111-1307 USA
193bb6b037SMinkyu Kang  */
203bb6b037SMinkyu Kang 
213bb6b037SMinkyu Kang #include <common.h>
223bb6b037SMinkyu Kang #include <asm/io.h>
233bb6b037SMinkyu Kang #include <asm/arch/gpio.h>
243bb6b037SMinkyu Kang 
253bb6b037SMinkyu Kang #define CON_MASK(x)		(0xf << ((x) << 2))
263bb6b037SMinkyu Kang #define CON_SFR(x, v)		((v) << ((x) << 2))
273bb6b037SMinkyu Kang 
283bb6b037SMinkyu Kang #define DAT_MASK(x)		(0x1 << (x))
293bb6b037SMinkyu Kang #define DAT_SET(x)		(0x1 << (x))
303bb6b037SMinkyu Kang 
313bb6b037SMinkyu Kang #define PULL_MASK(x)		(0x3 << ((x) << 1))
323bb6b037SMinkyu Kang #define PULL_MODE(x, v)		((v) << ((x) << 1))
333bb6b037SMinkyu Kang 
343bb6b037SMinkyu Kang #define DRV_MASK(x)		(0x3 << ((x) << 1))
353bb6b037SMinkyu Kang #define DRV_SET(x, m)		((m) << ((x) << 1))
363bb6b037SMinkyu Kang #define RATE_MASK(x)		(0x1 << (x + 16))
373bb6b037SMinkyu Kang #define RATE_SET(x)		(0x1 << (x + 16))
383bb6b037SMinkyu Kang 
39ef5d9eb9SŁukasz Majewski void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg)
403bb6b037SMinkyu Kang {
413bb6b037SMinkyu Kang 	unsigned int value;
423bb6b037SMinkyu Kang 
433bb6b037SMinkyu Kang 	value = readl(&bank->con);
443bb6b037SMinkyu Kang 	value &= ~CON_MASK(gpio);
453bb6b037SMinkyu Kang 	value |= CON_SFR(gpio, cfg);
463bb6b037SMinkyu Kang 	writel(value, &bank->con);
473bb6b037SMinkyu Kang }
483bb6b037SMinkyu Kang 
49ef5d9eb9SŁukasz Majewski void s5p_gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int en)
503bb6b037SMinkyu Kang {
513bb6b037SMinkyu Kang 	unsigned int value;
523bb6b037SMinkyu Kang 
53ef5d9eb9SŁukasz Majewski 	s5p_gpio_cfg_pin(bank, gpio, GPIO_OUTPUT);
543bb6b037SMinkyu Kang 
553bb6b037SMinkyu Kang 	value = readl(&bank->dat);
563bb6b037SMinkyu Kang 	value &= ~DAT_MASK(gpio);
573bb6b037SMinkyu Kang 	if (en)
583bb6b037SMinkyu Kang 		value |= DAT_SET(gpio);
593bb6b037SMinkyu Kang 	writel(value, &bank->dat);
603bb6b037SMinkyu Kang }
613bb6b037SMinkyu Kang 
62ef5d9eb9SŁukasz Majewski void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, int gpio)
633bb6b037SMinkyu Kang {
64ef5d9eb9SŁukasz Majewski 	s5p_gpio_cfg_pin(bank, gpio, GPIO_INPUT);
653bb6b037SMinkyu Kang }
663bb6b037SMinkyu Kang 
67ef5d9eb9SŁukasz Majewski void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en)
683bb6b037SMinkyu Kang {
693bb6b037SMinkyu Kang 	unsigned int value;
703bb6b037SMinkyu Kang 
713bb6b037SMinkyu Kang 	value = readl(&bank->dat);
723bb6b037SMinkyu Kang 	value &= ~DAT_MASK(gpio);
733bb6b037SMinkyu Kang 	if (en)
743bb6b037SMinkyu Kang 		value |= DAT_SET(gpio);
753bb6b037SMinkyu Kang 	writel(value, &bank->dat);
763bb6b037SMinkyu Kang }
773bb6b037SMinkyu Kang 
78ef5d9eb9SŁukasz Majewski unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, int gpio)
793bb6b037SMinkyu Kang {
803bb6b037SMinkyu Kang 	unsigned int value;
813bb6b037SMinkyu Kang 
823bb6b037SMinkyu Kang 	value = readl(&bank->dat);
833bb6b037SMinkyu Kang 	return !!(value & DAT_MASK(gpio));
843bb6b037SMinkyu Kang }
853bb6b037SMinkyu Kang 
86ef5d9eb9SŁukasz Majewski void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode)
873bb6b037SMinkyu Kang {
883bb6b037SMinkyu Kang 	unsigned int value;
893bb6b037SMinkyu Kang 
903bb6b037SMinkyu Kang 	value = readl(&bank->pull);
913bb6b037SMinkyu Kang 	value &= ~PULL_MASK(gpio);
923bb6b037SMinkyu Kang 
933bb6b037SMinkyu Kang 	switch (mode) {
943bb6b037SMinkyu Kang 	case GPIO_PULL_DOWN:
953bb6b037SMinkyu Kang 	case GPIO_PULL_UP:
963bb6b037SMinkyu Kang 		value |= PULL_MODE(gpio, mode);
973bb6b037SMinkyu Kang 		break;
983bb6b037SMinkyu Kang 	default:
99ffb4b025SMinkyu Kang 		break;
1003bb6b037SMinkyu Kang 	}
1013bb6b037SMinkyu Kang 
1023bb6b037SMinkyu Kang 	writel(value, &bank->pull);
1033bb6b037SMinkyu Kang }
1043bb6b037SMinkyu Kang 
105ef5d9eb9SŁukasz Majewski void s5p_gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode)
1063bb6b037SMinkyu Kang {
1073bb6b037SMinkyu Kang 	unsigned int value;
1083bb6b037SMinkyu Kang 
1093bb6b037SMinkyu Kang 	value = readl(&bank->drv);
1103bb6b037SMinkyu Kang 	value &= ~DRV_MASK(gpio);
1113bb6b037SMinkyu Kang 
1123bb6b037SMinkyu Kang 	switch (mode) {
1133bb6b037SMinkyu Kang 	case GPIO_DRV_1X:
1143bb6b037SMinkyu Kang 	case GPIO_DRV_2X:
1153bb6b037SMinkyu Kang 	case GPIO_DRV_3X:
1163bb6b037SMinkyu Kang 	case GPIO_DRV_4X:
1173bb6b037SMinkyu Kang 		value |= DRV_SET(gpio, mode);
1183bb6b037SMinkyu Kang 		break;
1193bb6b037SMinkyu Kang 	default:
1203bb6b037SMinkyu Kang 		return;
1213bb6b037SMinkyu Kang 	}
1223bb6b037SMinkyu Kang 
1233bb6b037SMinkyu Kang 	writel(value, &bank->drv);
1243bb6b037SMinkyu Kang }
1253bb6b037SMinkyu Kang 
126ef5d9eb9SŁukasz Majewski void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
1273bb6b037SMinkyu Kang {
1283bb6b037SMinkyu Kang 	unsigned int value;
1293bb6b037SMinkyu Kang 
1303bb6b037SMinkyu Kang 	value = readl(&bank->drv);
1313bb6b037SMinkyu Kang 	value &= ~RATE_MASK(gpio);
1323bb6b037SMinkyu Kang 
1333bb6b037SMinkyu Kang 	switch (mode) {
1343bb6b037SMinkyu Kang 	case GPIO_DRV_FAST:
1353bb6b037SMinkyu Kang 	case GPIO_DRV_SLOW:
1363bb6b037SMinkyu Kang 		value |= RATE_SET(gpio);
1373bb6b037SMinkyu Kang 		break;
1383bb6b037SMinkyu Kang 	default:
1393bb6b037SMinkyu Kang 		return;
1403bb6b037SMinkyu Kang 	}
1413bb6b037SMinkyu Kang 
1423bb6b037SMinkyu Kang 	writel(value, &bank->drv);
1433bb6b037SMinkyu Kang }
144*9f15bc0cSŁukasz Majewski 
145*9f15bc0cSŁukasz Majewski struct s5p_gpio_bank *s5p_gpio_get_bank(int nr)
146*9f15bc0cSŁukasz Majewski {
147*9f15bc0cSŁukasz Majewski 	int bank = nr / GPIO_PER_BANK;
148*9f15bc0cSŁukasz Majewski 	bank *= sizeof(struct s5p_gpio_bank);
149*9f15bc0cSŁukasz Majewski 
150*9f15bc0cSŁukasz Majewski 	return (struct s5p_gpio_bank *) (s5p_gpio_base(nr) + bank);
151*9f15bc0cSŁukasz Majewski }
152*9f15bc0cSŁukasz Majewski 
153*9f15bc0cSŁukasz Majewski int s5p_gpio_get_pin(int nr)
154*9f15bc0cSŁukasz Majewski {
155*9f15bc0cSŁukasz Majewski 	return nr % GPIO_PER_BANK;
156*9f15bc0cSŁukasz Majewski }
157*9f15bc0cSŁukasz Majewski 
158*9f15bc0cSŁukasz Majewski int gpio_request(int gpio, const char *label)
159*9f15bc0cSŁukasz Majewski {
160*9f15bc0cSŁukasz Majewski 	return 0;
161*9f15bc0cSŁukasz Majewski }
162*9f15bc0cSŁukasz Majewski 
163*9f15bc0cSŁukasz Majewski int gpio_direction_input(int nr)
164*9f15bc0cSŁukasz Majewski {
165*9f15bc0cSŁukasz Majewski 	s5p_gpio_direction_input(s5p_gpio_get_bank(nr),
166*9f15bc0cSŁukasz Majewski 				s5p_gpio_get_pin(nr));
167*9f15bc0cSŁukasz Majewski 	return 0;
168*9f15bc0cSŁukasz Majewski }
169*9f15bc0cSŁukasz Majewski 
170*9f15bc0cSŁukasz Majewski int gpio_direction_output(int nr, int value)
171*9f15bc0cSŁukasz Majewski {
172*9f15bc0cSŁukasz Majewski 	s5p_gpio_direction_output(s5p_gpio_get_bank(nr),
173*9f15bc0cSŁukasz Majewski 				 s5p_gpio_get_pin(nr), value);
174*9f15bc0cSŁukasz Majewski 	return 0;
175*9f15bc0cSŁukasz Majewski }
176*9f15bc0cSŁukasz Majewski 
177*9f15bc0cSŁukasz Majewski int gpio_get_value(int nr)
178*9f15bc0cSŁukasz Majewski {
179*9f15bc0cSŁukasz Majewski 	return (int) s5p_gpio_get_value(s5p_gpio_get_bank(nr),
180*9f15bc0cSŁukasz Majewski 				       s5p_gpio_get_pin(nr));
181*9f15bc0cSŁukasz Majewski }
182*9f15bc0cSŁukasz Majewski 
183*9f15bc0cSŁukasz Majewski void gpio_set_value(int nr, int value)
184*9f15bc0cSŁukasz Majewski {
185*9f15bc0cSŁukasz Majewski 	s5p_gpio_set_value(s5p_gpio_get_bank(nr),
186*9f15bc0cSŁukasz Majewski 			  s5p_gpio_get_pin(nr), value);
187*9f15bc0cSŁukasz Majewski }
188