blob: e2219aad9713eb590ca7f10d80bd3bcb61b5bd2b [file] [log] [blame]
Padmanabhan Komandurudbd2fb02016-12-02 15:18:49 +05301/*
2 * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/of.h>
16#include <linux/delay.h>
17#include <linux/slab.h>
18
19#include "dsi_pwr.h"
20
21/*
22 * dsi_pwr_parse_supply_node() - parse power supply node from root device node
23 */
24static int dsi_pwr_parse_supply_node(struct device_node *root,
25 struct dsi_regulator_info *regs)
26{
27 int rc = 0;
28 int i = 0;
29 u32 tmp = 0;
30 struct device_node *node = NULL;
31
32 for_each_child_of_node(root, node) {
33 const char *st = NULL;
34
35 rc = of_property_read_string(node, "qcom,supply-name", &st);
36 if (rc) {
37 pr_err("failed to read name, rc = %d\n", rc);
38 goto error;
39 }
40
41 snprintf(regs->vregs[i].vreg_name,
42 ARRAY_SIZE(regs->vregs[i].vreg_name),
43 "%s", st);
44
45 rc = of_property_read_u32(node, "qcom,supply-min-voltage",
46 &tmp);
47 if (rc) {
48 pr_err("failed to read min voltage, rc = %d\n", rc);
49 goto error;
50 }
51 regs->vregs[i].min_voltage = tmp;
52
53 rc = of_property_read_u32(node, "qcom,supply-max-voltage",
54 &tmp);
55 if (rc) {
56 pr_err("failed to read max voltage, rc = %d\n", rc);
57 goto error;
58 }
59 regs->vregs[i].max_voltage = tmp;
60
61 rc = of_property_read_u32(node, "qcom,supply-enable-load",
62 &tmp);
63 if (rc) {
64 pr_err("failed to read enable load, rc = %d\n", rc);
65 goto error;
66 }
67 regs->vregs[i].enable_load = tmp;
68
69 rc = of_property_read_u32(node, "qcom,supply-disable-load",
70 &tmp);
71 if (rc) {
72 pr_err("failed to read disable load, rc = %d\n", rc);
73 goto error;
74 }
75 regs->vregs[i].disable_load = tmp;
76
77 /* Optional values */
78 rc = of_property_read_u32(node, "qcom,supply-pre-on-sleep",
79 &tmp);
80 if (rc) {
81 pr_debug("pre-on-sleep not specified\n");
82 rc = 0;
83 } else {
84 regs->vregs[i].pre_on_sleep = tmp;
85 }
86
87 rc = of_property_read_u32(node, "qcom,supply-pre-off-sleep",
88 &tmp);
89 if (rc) {
90 pr_debug("pre-off-sleep not specified\n");
91 rc = 0;
92 } else {
93 regs->vregs[i].pre_off_sleep = tmp;
94 }
95
96 rc = of_property_read_u32(node, "qcom,supply-post-on-sleep",
97 &tmp);
98 if (rc) {
99 pr_debug("post-on-sleep not specified\n");
100 rc = 0;
101 } else {
102 regs->vregs[i].post_on_sleep = tmp;
103 }
104
105 rc = of_property_read_u32(node, "qcom,supply-post-off-sleep",
106 &tmp);
107 if (rc) {
108 pr_debug("post-off-sleep not specified\n");
109 rc = 0;
110 } else {
111 regs->vregs[i].post_off_sleep = tmp;
112 }
113
114 ++i;
115 pr_debug("[%s] minv=%d maxv=%d, en_load=%d, dis_load=%d\n",
116 regs->vregs[i].vreg_name,
117 regs->vregs[i].min_voltage,
118 regs->vregs[i].max_voltage,
119 regs->vregs[i].enable_load,
120 regs->vregs[i].disable_load);
121 }
122
123error:
124 return rc;
125}
126
127/**
128 * dsi_pwr_enable_vregs() - enable/disable regulators
129 */
130static int dsi_pwr_enable_vregs(struct dsi_regulator_info *regs, bool enable)
131{
132 int rc = 0, i = 0;
133 struct dsi_vreg *vreg;
134 int num_of_v = 0;
135
136 if (enable) {
137 for (i = 0; i < regs->count; i++) {
138 vreg = &regs->vregs[i];
139 if (vreg->pre_on_sleep)
140 msleep(vreg->pre_on_sleep);
141
142 rc = regulator_set_load(vreg->vreg,
143 vreg->enable_load);
144 if (rc < 0) {
145 pr_err("Setting optimum mode failed for %s\n",
146 vreg->vreg_name);
147 goto error;
148 }
149 num_of_v = regulator_count_voltages(vreg->vreg);
150 if (num_of_v > 0) {
151 rc = regulator_set_voltage(vreg->vreg,
152 vreg->min_voltage,
153 vreg->max_voltage);
154 if (rc) {
155 pr_err("Set voltage(%s) fail, rc=%d\n",
156 vreg->vreg_name, rc);
157 goto error_disable_opt_mode;
158 }
159 }
160
161 rc = regulator_enable(vreg->vreg);
162 if (rc) {
163 pr_err("enable failed for %s, rc=%d\n",
164 vreg->vreg_name, rc);
165 goto error_disable_voltage;
166 }
167
168 if (vreg->post_on_sleep)
169 msleep(vreg->post_on_sleep);
170 }
171 } else {
172 for (i = (regs->count - 1); i >= 0; i--) {
173 if (regs->vregs[i].pre_off_sleep)
174 msleep(regs->vregs[i].pre_off_sleep);
175
176 (void)regulator_set_load(regs->vregs[i].vreg,
177 regs->vregs[i].disable_load);
178 (void)regulator_disable(regs->vregs[i].vreg);
179
180 if (regs->vregs[i].post_off_sleep)
181 msleep(regs->vregs[i].post_off_sleep);
182 }
183 }
184
185 return 0;
186error_disable_opt_mode:
187 (void)regulator_set_load(regs->vregs[i].vreg,
188 regs->vregs[i].disable_load);
189
190error_disable_voltage:
191 if (num_of_v > 0)
192 (void)regulator_set_voltage(regs->vregs[i].vreg,
193 0, regs->vregs[i].max_voltage);
194error:
195 for (i--; i >= 0; i--) {
196 if (regs->vregs[i].pre_off_sleep)
197 msleep(regs->vregs[i].pre_off_sleep);
198
199 (void)regulator_set_load(regs->vregs[i].vreg,
200 regs->vregs[i].disable_load);
201
202 num_of_v = regulator_count_voltages(regs->vregs[i].vreg);
203 if (num_of_v > 0)
204 (void)regulator_set_voltage(regs->vregs[i].vreg,
205 0, regs->vregs[i].max_voltage);
206
207 (void)regulator_disable(regs->vregs[i].vreg);
208
209 if (regs->vregs[i].post_off_sleep)
210 msleep(regs->vregs[i].post_off_sleep);
211 }
212
213 return rc;
214}
215
216/**
217* dsi_pwr_of_get_vreg_data - Parse regulator supply information
218* @of_node: Device of node to parse for supply information.
219* @regs: Pointer where regulator information will be copied to.
220* @supply_name: Name of the supply node.
221*
222* return: error code in case of failure or 0 for success.
223*/
224int dsi_pwr_of_get_vreg_data(struct device_node *of_node,
225 struct dsi_regulator_info *regs,
226 char *supply_name)
227{
228 int rc = 0;
229 struct device_node *supply_root_node = NULL;
230
231 if (!of_node || !regs) {
232 pr_err("Bad params\n");
233 return -EINVAL;
234 }
235
236 regs->count = 0;
237 supply_root_node = of_get_child_by_name(of_node, supply_name);
238 if (!supply_root_node) {
239 supply_root_node = of_parse_phandle(of_node, supply_name, 0);
240 if (!supply_root_node) {
Shashank Babu Chinta Venkatacf411332017-05-10 17:30:08 -0700241 pr_debug("No supply entry present for %s\n",
242 supply_name);
Padmanabhan Komandurudbd2fb02016-12-02 15:18:49 +0530243 return -EINVAL;
244 }
245 }
246
247 regs->count = of_get_available_child_count(supply_root_node);
248 if (regs->count == 0) {
249 pr_err("No vregs defined for %s\n", supply_name);
250 return -EINVAL;
251 }
252
253 regs->vregs = kcalloc(regs->count, sizeof(*regs->vregs), GFP_KERNEL);
254 if (!regs->vregs) {
255 regs->count = 0;
256 return -ENOMEM;
257 }
258
259 rc = dsi_pwr_parse_supply_node(supply_root_node, regs);
260 if (rc) {
261 pr_err("failed to parse supply node for %s, rc = %d\n",
262 supply_name, rc);
263
264 kfree(regs->vregs);
265 regs->vregs = NULL;
266 regs->count = 0;
267 }
268
269 return rc;
270}
271
272/**
273 * dsi_pwr_get_dt_vreg_data - parse regulator supply information
274 * @dev: Device whose of_node needs to be parsed.
275 * @regs: Pointer where regulator information will be copied to.
276 * @supply_name: Name of the supply node.
277 *
278 * return: error code in case of failure or 0 for success.
279 */
280int dsi_pwr_get_dt_vreg_data(struct device *dev,
281 struct dsi_regulator_info *regs,
282 char *supply_name)
283{
284 int rc = 0;
285 struct device_node *of_node = NULL;
286 struct device_node *supply_node = NULL;
287 struct device_node *supply_root_node = NULL;
288
289 if (!dev || !regs) {
290 pr_err("Bad params\n");
291 return -EINVAL;
292 }
293
294 of_node = dev->of_node;
295 regs->count = 0;
296 supply_root_node = of_get_child_by_name(of_node, supply_name);
297 if (!supply_root_node) {
298 supply_root_node = of_parse_phandle(of_node, supply_name, 0);
299 if (!supply_root_node) {
Shashank Babu Chinta Venkatacf411332017-05-10 17:30:08 -0700300 pr_debug("No supply entry present for %s\n",
301 supply_name);
Padmanabhan Komandurudbd2fb02016-12-02 15:18:49 +0530302 return -EINVAL;
303 }
304 }
305
306 for_each_child_of_node(supply_root_node, supply_node)
307 regs->count++;
308
309 if (regs->count == 0) {
310 pr_err("No vregs defined for %s\n", supply_name);
311 return -EINVAL;
312 }
313
314 regs->vregs = devm_kcalloc(dev, regs->count, sizeof(*regs->vregs),
315 GFP_KERNEL);
316 if (!regs->vregs) {
317 regs->count = 0;
318 return -ENOMEM;
319 }
320
321 rc = dsi_pwr_parse_supply_node(supply_root_node, regs);
322 if (rc) {
323 pr_err("failed to parse supply node for %s, rc = %d\n",
324 supply_name, rc);
325 devm_kfree(dev, regs->vregs);
326 regs->vregs = NULL;
327 regs->count = 0;
328 }
329
330 return rc;
331}
332
333/**
334 * dsi_pwr_enable_regulator() - enable a set of regulators
335 * @regs: Pointer to set of regulators to enable or disable.
336 * @enable: Enable/Disable regulators.
337 *
338 * return: error code in case of failure or 0 for success.
339 */
340int dsi_pwr_enable_regulator(struct dsi_regulator_info *regs, bool enable)
341{
342 int rc = 0;
343
344 if (enable) {
345 if (regs->refcount == 0) {
346 rc = dsi_pwr_enable_vregs(regs, true);
347 if (rc)
348 pr_err("failed to enable regulators\n");
349 }
350 regs->refcount++;
351 } else {
352 if (regs->refcount == 0) {
353 pr_err("Unbalanced regulator off\n");
354 } else {
355 regs->refcount--;
356 if (regs->refcount == 0) {
357 rc = dsi_pwr_enable_vregs(regs, false);
358 if (rc)
359 pr_err("failed to disable vregs\n");
360 }
361 }
362 }
363
364 return rc;
365}