1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2015 Linaro 4 * Peter Griffin <peter.griffin@linaro.org> 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <asm/gpio.h> 10 #include <asm/io.h> 11 #include <errno.h> 12 13 static int hi6220_gpio_direction_input(struct udevice *dev, unsigned int gpio) 14 { 15 struct gpio_bank *bank = dev_get_priv(dev); 16 u8 data; 17 18 data = readb(bank->base + HI6220_GPIO_DIR); 19 data &= ~(1 << gpio); 20 writeb(data, bank->base + HI6220_GPIO_DIR); 21 22 return 0; 23 } 24 25 static int hi6220_gpio_set_value(struct udevice *dev, unsigned gpio, 26 int value) 27 { 28 struct gpio_bank *bank = dev_get_priv(dev); 29 30 writeb(!!value << gpio, bank->base + (BIT(gpio + 2))); 31 return 0; 32 } 33 34 static int hi6220_gpio_direction_output(struct udevice *dev, unsigned gpio, 35 int value) 36 { 37 struct gpio_bank *bank = dev_get_priv(dev); 38 u8 data; 39 40 data = readb(bank->base + HI6220_GPIO_DIR); 41 data |= 1 << gpio; 42 writeb(data, bank->base + HI6220_GPIO_DIR); 43 44 hi6220_gpio_set_value(dev, gpio, value); 45 46 return 0; 47 } 48 49 static int hi6220_gpio_get_value(struct udevice *dev, unsigned gpio) 50 { 51 struct gpio_bank *bank = dev_get_priv(dev); 52 53 return !!readb(bank->base + (BIT(gpio + 2))); 54 } 55 56 57 58 static const struct dm_gpio_ops gpio_hi6220_ops = { 59 .direction_input = hi6220_gpio_direction_input, 60 .direction_output = hi6220_gpio_direction_output, 61 .get_value = hi6220_gpio_get_value, 62 .set_value = hi6220_gpio_set_value, 63 }; 64 65 static int hi6220_gpio_probe(struct udevice *dev) 66 { 67 struct gpio_bank *bank = dev_get_priv(dev); 68 struct hikey_gpio_platdata *plat = dev_get_platdata(dev); 69 struct gpio_dev_priv *uc_priv = dev->uclass_priv; 70 char name[18], *str; 71 72 sprintf(name, "GPIO%d_", plat->bank_index); 73 74 str = strdup(name); 75 if (!str) 76 return -ENOMEM; 77 78 uc_priv->bank_name = str; 79 uc_priv->gpio_count = HI6220_GPIO_PER_BANK; 80 81 bank->base = (u8 *)plat->base; 82 83 return 0; 84 } 85 86 U_BOOT_DRIVER(gpio_hi6220) = { 87 .name = "gpio_hi6220", 88 .id = UCLASS_GPIO, 89 .ops = &gpio_hi6220_ops, 90 .probe = hi6220_gpio_probe, 91 .priv_auto_alloc_size = sizeof(struct gpio_bank), 92 }; 93 94 95