]> git.sur5r.net Git - u-boot/blob - drivers/power/regulator/gpio-regulator.c
SPDX: Convert all of our single license tags to Linux Kernel style
[u-boot] / drivers / power / regulator / gpio-regulator.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2016 Texas Instruments Incorporated, <www.ti.com>
4  * Keerthy <j-keerthy@ti.com>
5  */
6
7 #include <common.h>
8 #include <fdtdec.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 #define GPIO_REGULATOR_MAX_STATES       2
17
18 DECLARE_GLOBAL_DATA_PTR;
19
20 struct gpio_regulator_platdata {
21         struct gpio_desc gpio; /* GPIO for regulator voltage control */
22         int states[GPIO_REGULATOR_MAX_STATES];
23         int voltages[GPIO_REGULATOR_MAX_STATES];
24 };
25
26 static int gpio_regulator_ofdata_to_platdata(struct udevice *dev)
27 {
28         struct dm_regulator_uclass_platdata *uc_pdata;
29         struct gpio_regulator_platdata *dev_pdata;
30         struct gpio_desc *gpio;
31         const void *blob = gd->fdt_blob;
32         int node = dev_of_offset(dev);
33         int ret, count, i, j;
34         u32 states_array[8];
35
36         dev_pdata = dev_get_platdata(dev);
37         uc_pdata = dev_get_uclass_platdata(dev);
38         if (!uc_pdata)
39                 return -ENXIO;
40
41         /* Set type to gpio */
42         uc_pdata->type = REGULATOR_TYPE_GPIO;
43
44         /*
45          * Get gpio regulator gpio desc
46          * Assuming one GPIO per regulator.
47          * Can be extended later to multiple GPIOs
48          * per gpio-regulator. As of now no instance with multiple
49          * gpios is presnt
50          */
51         gpio = &dev_pdata->gpio;
52         ret = gpio_request_by_name(dev, "gpios", 0, gpio, GPIOD_IS_OUT);
53         if (ret)
54                 debug("regulator gpio - not found! Error: %d", ret);
55
56         count = fdtdec_get_int_array_count(blob, node, "states",
57                                            states_array, 8);
58
59         if (!count)
60                 return -EINVAL;
61
62         for (i = 0, j = 0; i < count; i += 2) {
63                 dev_pdata->voltages[j] = states_array[i];
64                 dev_pdata->states[j] = states_array[i + 1];
65                 j++;
66         }
67
68         return 0;
69 }
70
71 static int gpio_regulator_get_value(struct udevice *dev)
72 {
73         struct dm_regulator_uclass_platdata *uc_pdata;
74         struct gpio_regulator_platdata *dev_pdata = dev_get_platdata(dev);
75         int enable;
76
77         if (!dev_pdata->gpio.dev)
78                 return -ENOSYS;
79
80         uc_pdata = dev_get_uclass_platdata(dev);
81         if (uc_pdata->min_uV > uc_pdata->max_uV) {
82                 debug("Invalid constraints for: %s\n", uc_pdata->name);
83                 return -EINVAL;
84         }
85
86         enable = dm_gpio_get_value(&dev_pdata->gpio);
87         if (enable == dev_pdata->states[0])
88                 return dev_pdata->voltages[0];
89         else
90                 return dev_pdata->voltages[1];
91 }
92
93 static int gpio_regulator_set_value(struct udevice *dev, int uV)
94 {
95         struct gpio_regulator_platdata *dev_pdata = dev_get_platdata(dev);
96         int ret;
97         bool enable;
98
99         if (!dev_pdata->gpio.dev)
100                 return -ENOSYS;
101
102         if (uV == dev_pdata->voltages[0])
103                 enable = dev_pdata->states[0];
104         else if (uV == dev_pdata->voltages[1])
105                 enable = dev_pdata->states[1];
106         else
107                 return -EINVAL;
108
109         ret = dm_gpio_set_value(&dev_pdata->gpio, enable);
110         if (ret) {
111                 pr_err("Can't set regulator : %s gpio to: %d\n", dev->name,
112                       enable);
113                 return ret;
114         }
115
116         return 0;
117 }
118
119 static const struct dm_regulator_ops gpio_regulator_ops = {
120         .get_value      = gpio_regulator_get_value,
121         .set_value      = gpio_regulator_set_value,
122 };
123
124 static const struct udevice_id gpio_regulator_ids[] = {
125         { .compatible = "regulator-gpio" },
126         { },
127 };
128
129 U_BOOT_DRIVER(gpio_regulator) = {
130         .name = "gpio regulator",
131         .id = UCLASS_REGULATOR,
132         .ops = &gpio_regulator_ops,
133         .of_match = gpio_regulator_ids,
134         .ofdata_to_platdata = gpio_regulator_ofdata_to_platdata,
135         .platdata_auto_alloc_size = sizeof(struct gpio_regulator_platdata),
136 };