uboot/drivers/gpio/mvebu_gpio.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2016 Stefan Roese <sr@denx.de>
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   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
  13DECLARE_GLOBAL_DATA_PTR;
  14
  15#define MVEBU_GPIOS_PER_BANK    32
  16
  17struct mvebu_gpio_regs {
  18        u32 data_out;
  19        u32 io_conf;
  20        u32 blink_en;
  21        u32 in_pol;
  22        u32 data_in;
  23};
  24
  25struct mvebu_gpio_priv {
  26        struct mvebu_gpio_regs *regs;
  27        char name[2];
  28};
  29
  30static int mvebu_gpio_direction_input(struct udevice *dev, unsigned int gpio)
  31{
  32        struct mvebu_gpio_priv *priv = dev_get_priv(dev);
  33        struct mvebu_gpio_regs *regs = priv->regs;
  34
  35        setbits_le32(&regs->io_conf, BIT(gpio));
  36
  37        return 0;
  38}
  39
  40static int mvebu_gpio_direction_output(struct udevice *dev, unsigned gpio,
  41                                       int value)
  42{
  43        struct mvebu_gpio_priv *priv = dev_get_priv(dev);
  44        struct mvebu_gpio_regs *regs = priv->regs;
  45
  46        if (value)
  47                setbits_le32(&regs->data_out, BIT(gpio));
  48        else
  49                clrbits_le32(&regs->data_out, BIT(gpio));
  50        clrbits_le32(&regs->io_conf, BIT(gpio));
  51
  52        return 0;
  53}
  54
  55static int mvebu_gpio_get_function(struct udevice *dev, unsigned gpio)
  56{
  57        struct mvebu_gpio_priv *priv = dev_get_priv(dev);
  58        struct mvebu_gpio_regs *regs = priv->regs;
  59        u32 val;
  60
  61        val = readl(&regs->io_conf) & BIT(gpio);
  62        if (val)
  63                return GPIOF_INPUT;
  64        else
  65                return GPIOF_OUTPUT;
  66}
  67
  68static int mvebu_gpio_set_value(struct udevice *dev, unsigned gpio,
  69                                int value)
  70{
  71        struct mvebu_gpio_priv *priv = dev_get_priv(dev);
  72        struct mvebu_gpio_regs *regs = priv->regs;
  73
  74        if (value)
  75                setbits_le32(&regs->data_out, BIT(gpio));
  76        else
  77                clrbits_le32(&regs->data_out, BIT(gpio));
  78
  79        return 0;
  80}
  81
  82static int mvebu_gpio_get_value(struct udevice *dev, unsigned gpio)
  83{
  84        struct mvebu_gpio_priv *priv = dev_get_priv(dev);
  85        struct mvebu_gpio_regs *regs = priv->regs;
  86
  87        return !!(readl(&regs->data_in) & BIT(gpio));
  88}
  89
  90static int mvebu_gpio_probe(struct udevice *dev)
  91{
  92        struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  93        struct mvebu_gpio_priv *priv = dev_get_priv(dev);
  94
  95        priv->regs = (struct mvebu_gpio_regs *)dev_get_addr(dev);
  96        uc_priv->gpio_count = MVEBU_GPIOS_PER_BANK;
  97        priv->name[0] = 'A' + dev->req_seq;
  98        uc_priv->bank_name = priv->name;
  99
 100        return 0;
 101}
 102
 103static const struct dm_gpio_ops mvebu_gpio_ops = {
 104        .direction_input        = mvebu_gpio_direction_input,
 105        .direction_output       = mvebu_gpio_direction_output,
 106        .get_function           = mvebu_gpio_get_function,
 107        .get_value              = mvebu_gpio_get_value,
 108        .set_value              = mvebu_gpio_set_value,
 109};
 110
 111static const struct udevice_id mvebu_gpio_ids[] = {
 112        { .compatible = "marvell,orion-gpio" },
 113        { }
 114};
 115
 116U_BOOT_DRIVER(gpio_mvebu) = {
 117        .name                   = "gpio_mvebu",
 118        .id                     = UCLASS_GPIO,
 119        .of_match               = mvebu_gpio_ids,
 120        .ops                    = &mvebu_gpio_ops,
 121        .probe                  = mvebu_gpio_probe,
 122        .priv_auto_alloc_size   = sizeof(struct mvebu_gpio_priv),
 123};
 124