uboot/drivers/power/regulator/gpio-regulator.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2016 Texas Instruments Incorporated, <www.ti.com>
   4 * Keerthy <j-keerthy@ti.com>
   5 */
   6
   7#include <common.h>
   8#include <fdtdec.h>
   9#include <errno.h>
  10#include <dm.h>
  11#include <i2c.h>
  12#include <log.h>
  13#include <asm/gpio.h>
  14#include <power/pmic.h>
  15#include <power/regulator.h>
  16
  17#include "regulator_common.h"
  18
  19#define GPIO_REGULATOR_MAX_STATES       2
  20
  21struct gpio_regulator_plat {
  22        struct regulator_common_plat common;
  23        struct gpio_desc gpio; /* GPIO for regulator voltage control */
  24        int states[GPIO_REGULATOR_MAX_STATES];
  25        int voltages[GPIO_REGULATOR_MAX_STATES];
  26};
  27
  28static int gpio_regulator_of_to_plat(struct udevice *dev)
  29{
  30        struct dm_regulator_uclass_plat *uc_pdata;
  31        struct gpio_regulator_plat *dev_pdata;
  32        struct gpio_desc *gpio;
  33        int ret, count, i, j;
  34        u32 states_array[GPIO_REGULATOR_MAX_STATES * 2];
  35
  36        dev_pdata = dev_get_plat(dev);
  37        uc_pdata = dev_get_uclass_plat(dev);
  38        if (!uc_pdata)
  39                return -ENXIO;
  40
  41        /* Set type to gpio */
  42        uc_pdata->type = REGULATOR_TYPE_GPIO;
  43
  44        /*
  45         * Get gpio regulator gpio desc
  46         * Assuming one GPIO per regulator.
  47         * Can be extended later to multiple GPIOs
  48         * per gpio-regulator. As of now no instance with multiple
  49         * gpios is presnt
  50         */
  51        gpio = &dev_pdata->gpio;
  52        ret = gpio_request_by_name(dev, "gpios", 0, gpio, GPIOD_IS_OUT);
  53        if (ret)
  54                debug("regulator gpio - not found! Error: %d", ret);
  55
  56        ret = dev_read_size(dev, "states");
  57        if (ret < 0)
  58                return ret;
  59
  60        count = ret / sizeof(states_array[0]);
  61        if (count > ARRAY_SIZE(states_array)) {
  62                debug("regulator gpio - to many states (%d > %d)",
  63                      count / 2, GPIO_REGULATOR_MAX_STATES);
  64                count = ARRAY_SIZE(states_array);
  65        }
  66
  67        ret = dev_read_u32_array(dev, "states", states_array, count);
  68        if (ret < 0)
  69                return ret;
  70
  71        for (i = 0, j = 0; i < count; i += 2) {
  72                dev_pdata->voltages[j] = states_array[i];
  73                dev_pdata->states[j] = states_array[i + 1];
  74                j++;
  75        }
  76
  77        return regulator_common_of_to_plat(dev, &dev_pdata->common, "enable-gpios");
  78}
  79
  80static int gpio_regulator_get_value(struct udevice *dev)
  81{
  82        struct dm_regulator_uclass_plat *uc_pdata;
  83        struct gpio_regulator_plat *dev_pdata = dev_get_plat(dev);
  84        int enable;
  85
  86        if (!dev_pdata->gpio.dev)
  87                return -ENOSYS;
  88
  89        uc_pdata = dev_get_uclass_plat(dev);
  90        if (uc_pdata->min_uV > uc_pdata->max_uV) {
  91                debug("Invalid constraints for: %s\n", uc_pdata->name);
  92                return -EINVAL;
  93        }
  94
  95        enable = dm_gpio_get_value(&dev_pdata->gpio);
  96        if (enable == dev_pdata->states[0])
  97                return dev_pdata->voltages[0];
  98        else
  99                return dev_pdata->voltages[1];
 100}
 101
 102static int gpio_regulator_set_value(struct udevice *dev, int uV)
 103{
 104        struct gpio_regulator_plat *dev_pdata = dev_get_plat(dev);
 105        int ret;
 106        bool enable;
 107
 108        if (!dev_pdata->gpio.dev)
 109                return -ENOSYS;
 110
 111        if (uV == dev_pdata->voltages[0])
 112                enable = dev_pdata->states[0];
 113        else if (uV == dev_pdata->voltages[1])
 114                enable = dev_pdata->states[1];
 115        else
 116                return -EINVAL;
 117
 118        ret = dm_gpio_set_value(&dev_pdata->gpio, enable);
 119        if (ret) {
 120                pr_err("Can't set regulator : %s gpio to: %d\n", dev->name,
 121                      enable);
 122                return ret;
 123        }
 124
 125        return 0;
 126}
 127
 128static int gpio_regulator_get_enable(struct udevice *dev)
 129{
 130        struct gpio_regulator_plat *dev_pdata = dev_get_plat(dev);
 131        return regulator_common_get_enable(dev, &dev_pdata->common);
 132}
 133
 134static int gpio_regulator_set_enable(struct udevice *dev, bool enable)
 135{
 136        struct gpio_regulator_plat *dev_pdata = dev_get_plat(dev);
 137        return regulator_common_set_enable(dev, &dev_pdata->common, enable);
 138}
 139
 140static const struct dm_regulator_ops gpio_regulator_ops = {
 141        .get_value      = gpio_regulator_get_value,
 142        .set_value      = gpio_regulator_set_value,
 143        .get_enable     = gpio_regulator_get_enable,
 144        .set_enable     = gpio_regulator_set_enable,
 145};
 146
 147static const struct udevice_id gpio_regulator_ids[] = {
 148        { .compatible = "regulator-gpio" },
 149        { },
 150};
 151
 152U_BOOT_DRIVER(gpio_regulator) = {
 153        .name = "gpio regulator",
 154        .id = UCLASS_REGULATOR,
 155        .ops = &gpio_regulator_ops,
 156        .of_match = gpio_regulator_ids,
 157        .of_to_plat = gpio_regulator_of_to_plat,
 158        .plat_auto      = sizeof(struct gpio_regulator_plat),
 159};
 160