1 /* 2 * (C) Copyright 2009 Samsung Electronics 3 * Minkyu Kang <mk7.kang@samsung.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <asm/io.h> 10 #include <asm/gpio.h> 11 12 #define CON_MASK(x) (0xf << ((x) << 2)) 13 #define CON_SFR(x, v) ((v) << ((x) << 2)) 14 15 #define DAT_MASK(x) (0x1 << (x)) 16 #define DAT_SET(x) (0x1 << (x)) 17 18 #define PULL_MASK(x) (0x3 << ((x) << 1)) 19 #define PULL_MODE(x, v) ((v) << ((x) << 1)) 20 21 #define DRV_MASK(x) (0x3 << ((x) << 1)) 22 #define DRV_SET(x, m) ((m) << ((x) << 1)) 23 #define RATE_MASK(x) (0x1 << (x + 16)) 24 #define RATE_SET(x) (0x1 << (x + 16)) 25 26 void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg) 27 { 28 unsigned int value; 29 30 value = readl(&bank->con); 31 value &= ~CON_MASK(gpio); 32 value |= CON_SFR(gpio, cfg); 33 writel(value, &bank->con); 34 } 35 36 void s5p_gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int en) 37 { 38 s5p_gpio_cfg_pin(bank, gpio, GPIO_OUTPUT); 39 s5p_gpio_set_value(bank, gpio, en); 40 } 41 42 void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, int gpio) 43 { 44 s5p_gpio_cfg_pin(bank, gpio, GPIO_INPUT); 45 } 46 47 void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en) 48 { 49 unsigned int value; 50 51 value = readl(&bank->dat); 52 value &= ~DAT_MASK(gpio); 53 if (en) 54 value |= DAT_SET(gpio); 55 writel(value, &bank->dat); 56 } 57 58 unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, int gpio) 59 { 60 unsigned int value; 61 62 value = readl(&bank->dat); 63 return !!(value & DAT_MASK(gpio)); 64 } 65 66 void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode) 67 { 68 unsigned int value; 69 70 value = readl(&bank->pull); 71 value &= ~PULL_MASK(gpio); 72 73 switch (mode) { 74 case GPIO_PULL_DOWN: 75 case GPIO_PULL_UP: 76 value |= PULL_MODE(gpio, mode); 77 break; 78 default: 79 break; 80 } 81 82 writel(value, &bank->pull); 83 } 84 85 void s5p_gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode) 86 { 87 unsigned int value; 88 89 value = readl(&bank->drv); 90 value &= ~DRV_MASK(gpio); 91 92 switch (mode) { 93 case GPIO_DRV_1X: 94 case GPIO_DRV_2X: 95 case GPIO_DRV_3X: 96 case GPIO_DRV_4X: 97 value |= DRV_SET(gpio, mode); 98 break; 99 default: 100 return; 101 } 102 103 writel(value, &bank->drv); 104 } 105 106 void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode) 107 { 108 unsigned int value; 109 110 value = readl(&bank->drv); 111 value &= ~RATE_MASK(gpio); 112 113 switch (mode) { 114 case GPIO_DRV_FAST: 115 case GPIO_DRV_SLOW: 116 value |= RATE_SET(gpio); 117 break; 118 default: 119 return; 120 } 121 122 writel(value, &bank->drv); 123 } 124 125 struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned gpio) 126 { 127 int bank; 128 unsigned g = gpio - s5p_gpio_part_max(gpio); 129 130 bank = g / GPIO_PER_BANK; 131 bank *= sizeof(struct s5p_gpio_bank); 132 return (struct s5p_gpio_bank *) (s5p_gpio_base(gpio) + bank); 133 } 134 135 int s5p_gpio_get_pin(unsigned gpio) 136 { 137 return gpio % GPIO_PER_BANK; 138 } 139 140 /* Common GPIO API */ 141 142 int gpio_request(unsigned gpio, const char *label) 143 { 144 return 0; 145 } 146 147 int gpio_free(unsigned gpio) 148 { 149 return 0; 150 } 151 152 int gpio_direction_input(unsigned gpio) 153 { 154 s5p_gpio_direction_input(s5p_gpio_get_bank(gpio), 155 s5p_gpio_get_pin(gpio)); 156 return 0; 157 } 158 159 int gpio_direction_output(unsigned gpio, int value) 160 { 161 s5p_gpio_direction_output(s5p_gpio_get_bank(gpio), 162 s5p_gpio_get_pin(gpio), value); 163 return 0; 164 } 165 166 int gpio_get_value(unsigned gpio) 167 { 168 return (int) s5p_gpio_get_value(s5p_gpio_get_bank(gpio), 169 s5p_gpio_get_pin(gpio)); 170 } 171 172 int gpio_set_value(unsigned gpio, int value) 173 { 174 s5p_gpio_set_value(s5p_gpio_get_bank(gpio), 175 s5p_gpio_get_pin(gpio), value); 176 177 return 0; 178 } 179