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