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