1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2017 Google, Inc
4  * Written by Simon Glass <sjg@chromium.org>
5  *
6  * Placeholder regulator driver for as3722.
7  */
8 
9 #include <common.h>
10 #include <dm.h>
11 #include <errno.h>
12 #include <log.h>
13 #include <power/as3722.h>
14 #include <power/pmic.h>
15 #include <power/regulator.h>
16 
17 #define AS3722_LDO_CONTROL0_MAX_INDEX 7
18 
stepdown_get_value(struct udevice * dev)19 static int stepdown_get_value(struct udevice *dev)
20 {
21 	return -ENOSYS;
22 }
23 
stepdown_set_value(struct udevice * dev,int uvolt)24 static int stepdown_set_value(struct udevice *dev, int uvolt)
25 {
26 	return -ENOSYS;
27 }
28 
stepdown_set_enable(struct udevice * dev,bool enable)29 static int stepdown_set_enable(struct udevice *dev, bool enable)
30 {
31 	struct udevice *pmic = dev_get_parent(dev);
32 	int sd = dev->driver_data;
33 	int ret;
34 
35 	ret = pmic_clrsetbits(pmic, AS3722_SD_CONTROL, 0, 1 << sd);
36 	if (ret < 0) {
37 		debug("%s: failed to write SD control register: %d", __func__,
38 		      ret);
39 		return ret;
40 	}
41 
42 	return 0;
43 }
44 
stepdown_get_enable(struct udevice * dev)45 static int stepdown_get_enable(struct udevice *dev)
46 {
47 	struct udevice *pmic = dev_get_parent(dev);
48 	int sd = dev->driver_data;
49 	int ret;
50 
51 	ret = pmic_reg_read(pmic, AS3722_SD_CONTROL);
52 	if (ret < 0) {
53 		debug("%s: failed to read SD control register: %d", __func__,
54 		      ret);
55 		return ret;
56 	}
57 
58 	return ret & (1 << sd) ? true : false;
59 }
60 
ldo_get_value(struct udevice * dev)61 static int ldo_get_value(struct udevice *dev)
62 {
63 	return -ENOSYS;
64 }
65 
ldo_set_value(struct udevice * dev,int uvolt)66 static int ldo_set_value(struct udevice *dev, int uvolt)
67 {
68 	return -ENOSYS;
69 }
70 
ldo_set_enable(struct udevice * dev,bool enable)71 static int ldo_set_enable(struct udevice *dev, bool enable)
72 {
73 	struct udevice *pmic = dev_get_parent(dev);
74 	u8 ctrl_reg = AS3722_LDO_CONTROL0;
75 	int ldo = dev->driver_data;
76 	int ret;
77 
78 	if (ldo > AS3722_LDO_CONTROL0_MAX_INDEX) {
79 		ctrl_reg = AS3722_LDO_CONTROL1;
80 		ldo -= 8;
81 	}
82 
83 	ret = pmic_clrsetbits(pmic, ctrl_reg, !enable << ldo, enable << ldo);
84 	if (ret < 0) {
85 		debug("%s: failed to write LDO control register: %d", __func__,
86 		      ret);
87 		return ret;
88 	}
89 
90 	return 0;
91 }
92 
ldo_get_enable(struct udevice * dev)93 static int ldo_get_enable(struct udevice *dev)
94 {
95 	struct udevice *pmic = dev_get_parent(dev);
96 	u8 ctrl_reg = AS3722_LDO_CONTROL0;
97 	int ldo = dev->driver_data;
98 	int ret;
99 
100 	if (ldo > AS3722_LDO_CONTROL0_MAX_INDEX) {
101 		ctrl_reg = AS3722_LDO_CONTROL1;
102 		ldo -= 8;
103 	}
104 
105 	ret = pmic_reg_read(pmic, ctrl_reg);
106 	if (ret < 0) {
107 		debug("%s: failed to read SD control register: %d", __func__,
108 		      ret);
109 		return ret;
110 	}
111 
112 	return ret & (1 << ldo) ? true : false;
113 }
114 
as3722_stepdown_probe(struct udevice * dev)115 static int as3722_stepdown_probe(struct udevice *dev)
116 {
117 	struct dm_regulator_uclass_plat *uc_pdata;
118 
119 	uc_pdata = dev_get_uclass_plat(dev);
120 
121 	uc_pdata->type = REGULATOR_TYPE_BUCK;
122 
123 	return 0;
124 }
125 
as3722_ldo_probe(struct udevice * dev)126 static int as3722_ldo_probe(struct udevice *dev)
127 {
128 	struct dm_regulator_uclass_plat *uc_pdata;
129 
130 	uc_pdata = dev_get_uclass_plat(dev);
131 
132 	uc_pdata->type = REGULATOR_TYPE_LDO;
133 
134 	return 0;
135 }
136 
137 static const struct dm_regulator_ops as3722_stepdown_ops = {
138 	.get_value  = stepdown_get_value,
139 	.set_value  = stepdown_set_value,
140 	.get_enable = stepdown_get_enable,
141 	.set_enable = stepdown_set_enable,
142 };
143 
144 static const struct dm_regulator_ops as3722_ldo_ops = {
145 	.get_value  = ldo_get_value,
146 	.set_value  = ldo_set_value,
147 	.get_enable = ldo_get_enable,
148 	.set_enable = ldo_set_enable,
149 };
150 
151 U_BOOT_DRIVER(as3722_stepdown) = {
152 	.name = "as3722_stepdown",
153 	.id = UCLASS_REGULATOR,
154 	.ops = &as3722_stepdown_ops,
155 	.probe = as3722_stepdown_probe,
156 };
157 
158 U_BOOT_DRIVER(as3722_ldo) = {
159 	.name = "as3722_ldo",
160 	.id = UCLASS_REGULATOR,
161 	.ops = &as3722_ldo_ops,
162 	.probe = as3722_ldo_probe,
163 };
164