1 /* 2 * Copyright (c) 2011 The Chromium OS Authors. 3 * SPDX-License-Identifier: GPL-2.0+ 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <fdtdec.h> 9 #include <malloc.h> 10 #include <asm/gpio.h> 11 #include <dm/of.h> 12 #include <dt-bindings/gpio/gpio.h> 13 14 DECLARE_GLOBAL_DATA_PTR; 15 16 /* Flags for each GPIO */ 17 #define GPIOF_OUTPUT (1 << 0) /* Currently set as an output */ 18 #define GPIOF_HIGH (1 << 1) /* Currently set high */ 19 #define GPIOF_ODR (1 << 2) /* Currently set to open drain mode */ 20 21 struct gpio_state { 22 const char *label; /* label given by requester */ 23 u8 flags; /* flags (GPIOF_...) */ 24 }; 25 26 /* Access routines for GPIO state */ 27 static u8 *get_gpio_flags(struct udevice *dev, unsigned offset) 28 { 29 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 30 struct gpio_state *state = dev_get_priv(dev); 31 32 if (offset >= uc_priv->gpio_count) { 33 static u8 invalid_flags; 34 printf("sandbox_gpio: error: invalid gpio %u\n", offset); 35 return &invalid_flags; 36 } 37 38 return &state[offset].flags; 39 } 40 41 static int get_gpio_flag(struct udevice *dev, unsigned offset, int flag) 42 { 43 return (*get_gpio_flags(dev, offset) & flag) != 0; 44 } 45 46 static int set_gpio_flag(struct udevice *dev, unsigned offset, int flag, 47 int value) 48 { 49 u8 *gpio = get_gpio_flags(dev, offset); 50 51 if (value) 52 *gpio |= flag; 53 else 54 *gpio &= ~flag; 55 56 return 0; 57 } 58 59 /* 60 * Back-channel sandbox-internal-only access to GPIO state 61 */ 62 63 int sandbox_gpio_get_value(struct udevice *dev, unsigned offset) 64 { 65 if (get_gpio_flag(dev, offset, GPIOF_OUTPUT)) 66 debug("sandbox_gpio: get_value on output gpio %u\n", offset); 67 return get_gpio_flag(dev, offset, GPIOF_HIGH); 68 } 69 70 int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value) 71 { 72 return set_gpio_flag(dev, offset, GPIOF_HIGH, value); 73 } 74 75 int sandbox_gpio_get_open_drain(struct udevice *dev, unsigned offset) 76 { 77 return get_gpio_flag(dev, offset, GPIOF_ODR); 78 } 79 80 int sandbox_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value) 81 { 82 return set_gpio_flag(dev, offset, GPIOF_ODR, value); 83 } 84 85 int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset) 86 { 87 return get_gpio_flag(dev, offset, GPIOF_OUTPUT); 88 } 89 90 int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output) 91 { 92 return set_gpio_flag(dev, offset, GPIOF_OUTPUT, output); 93 } 94 95 /* 96 * These functions implement the public interface within U-Boot 97 */ 98 99 /* set GPIO port 'offset' as an input */ 100 static int sb_gpio_direction_input(struct udevice *dev, unsigned offset) 101 { 102 debug("%s: offset:%u\n", __func__, offset); 103 104 return sandbox_gpio_set_direction(dev, offset, 0); 105 } 106 107 /* set GPIO port 'offset' as an output, with polarity 'value' */ 108 static int sb_gpio_direction_output(struct udevice *dev, unsigned offset, 109 int value) 110 { 111 debug("%s: offset:%u, value = %d\n", __func__, offset, value); 112 113 return sandbox_gpio_set_direction(dev, offset, 1) | 114 sandbox_gpio_set_value(dev, offset, value); 115 } 116 117 /* read GPIO IN value of port 'offset' */ 118 static int sb_gpio_get_value(struct udevice *dev, unsigned offset) 119 { 120 debug("%s: offset:%u\n", __func__, offset); 121 122 return sandbox_gpio_get_value(dev, offset); 123 } 124 125 /* write GPIO OUT value to port 'offset' */ 126 static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value) 127 { 128 debug("%s: offset:%u, value = %d\n", __func__, offset, value); 129 130 if (!sandbox_gpio_get_direction(dev, offset)) { 131 printf("sandbox_gpio: error: set_value on input gpio %u\n", 132 offset); 133 return -1; 134 } 135 136 return sandbox_gpio_set_value(dev, offset, value); 137 } 138 139 /* read GPIO ODR value of port 'offset' */ 140 static int sb_gpio_get_open_drain(struct udevice *dev, unsigned offset) 141 { 142 debug("%s: offset:%u\n", __func__, offset); 143 144 return sandbox_gpio_get_open_drain(dev, offset); 145 } 146 147 /* write GPIO ODR value to port 'offset' */ 148 static int sb_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value) 149 { 150 debug("%s: offset:%u, value = %d\n", __func__, offset, value); 151 152 if (!sandbox_gpio_get_direction(dev, offset)) { 153 printf("sandbox_gpio: error: set_open_drain on input gpio %u\n", 154 offset); 155 return -1; 156 } 157 158 return sandbox_gpio_set_open_drain(dev, offset, value); 159 } 160 161 static int sb_gpio_get_function(struct udevice *dev, unsigned offset) 162 { 163 if (get_gpio_flag(dev, offset, GPIOF_OUTPUT)) 164 return GPIOF_OUTPUT; 165 return GPIOF_INPUT; 166 } 167 168 static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, 169 struct ofnode_phandle_args *args) 170 { 171 desc->offset = args->args[0]; 172 if (args->args_count < 2) 173 return 0; 174 if (args->args[1] & GPIO_ACTIVE_LOW) 175 desc->flags |= GPIOD_ACTIVE_LOW; 176 if (args->args[1] & 2) 177 desc->flags |= GPIOD_IS_IN; 178 if (args->args[1] & 4) 179 desc->flags |= GPIOD_IS_OUT; 180 if (args->args[1] & 8) 181 desc->flags |= GPIOD_IS_OUT_ACTIVE; 182 183 return 0; 184 } 185 186 static const struct dm_gpio_ops gpio_sandbox_ops = { 187 .direction_input = sb_gpio_direction_input, 188 .direction_output = sb_gpio_direction_output, 189 .get_value = sb_gpio_get_value, 190 .set_value = sb_gpio_set_value, 191 .get_open_drain = sb_gpio_get_open_drain, 192 .set_open_drain = sb_gpio_set_open_drain, 193 .get_function = sb_gpio_get_function, 194 .xlate = sb_gpio_xlate, 195 }; 196 197 static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev) 198 { 199 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 200 201 uc_priv->gpio_count = dev_read_u32_default(dev, "num-gpios", 0); 202 uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name"); 203 204 return 0; 205 } 206 207 static int gpio_sandbox_probe(struct udevice *dev) 208 { 209 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 210 211 if (!dev_of_valid(dev)) 212 /* Tell the uclass how many GPIOs we have */ 213 uc_priv->gpio_count = CONFIG_SANDBOX_GPIO_COUNT; 214 215 dev->priv = calloc(sizeof(struct gpio_state), uc_priv->gpio_count); 216 217 return 0; 218 } 219 220 static int gpio_sandbox_remove(struct udevice *dev) 221 { 222 free(dev->priv); 223 224 return 0; 225 } 226 227 static const struct udevice_id sandbox_gpio_ids[] = { 228 { .compatible = "sandbox,gpio" }, 229 { } 230 }; 231 232 U_BOOT_DRIVER(gpio_sandbox) = { 233 .name = "gpio_sandbox", 234 .id = UCLASS_GPIO, 235 .of_match = sandbox_gpio_ids, 236 .ofdata_to_platdata = sandbox_gpio_ofdata_to_platdata, 237 .probe = gpio_sandbox_probe, 238 .remove = gpio_sandbox_remove, 239 .ops = &gpio_sandbox_ops, 240 }; 241