uboot/drivers/gpio/hi6220_gpio.c
<<
>>
Prefs
   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#include <linux/bitops.h>
  13
  14static int hi6220_gpio_direction_input(struct udevice *dev, unsigned int gpio)
  15{
  16        struct gpio_bank *bank = dev_get_priv(dev);
  17        u8 data;
  18
  19        data = readb(bank->base + HI6220_GPIO_DIR);
  20        data &= ~(1 << gpio);
  21        writeb(data, bank->base + HI6220_GPIO_DIR);
  22
  23        return 0;
  24}
  25
  26static int hi6220_gpio_set_value(struct udevice *dev, unsigned gpio,
  27                                  int value)
  28{
  29        struct gpio_bank *bank = dev_get_priv(dev);
  30
  31        writeb(!!value << gpio, bank->base + (BIT(gpio + 2)));
  32        return 0;
  33}
  34
  35static int hi6220_gpio_direction_output(struct udevice *dev, unsigned gpio,
  36                                        int value)
  37{
  38        struct gpio_bank *bank = dev_get_priv(dev);
  39        u8 data;
  40
  41        data = readb(bank->base + HI6220_GPIO_DIR);
  42        data |= 1 << gpio;
  43        writeb(data, bank->base + HI6220_GPIO_DIR);
  44
  45        hi6220_gpio_set_value(dev, gpio, value);
  46
  47        return 0;
  48}
  49
  50static int hi6220_gpio_get_value(struct udevice *dev, unsigned gpio)
  51{
  52        struct gpio_bank *bank = dev_get_priv(dev);
  53
  54        return !!readb(bank->base + (BIT(gpio + 2)));
  55}
  56
  57static const struct dm_gpio_ops gpio_hi6220_ops = {
  58        .direction_input        = hi6220_gpio_direction_input,
  59        .direction_output       = hi6220_gpio_direction_output,
  60        .get_value              = hi6220_gpio_get_value,
  61        .set_value              = hi6220_gpio_set_value,
  62};
  63
  64static int hi6220_gpio_probe(struct udevice *dev)
  65{
  66        struct gpio_bank *bank = dev_get_priv(dev);
  67        struct hikey_gpio_plat *plat = dev_get_plat(dev);
  68        struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  69        char name[18], *str;
  70
  71        sprintf(name, "GPIO%d_", plat->bank_index);
  72
  73        str = strdup(name);
  74        if (!str)
  75                return -ENOMEM;
  76
  77        uc_priv->bank_name = str;
  78        uc_priv->gpio_count = HI6220_GPIO_PER_BANK;
  79
  80        bank->base = (u8 *)plat->base;
  81
  82        return 0;
  83}
  84
  85U_BOOT_DRIVER(gpio_hi6220) = {
  86        .name   = "gpio_hi6220",
  87        .id     = UCLASS_GPIO,
  88        .ops    = &gpio_hi6220_ops,
  89        .probe  = hi6220_gpio_probe,
  90        .priv_auto      = sizeof(struct gpio_bank),
  91};
  92