xref: /openbmc/u-boot/drivers/power/regulator/fixed.c (revision 3335786a)
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 	int ret;
31 
32 	dev_pdata = dev_get_platdata(dev);
33 	uc_pdata = dev_get_uclass_platdata(dev);
34 	if (!uc_pdata)
35 		return -ENXIO;
36 
37 	/* Set type to fixed */
38 	uc_pdata->type = REGULATOR_TYPE_FIXED;
39 
40 	/* Get fixed regulator gpio desc */
41 	gpio = &dev_pdata->gpio;
42 	ret = gpio_request_by_name(dev, "gpio", 0, gpio, GPIOD_IS_OUT);
43 	if (ret)
44 		debug("Fixed regulator gpio - not found! Error: %d", ret);
45 
46 	/* Get optional ramp up delay */
47 	dev_pdata->startup_delay_us = fdtdec_get_uint(gd->fdt_blob,
48 						      dev->of_offset,
49 						      "startup-delay-us", 0);
50 
51 	return 0;
52 }
53 
54 static int fixed_regulator_get_value(struct udevice *dev)
55 {
56 	struct dm_regulator_uclass_platdata *uc_pdata;
57 
58 	uc_pdata = dev_get_uclass_platdata(dev);
59 	if (!uc_pdata)
60 		return -ENXIO;
61 
62 	if (uc_pdata->min_uV != uc_pdata->max_uV) {
63 		debug("Invalid constraints for: %s\n", uc_pdata->name);
64 		return -EINVAL;
65 	}
66 
67 	return uc_pdata->min_uV;
68 }
69 
70 static int fixed_regulator_get_current(struct udevice *dev)
71 {
72 	struct dm_regulator_uclass_platdata *uc_pdata;
73 
74 	uc_pdata = dev_get_uclass_platdata(dev);
75 	if (!uc_pdata)
76 		return -ENXIO;
77 
78 	if (uc_pdata->min_uA != uc_pdata->max_uA) {
79 		debug("Invalid constraints for: %s\n", uc_pdata->name);
80 		return -EINVAL;
81 	}
82 
83 	return uc_pdata->min_uA;
84 }
85 
86 static bool fixed_regulator_get_enable(struct udevice *dev)
87 {
88 	struct fixed_regulator_platdata *dev_pdata = dev_get_platdata(dev);
89 
90 	if (!dev_pdata->gpio.dev)
91 		return false;
92 
93 	return dm_gpio_get_value(&dev_pdata->gpio);
94 }
95 
96 static int fixed_regulator_set_enable(struct udevice *dev, bool enable)
97 {
98 	struct fixed_regulator_platdata *dev_pdata = dev_get_platdata(dev);
99 	int ret;
100 
101 	if (!dev_pdata->gpio.dev)
102 		return -ENOSYS;
103 
104 	ret = dm_gpio_set_value(&dev_pdata->gpio, enable);
105 	if (ret) {
106 		error("Can't set regulator : %s gpio to: %d\n", dev->name,
107 		      enable);
108 		return ret;
109 	}
110 
111 	if (enable && dev_pdata->startup_delay_us)
112 		udelay(dev_pdata->startup_delay_us);
113 
114 	return 0;
115 }
116 
117 static const struct dm_regulator_ops fixed_regulator_ops = {
118 	.get_value	= fixed_regulator_get_value,
119 	.get_current	= fixed_regulator_get_current,
120 	.get_enable	= fixed_regulator_get_enable,
121 	.set_enable	= fixed_regulator_set_enable,
122 };
123 
124 static const struct udevice_id fixed_regulator_ids[] = {
125 	{ .compatible = "regulator-fixed" },
126 	{ },
127 };
128 
129 U_BOOT_DRIVER(fixed_regulator) = {
130 	.name = "fixed regulator",
131 	.id = UCLASS_REGULATOR,
132 	.ops = &fixed_regulator_ops,
133 	.of_match = fixed_regulator_ids,
134 	.ofdata_to_platdata = fixed_regulator_ofdata_to_platdata,
135 	.platdata_auto_alloc_size = sizeof(struct fixed_regulator_platdata),
136 };
137