Home | History | Annotate | Download | only in regulator
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  *  Copyright (C) 2015 Samsung Electronics
      4  *
      5  *  Przemyslaw Marczak <p.marczak (at) samsung.com>
      6  */
      7 
      8 #include <common.h>
      9 #include <errno.h>
     10 #include <dm.h>
     11 #include <i2c.h>
     12 #include <asm/gpio.h>
     13 #include <power/pmic.h>
     14 #include <power/regulator.h>
     15 
     16 struct fixed_regulator_platdata {
     17 	struct gpio_desc gpio; /* GPIO for regulator enable control */
     18 	unsigned int startup_delay_us;
     19 };
     20 
     21 static int fixed_regulator_ofdata_to_platdata(struct udevice *dev)
     22 {
     23 	struct dm_regulator_uclass_platdata *uc_pdata;
     24 	struct fixed_regulator_platdata *dev_pdata;
     25 	struct gpio_desc *gpio;
     26 	int flags = GPIOD_IS_OUT;
     27 	int ret;
     28 
     29 	dev_pdata = dev_get_platdata(dev);
     30 	uc_pdata = dev_get_uclass_platdata(dev);
     31 	if (!uc_pdata)
     32 		return -ENXIO;
     33 
     34 	/* Set type to fixed */
     35 	uc_pdata->type = REGULATOR_TYPE_FIXED;
     36 
     37 	if (dev_read_bool(dev, "enable-active-high"))
     38 		flags |= GPIOD_IS_OUT_ACTIVE;
     39 
     40 	/* Get fixed regulator optional enable GPIO desc */
     41 	gpio = &dev_pdata->gpio;
     42 	ret = gpio_request_by_name(dev, "gpio", 0, gpio, flags);
     43 	if (ret) {
     44 		debug("Fixed regulator optional enable GPIO - not found! Error: %d\n",
     45 		      ret);
     46 		if (ret != -ENOENT)
     47 			return ret;
     48 	}
     49 
     50 	/* Get optional ramp up delay */
     51 	dev_pdata->startup_delay_us = dev_read_u32_default(dev,
     52 							"startup-delay-us", 0);
     53 
     54 	return 0;
     55 }
     56 
     57 static int fixed_regulator_get_value(struct udevice *dev)
     58 {
     59 	struct dm_regulator_uclass_platdata *uc_pdata;
     60 
     61 	uc_pdata = dev_get_uclass_platdata(dev);
     62 	if (!uc_pdata)
     63 		return -ENXIO;
     64 
     65 	if (uc_pdata->min_uV != uc_pdata->max_uV) {
     66 		debug("Invalid constraints for: %s\n", uc_pdata->name);
     67 		return -EINVAL;
     68 	}
     69 
     70 	return uc_pdata->min_uV;
     71 }
     72 
     73 static int fixed_regulator_get_current(struct udevice *dev)
     74 {
     75 	struct dm_regulator_uclass_platdata *uc_pdata;
     76 
     77 	uc_pdata = dev_get_uclass_platdata(dev);
     78 	if (!uc_pdata)
     79 		return -ENXIO;
     80 
     81 	if (uc_pdata->min_uA != uc_pdata->max_uA) {
     82 		debug("Invalid constraints for: %s\n", uc_pdata->name);
     83 		return -EINVAL;
     84 	}
     85 
     86 	return uc_pdata->min_uA;
     87 }
     88 
     89 static int fixed_regulator_get_enable(struct udevice *dev)
     90 {
     91 	struct fixed_regulator_platdata *dev_pdata = dev_get_platdata(dev);
     92 
     93 	/* Enable GPIO is optional */
     94 	if (!dev_pdata->gpio.dev)
     95 		return true;
     96 
     97 	return dm_gpio_get_value(&dev_pdata->gpio);
     98 }
     99 
    100 static int fixed_regulator_set_enable(struct udevice *dev, bool enable)
    101 {
    102 	struct fixed_regulator_platdata *dev_pdata = dev_get_platdata(dev);
    103 	int ret;
    104 
    105 	debug("%s: dev='%s', enable=%d, delay=%d, has_gpio=%d\n", __func__,
    106 	      dev->name, enable, dev_pdata->startup_delay_us,
    107 	      dm_gpio_is_valid(&dev_pdata->gpio));
    108 	/* Enable GPIO is optional */
    109 	if (!dm_gpio_is_valid(&dev_pdata->gpio)) {
    110 		if (!enable)
    111 			return -ENOSYS;
    112 		return 0;
    113 	}
    114 
    115 	ret = dm_gpio_set_value(&dev_pdata->gpio, enable);
    116 	if (ret) {
    117 		pr_err("Can't set regulator : %s gpio to: %d\n", dev->name,
    118 		      enable);
    119 		return ret;
    120 	}
    121 
    122 	if (enable && dev_pdata->startup_delay_us)
    123 		udelay(dev_pdata->startup_delay_us);
    124 	debug("%s: done\n", __func__);
    125 
    126 	return 0;
    127 }
    128 
    129 static const struct dm_regulator_ops fixed_regulator_ops = {
    130 	.get_value	= fixed_regulator_get_value,
    131 	.get_current	= fixed_regulator_get_current,
    132 	.get_enable	= fixed_regulator_get_enable,
    133 	.set_enable	= fixed_regulator_set_enable,
    134 };
    135 
    136 static const struct udevice_id fixed_regulator_ids[] = {
    137 	{ .compatible = "regulator-fixed" },
    138 	{ },
    139 };
    140 
    141 U_BOOT_DRIVER(fixed_regulator) = {
    142 	.name = "fixed regulator",
    143 	.id = UCLASS_REGULATOR,
    144 	.ops = &fixed_regulator_ops,
    145 	.of_match = fixed_regulator_ids,
    146 	.ofdata_to_platdata = fixed_regulator_ofdata_to_platdata,
    147 	.platdata_auto_alloc_size = sizeof(struct fixed_regulator_platdata),
    148 };
    149