1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2015 Linaro 4 * Peter Griffin <peter.griffin@linaro.org> 5 */ 6 7#include <dm.h> 8#include <asm/gpio.h> 9#include <asm/io.h> 10#include <errno.h> 11#include <linux/bitops.h> 12 13static 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 25static 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 34static 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 49static 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 56static const struct dm_gpio_ops gpio_hi6220_ops = { 57 .direction_input = hi6220_gpio_direction_input, 58 .direction_output = hi6220_gpio_direction_output, 59 .get_value = hi6220_gpio_get_value, 60 .set_value = hi6220_gpio_set_value, 61}; 62 63static int hi6220_gpio_probe(struct udevice *dev) 64{ 65 struct gpio_bank *bank = dev_get_priv(dev); 66 struct hikey_gpio_plat *plat = dev_get_plat(dev); 67 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 68 char name[18], *str; 69 70 sprintf(name, "GPIO%d_", plat->bank_index); 71 72 str = strdup(name); 73 if (!str) 74 return -ENOMEM; 75 76 uc_priv->bank_name = str; 77 uc_priv->gpio_count = HI6220_GPIO_PER_BANK; 78 79 bank->base = (u8 *)plat->base; 80 81 return 0; 82} 83 84U_BOOT_DRIVER(gpio_hi6220) = { 85 .name = "gpio_hi6220", 86 .id = UCLASS_GPIO, 87 .ops = &gpio_hi6220_ops, 88 .probe = hi6220_gpio_probe, 89 .priv_auto = sizeof(struct gpio_bank), 90}; 91