xref: /rk3399_rockchip-uboot/drivers/power/regulator/gpio-regulator.c (revision fae486e4076acd421e41805d832bf2e2e24dd302)
1477dfe2fSKeerthy /*
2477dfe2fSKeerthy  * (C) Copyright 2016 Texas Instruments Incorporated, <www.ti.com>
3477dfe2fSKeerthy  * Keerthy <j-keerthy@ti.com>
4477dfe2fSKeerthy  *
5477dfe2fSKeerthy  * SPDX-License-Identifier:     GPL-2.0+
6477dfe2fSKeerthy  */
7477dfe2fSKeerthy 
8477dfe2fSKeerthy #include <common.h>
9477dfe2fSKeerthy #include <fdtdec.h>
10477dfe2fSKeerthy #include <errno.h>
11477dfe2fSKeerthy #include <dm.h>
12477dfe2fSKeerthy #include <i2c.h>
13477dfe2fSKeerthy #include <asm/gpio.h>
14477dfe2fSKeerthy #include <power/pmic.h>
15477dfe2fSKeerthy #include <power/regulator.h>
16477dfe2fSKeerthy 
17477dfe2fSKeerthy #define GPIO_REGULATOR_MAX_STATES	2
18477dfe2fSKeerthy 
19477dfe2fSKeerthy DECLARE_GLOBAL_DATA_PTR;
20477dfe2fSKeerthy 
21477dfe2fSKeerthy struct gpio_regulator_platdata {
22477dfe2fSKeerthy 	struct gpio_desc gpio; /* GPIO for regulator voltage control */
23477dfe2fSKeerthy 	int states[GPIO_REGULATOR_MAX_STATES];
24477dfe2fSKeerthy 	int voltages[GPIO_REGULATOR_MAX_STATES];
25477dfe2fSKeerthy };
26477dfe2fSKeerthy 
gpio_regulator_ofdata_to_platdata(struct udevice * dev)27477dfe2fSKeerthy static int gpio_regulator_ofdata_to_platdata(struct udevice *dev)
28477dfe2fSKeerthy {
29477dfe2fSKeerthy 	struct dm_regulator_uclass_platdata *uc_pdata;
30477dfe2fSKeerthy 	struct gpio_regulator_platdata *dev_pdata;
31477dfe2fSKeerthy 	struct gpio_desc *gpio;
32*fae486e4SShawn Lin 	int ret, len, i, j;
33477dfe2fSKeerthy 	u32 states_array[8];
34477dfe2fSKeerthy 
35477dfe2fSKeerthy 	dev_pdata = dev_get_platdata(dev);
36477dfe2fSKeerthy 	uc_pdata = dev_get_uclass_platdata(dev);
37477dfe2fSKeerthy 	if (!uc_pdata)
38477dfe2fSKeerthy 		return -ENXIO;
39477dfe2fSKeerthy 
40477dfe2fSKeerthy 	/* Set type to gpio */
41477dfe2fSKeerthy 	uc_pdata->type = REGULATOR_TYPE_GPIO;
42477dfe2fSKeerthy 
43477dfe2fSKeerthy 	/*
44477dfe2fSKeerthy 	 * Get gpio regulator gpio desc
45477dfe2fSKeerthy 	 * Assuming one GPIO per regulator.
46477dfe2fSKeerthy 	 * Can be extended later to multiple GPIOs
47477dfe2fSKeerthy 	 * per gpio-regulator. As of now no instance with multiple
48477dfe2fSKeerthy 	 * gpios is presnt
49477dfe2fSKeerthy 	 */
50477dfe2fSKeerthy 	gpio = &dev_pdata->gpio;
51477dfe2fSKeerthy 	ret = gpio_request_by_name(dev, "gpios", 0, gpio, GPIOD_IS_OUT);
52477dfe2fSKeerthy 	if (ret)
53477dfe2fSKeerthy 		debug("regulator gpio - not found! Error: %d", ret);
54477dfe2fSKeerthy 
55*fae486e4SShawn Lin 	len = dev_read_size(dev, "states");
56*fae486e4SShawn Lin 	if (len < 0)
57*fae486e4SShawn Lin 		return len;
58477dfe2fSKeerthy 
59*fae486e4SShawn Lin 	len /= sizeof(fdt32_t);
60*fae486e4SShawn Lin 
61*fae486e4SShawn Lin 	ret = dev_read_u32_array(dev, "states", states_array, len);
62cd282fabSShawn Lin 	if (ret)
63cd282fabSShawn Lin 		return -EINVAL;
64cd282fabSShawn Lin 
65*fae486e4SShawn Lin 	for (i = 0, j = 0; i < len; i += 2) {
66477dfe2fSKeerthy 		dev_pdata->voltages[j] = states_array[i];
67477dfe2fSKeerthy 		dev_pdata->states[j] = states_array[i + 1];
68477dfe2fSKeerthy 		j++;
69477dfe2fSKeerthy 	}
70477dfe2fSKeerthy 
71477dfe2fSKeerthy 	return 0;
72477dfe2fSKeerthy }
73477dfe2fSKeerthy 
gpio_regulator_get_value(struct udevice * dev)74477dfe2fSKeerthy static int gpio_regulator_get_value(struct udevice *dev)
75477dfe2fSKeerthy {
76477dfe2fSKeerthy 	struct dm_regulator_uclass_platdata *uc_pdata;
77477dfe2fSKeerthy 	struct gpio_regulator_platdata *dev_pdata = dev_get_platdata(dev);
78477dfe2fSKeerthy 	int enable;
79477dfe2fSKeerthy 
80477dfe2fSKeerthy 	if (!dev_pdata->gpio.dev)
81477dfe2fSKeerthy 		return -ENOSYS;
82477dfe2fSKeerthy 
83477dfe2fSKeerthy 	uc_pdata = dev_get_uclass_platdata(dev);
84477dfe2fSKeerthy 	if (uc_pdata->min_uV > uc_pdata->max_uV) {
85477dfe2fSKeerthy 		debug("Invalid constraints for: %s\n", uc_pdata->name);
86477dfe2fSKeerthy 		return -EINVAL;
87477dfe2fSKeerthy 	}
88477dfe2fSKeerthy 
89477dfe2fSKeerthy 	enable = dm_gpio_get_value(&dev_pdata->gpio);
90477dfe2fSKeerthy 	if (enable == dev_pdata->states[0])
91477dfe2fSKeerthy 		return dev_pdata->voltages[0];
92477dfe2fSKeerthy 	else
93477dfe2fSKeerthy 		return dev_pdata->voltages[1];
94477dfe2fSKeerthy }
95477dfe2fSKeerthy 
gpio_regulator_set_value(struct udevice * dev,int uV)96477dfe2fSKeerthy static int gpio_regulator_set_value(struct udevice *dev, int uV)
97477dfe2fSKeerthy {
98477dfe2fSKeerthy 	struct gpio_regulator_platdata *dev_pdata = dev_get_platdata(dev);
99477dfe2fSKeerthy 	int ret;
100477dfe2fSKeerthy 	bool enable;
101477dfe2fSKeerthy 
102477dfe2fSKeerthy 	if (!dev_pdata->gpio.dev)
103477dfe2fSKeerthy 		return -ENOSYS;
104477dfe2fSKeerthy 
105477dfe2fSKeerthy 	if (uV == dev_pdata->voltages[0])
106477dfe2fSKeerthy 		enable = dev_pdata->states[0];
107477dfe2fSKeerthy 	else if (uV == dev_pdata->voltages[1])
108477dfe2fSKeerthy 		enable = dev_pdata->states[1];
109477dfe2fSKeerthy 	else
110477dfe2fSKeerthy 		return -EINVAL;
111477dfe2fSKeerthy 
112477dfe2fSKeerthy 	ret = dm_gpio_set_value(&dev_pdata->gpio, enable);
113477dfe2fSKeerthy 	if (ret) {
11490aa625cSMasahiro Yamada 		pr_err("Can't set regulator : %s gpio to: %d\n", dev->name,
115477dfe2fSKeerthy 		      enable);
116477dfe2fSKeerthy 		return ret;
117477dfe2fSKeerthy 	}
118477dfe2fSKeerthy 
119477dfe2fSKeerthy 	return 0;
120477dfe2fSKeerthy }
121477dfe2fSKeerthy 
122477dfe2fSKeerthy static const struct dm_regulator_ops gpio_regulator_ops = {
123477dfe2fSKeerthy 	.get_value	= gpio_regulator_get_value,
124477dfe2fSKeerthy 	.set_value	= gpio_regulator_set_value,
125477dfe2fSKeerthy };
126477dfe2fSKeerthy 
127477dfe2fSKeerthy static const struct udevice_id gpio_regulator_ids[] = {
128477dfe2fSKeerthy 	{ .compatible = "regulator-gpio" },
129477dfe2fSKeerthy 	{ },
130477dfe2fSKeerthy };
131477dfe2fSKeerthy 
132477dfe2fSKeerthy U_BOOT_DRIVER(gpio_regulator) = {
133477dfe2fSKeerthy 	.name = "gpio regulator",
134477dfe2fSKeerthy 	.id = UCLASS_REGULATOR,
135477dfe2fSKeerthy 	.ops = &gpio_regulator_ops,
136477dfe2fSKeerthy 	.of_match = gpio_regulator_ids,
137477dfe2fSKeerthy 	.ofdata_to_platdata = gpio_regulator_ofdata_to_platdata,
138477dfe2fSKeerthy 	.platdata_auto_alloc_size = sizeof(struct gpio_regulator_platdata),
139477dfe2fSKeerthy };
140