uboot/drivers/power/pmic/as3722_gpio.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2014 NVIDIA Corporation
   4 */
   5
   6#include <common.h>
   7#include <dm.h>
   8#include <asm/gpio.h>
   9#include <power/as3722.h>
  10#include <power/pmic.h>
  11
  12#define NUM_GPIOS       8
  13
  14int as3722_gpio_configure(struct udevice *pmic, unsigned int gpio,
  15                          unsigned long flags)
  16{
  17        u8 value = 0;
  18        int err;
  19
  20        if (flags & AS3722_GPIO_OUTPUT_VDDH)
  21                value |= AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH;
  22
  23        if (flags & AS3722_GPIO_INVERT)
  24                value |= AS3722_GPIO_CONTROL_INVERT;
  25
  26        err = pmic_reg_write(pmic, AS3722_GPIO_CONTROL(gpio), value);
  27        if (err) {
  28                pr_err("failed to configure GPIO#%u: %d\n", gpio, err);
  29                return err;
  30        }
  31
  32        return 0;
  33}
  34
  35static int as3722_gpio_set_value(struct udevice *dev, unsigned int gpio,
  36                                 int level)
  37{
  38        struct udevice *pmic = dev_get_parent(dev);
  39        const char *l;
  40        u8 value;
  41        int err;
  42
  43        if (gpio >= NUM_GPIOS)
  44                return -EINVAL;
  45
  46        err = pmic_reg_read(pmic, AS3722_GPIO_SIGNAL_OUT);
  47        if (err < 0) {
  48                pr_err("failed to read GPIO signal out register: %d\n", err);
  49                return err;
  50        }
  51        value = err;
  52
  53        if (level == 0) {
  54                value &= ~(1 << gpio);
  55                l = "low";
  56        } else {
  57                value |= 1 << gpio;
  58                l = "high";
  59        }
  60
  61        err = pmic_reg_write(pmic, AS3722_GPIO_SIGNAL_OUT, value);
  62        if (err) {
  63                pr_err("failed to set GPIO#%u %s: %d\n", gpio, l, err);
  64                return err;
  65        }
  66
  67        return 0;
  68}
  69
  70int as3722_gpio_direction_output(struct udevice *dev, unsigned int gpio,
  71                                 int value)
  72{
  73        struct udevice *pmic = dev_get_parent(dev);
  74        int err;
  75
  76        if (gpio > 7)
  77                return -EINVAL;
  78
  79        if (value == 0)
  80                value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL;
  81        else
  82                value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH;
  83
  84        err = pmic_reg_write(pmic, AS3722_GPIO_CONTROL(gpio), value);
  85        if (err) {
  86                pr_err("failed to configure GPIO#%u as output: %d\n", gpio,
  87                       err);
  88                return err;
  89        }
  90
  91        err = as3722_gpio_set_value(pmic, gpio, value);
  92        if (err < 0) {
  93                pr_err("failed to set GPIO#%u high: %d\n", gpio, err);
  94                return err;
  95        }
  96
  97        return 0;
  98}
  99
 100static int as3722_gpio_probe(struct udevice *dev)
 101{
 102        struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 103
 104        uc_priv->gpio_count = NUM_GPIOS;
 105        uc_priv->bank_name = "as3722_";
 106
 107        return 0;
 108}
 109
 110static const struct dm_gpio_ops gpio_as3722_ops = {
 111        .direction_output       = as3722_gpio_direction_output,
 112        .set_value              = as3722_gpio_set_value,
 113};
 114
 115U_BOOT_DRIVER(gpio_as3722) = {
 116        .name   = "gpio_as3722",
 117        .id     = UCLASS_GPIO,
 118        .ops    = &gpio_as3722_ops,
 119        .probe  = as3722_gpio_probe,
 120};
 121