1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2015 Samsung Electronics 4 * 5 * Przemyslaw Marczak <p.marczak@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