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