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