diff options
author | Tom Rini <trini@konsulko.com> | 2016-10-12 20:48:43 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2016-10-12 20:48:43 -0400 |
commit | 79493609c5300be6cc555ab8bd38971360b381f6 (patch) | |
tree | dff7c18752cbc05974dc5459c0b90879edf8e342 /drivers/power/regulator/gpio-regulator.c | |
parent | 5ebd27d860ec0c6e36f1b0f973653fe66a7360be (diff) | |
parent | bfeba0173aa45c24bbdba45149716c83258d25f6 (diff) | |
download | u-boot-imx-79493609c5300be6cc555ab8bd38971360b381f6.zip u-boot-imx-79493609c5300be6cc555ab8bd38971360b381f6.tar.gz u-boot-imx-79493609c5300be6cc555ab8bd38971360b381f6.tar.bz2 |
Merge git://git.denx.de/u-boot-dm
Diffstat (limited to 'drivers/power/regulator/gpio-regulator.c')
-rw-r--r-- | drivers/power/regulator/gpio-regulator.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/drivers/power/regulator/gpio-regulator.c b/drivers/power/regulator/gpio-regulator.c new file mode 100644 index 0000000..0a60a9c --- /dev/null +++ b/drivers/power/regulator/gpio-regulator.c @@ -0,0 +1,137 @@ +/* + * (C) Copyright 2016 Texas Instruments Incorporated, <www.ti.com> + * Keerthy <j-keerthy@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <fdtdec.h> +#include <errno.h> +#include <dm.h> +#include <i2c.h> +#include <asm/gpio.h> +#include <power/pmic.h> +#include <power/regulator.h> + +#define GPIO_REGULATOR_MAX_STATES 2 + +DECLARE_GLOBAL_DATA_PTR; + +struct gpio_regulator_platdata { + struct gpio_desc gpio; /* GPIO for regulator voltage control */ + int states[GPIO_REGULATOR_MAX_STATES]; + int voltages[GPIO_REGULATOR_MAX_STATES]; +}; + +static int gpio_regulator_ofdata_to_platdata(struct udevice *dev) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + struct gpio_regulator_platdata *dev_pdata; + struct gpio_desc *gpio; + const void *blob = gd->fdt_blob; + int node = dev->of_offset; + int ret, count, i, j; + u32 states_array[8]; + + dev_pdata = dev_get_platdata(dev); + uc_pdata = dev_get_uclass_platdata(dev); + if (!uc_pdata) + return -ENXIO; + + /* Set type to gpio */ + uc_pdata->type = REGULATOR_TYPE_GPIO; + + /* + * Get gpio regulator gpio desc + * Assuming one GPIO per regulator. + * Can be extended later to multiple GPIOs + * per gpio-regulator. As of now no instance with multiple + * gpios is presnt + */ + gpio = &dev_pdata->gpio; + ret = gpio_request_by_name(dev, "gpios", 0, gpio, GPIOD_IS_OUT); + if (ret) + debug("regulator gpio - not found! Error: %d", ret); + + count = fdtdec_get_int_array_count(blob, node, "states", + states_array, 8); + + if (!count) + return -EINVAL; + + for (i = 0, j = 0; i < count; i += 2) { + dev_pdata->voltages[j] = states_array[i]; + dev_pdata->states[j] = states_array[i + 1]; + j++; + } + + return 0; +} + +static int gpio_regulator_get_value(struct udevice *dev) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + struct gpio_regulator_platdata *dev_pdata = dev_get_platdata(dev); + int enable; + + if (!dev_pdata->gpio.dev) + return -ENOSYS; + + uc_pdata = dev_get_uclass_platdata(dev); + if (uc_pdata->min_uV > uc_pdata->max_uV) { + debug("Invalid constraints for: %s\n", uc_pdata->name); + return -EINVAL; + } + + enable = dm_gpio_get_value(&dev_pdata->gpio); + if (enable == dev_pdata->states[0]) + return dev_pdata->voltages[0]; + else + return dev_pdata->voltages[1]; +} + +static int gpio_regulator_set_value(struct udevice *dev, int uV) +{ + struct gpio_regulator_platdata *dev_pdata = dev_get_platdata(dev); + int ret; + bool enable; + + if (!dev_pdata->gpio.dev) + return -ENOSYS; + + if (uV == dev_pdata->voltages[0]) + enable = dev_pdata->states[0]; + else if (uV == dev_pdata->voltages[1]) + enable = dev_pdata->states[1]; + else + return -EINVAL; + + ret = dm_gpio_set_value(&dev_pdata->gpio, enable); + if (ret) { + error("Can't set regulator : %s gpio to: %d\n", dev->name, + enable); + return ret; + } + + return 0; +} + +static const struct dm_regulator_ops gpio_regulator_ops = { + .get_value = gpio_regulator_get_value, + .set_value = gpio_regulator_set_value, +}; + +static const struct udevice_id gpio_regulator_ids[] = { + { .compatible = "regulator-gpio" }, + { }, +}; + +U_BOOT_DRIVER(gpio_regulator) = { + .name = "gpio regulator", + .id = UCLASS_REGULATOR, + .ops = &gpio_regulator_ops, + .of_match = gpio_regulator_ids, + .ofdata_to_platdata = gpio_regulator_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct gpio_regulator_platdata), +}; |