blob: c012f373e80e9aead360d7c6e1c9c88c6b85b330 [file] [log] [blame]
David Collins8885f792017-01-26 14:36:34 -08001/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#define pr_fmt(fmt) "OLEDB: %s: " fmt, __func__
14
15#include <linux/delay.h>
16#include <linux/err.h>
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/module.h>
Kiran Gundab38cecc2017-02-13 19:55:40 +053020#include <linux/notifier.h>
David Collins8885f792017-01-26 14:36:34 -080021#include <linux/of.h>
22#include <linux/regmap.h>
23#include <linux/spmi.h>
24#include <linux/platform_device.h>
25#include <linux/regulator/driver.h>
26#include <linux/regulator/machine.h>
27#include <linux/regulator/of_regulator.h>
Kiran Gundab38cecc2017-02-13 19:55:40 +053028#include <linux/regulator/qpnp-labibb-regulator.h>
29#include <linux/qpnp/qpnp-pbs.h>
David Collins8885f792017-01-26 14:36:34 -080030
31#define QPNP_OLEDB_REGULATOR_DRIVER_NAME "qcom,qpnp-oledb-regulator"
32#define OLEDB_VOUT_STEP_MV 100
33#define OLEDB_VOUT_MIN_MV 5000
34#define OLEDB_VOUT_MAX_MV 8100
35#define OLEDB_VOUT_HW_DEFAULT 6400
36
37#define OLEDB_MODULE_RDY 0x45
38#define OLEDB_MODULE_RDY_BIT BIT(7)
39
40#define OLEDB_MODULE_ENABLE 0x46
41#define OLEDB_MODULE_ENABLE_BIT BIT(7)
42
43#define OLEDB_EXT_PIN_CTL 0x47
44#define OLEDB_EXT_PIN_CTL_BIT BIT(7)
45
46#define OLEDB_SWIRE_CONTROL 0x48
47#define OLEDB_EN_SWIRE_VOUT_UPD_BIT BIT(6)
48#define OLEDB_EN_SWIRE_PD_UPD_BIT BIT(7)
49
50#define OLEDB_VOUT_PGM 0x49
51#define OLEDB_VOUT_PGM_MASK GENMASK(4, 0)
52
53#define OLEDB_VOUT_DEFAULT 0x4A
54#define OLEDB_VOUT_DEFAULT_MASK GENMASK(4, 0)
55
56#define OLEDB_PD_CTL 0x4B
57
58#define OLEDB_ILIM_NFET 0x4E
59#define OLEDB_ILIMIT_NFET_MASK GENMASK(2, 0)
60
61#define OLEDB_BIAS_GEN_WARMUP_DELAY 0x52
62#define OLEDB_BIAS_GEN_WARMUP_DELAY_MASK GENMASK(1, 0)
63
64#define OLEDB_SHORT_PROTECT 0x59
65#define OLEDB_ENABLE_SC_DETECTION_BIT BIT(7)
66#define OLEDB_DBNC_SHORT_DETECTION_MASK GENMASK(1, 0)
67
68#define OLEDB_FAST_PRECHARGE 0x5A
69#define OLEDB_FAST_PRECHG_PPULSE_EN_BIT BIT(7)
70#define OLEDB_DBNC_PRECHARGE_MASK GENMASK(5, 4)
71#define OLEDB_DBNC_PRECHARGE_SHIFT 4
72#define OLEDB_PRECHARGE_PULSE_PERIOD_MASK GENMASK(3, 2)
73#define OLEDB_PRECHARGE_PULSE_PERIOD_SHIFT 2
74#define OLEDB_PRECHARGE_PULSE_TON_MASK GENMASK(1, 0)
75
76#define OLEDB_EN_PSM 0x5B
77#define OLEDB_PSM_ENABLE_BIT BIT(7)
78
79#define OLEDB_PSM_CTL 0x5C
80#define OLEDB_PSM_HYSTERYSIS_CTL_BIT BIT(3)
81#define OLEDB_PSM_HYSTERYSIS_CTL_BIT_SHIFT 3
82#define OLEDB_VREF_PSM_MASK GENMASK(2, 0)
83
84#define OLEDB_PFM_CTL 0x5D
85#define OLEDB_PFM_ENABLE_BIT BIT(7)
86#define OLEDB_PFM_HYSTERYSIS_CTRL_BIT_MASK BIT(4)
87#define OLEDB_PFM_HYSTERYSIS_CTL_BIT_SHIFT 4
88#define OLEDB_PFM_CURR_LIMIT_MASK GENMASK(3, 2)
89#define OLEDB_PFM_CURR_LIMIT_SHIFT 2
90#define OLEDB_PFM_OFF_TIME_NS_MASK GENMASK(1, 0)
91
92#define OLEDB_NLIMIT 0x64
93#define OLEDB_ENABLE_NLIMIT_BIT BIT(7)
94#define OLEDB_ENABLE_NLIMIT_BIT_SHIFT 7
95#define OLEDB_NLIMIT_PGM_MASK GENMASK(1, 0)
96
Kiran Gundab38cecc2017-02-13 19:55:40 +053097#define OLEDB_SPARE_CTL 0xE9
98#define OLEDB_FORCE_PD_CTL_SPARE_BIT BIT(7)
99
100#define OLEDB_PD_PBS_TRIGGER_BIT BIT(0)
101
102#define OLEDB_SEC_UNLOCK_CODE 0xA5
David Collins8885f792017-01-26 14:36:34 -0800103#define OLEDB_PSM_HYS_CTRL_MIN 13
104#define OLEDB_PSM_HYS_CTRL_MAX 26
105
106#define OLEDB_PFM_HYS_CTRL_MIN 13
107#define OLEDB_PFM_HYS_CTRL_MAX 26
108
109#define OLEDB_PFM_OFF_TIME_MIN 110
110#define OLEDB_PFM_OFF_TIME_MAX 480
111
112#define OLEDB_PRECHG_TIME_MIN 1
113#define OLEDB_PRECHG_TIME_MAX 8
114
115#define OLEDB_PRECHG_PULSE_PERIOD_MIN 3
116#define OLEDB_PRECHG_PULSE_PERIOD_MAX 12
117
118#define OLEDB_MIN_SC_DBNC_TIME_FSW 2
119#define OLEDB_MAX_SC_DBNC_TIME_FSW 16
120
121#define OLEDB_PRECHG_PULSE_ON_TIME_MIN 1200
122#define OLEDB_PRECHG_PULSE_ON_TIME_MAX 3000
123
124#define PSM_HYSTERYSIS_MV_TO_VAL(val_mv) ((val_mv/13) - 1)
125#define PFM_HYSTERYSIS_MV_TO_VAL(val_mv) ((val_mv/13) - 1)
126#define PFM_OFF_TIME_NS_TO_VAL(val_ns) ((val_ns/110) - 1)
127#define PRECHG_DEBOUNCE_TIME_MS_TO_VAL(val_ms) ((val_ms/2) - \
128 (val_ms/8))
129#define PRECHG_PULSE_PERIOD_US_TO_VAL(val_us) ((val_us/3) - 1)
130#define PRECHG_PULSE_ON_TIME_NS_TO_VAL(val_ns) (val_ns/600 - 2)
131#define SHORT_CIRCUIT_DEBOUNCE_TIME_TO_VAL(val) ((val/4) - (val/16))
132
133struct qpnp_oledb_psm_ctl {
134 int psm_enable;
135 int psm_hys_ctl;
136 int psm_vref;
137};
138
139struct qpnp_oledb_pfm_ctl {
140 int pfm_enable;
141 int pfm_hys_ctl;
142 int pfm_curr_limit;
143 int pfm_off_time;
144};
145
146struct qpnp_oledb_fast_precharge_ctl {
147 int fast_prechg_ppulse_en;
148 int prechg_debounce_time;
149 int prechg_pulse_period;
150 int prechg_pulse_on_time;
151};
152
153struct qpnp_oledb {
154 struct platform_device *pdev;
155 struct device *dev;
156 struct regmap *regmap;
157 struct regulator_desc rdesc;
158 struct regulator_dev *rdev;
159 struct qpnp_oledb_psm_ctl psm_ctl;
160 struct qpnp_oledb_pfm_ctl pfm_ctl;
161 struct qpnp_oledb_fast_precharge_ctl fast_prechg_ctl;
Kiran Gundab38cecc2017-02-13 19:55:40 +0530162 struct notifier_block oledb_nb;
163 struct mutex bus_lock;
164 struct device_node *pbs_dev_node;
David Collins8885f792017-01-26 14:36:34 -0800165
166 u32 base;
167 u8 mod_enable;
168 u8 ext_pinctl_state;
169 int current_voltage;
170 int default_voltage;
171 int vout_mv;
172 int warmup_delay;
173 int peak_curr_limit;
174 int pd_ctl;
175 int negative_curr_limit;
176 int nlimit_enable;
177 int sc_en;
178 int sc_dbnc_time;
179 bool swire_control;
180 bool ext_pin_control;
181 bool dynamic_ext_pinctl_config;
182 bool pbs_control;
Kiran Gundab38cecc2017-02-13 19:55:40 +0530183 bool force_pd_control;
David Collins8885f792017-01-26 14:36:34 -0800184};
185
186static const u16 oledb_warmup_dly_ns[] = {6700, 13300, 26700, 53400};
187static const u16 oledb_peak_curr_limit_ma[] = {115, 265, 415, 570,
188 720, 870, 1020, 1170};
189static const u16 oledb_psm_vref_mv[] = {440, 510, 580, 650, 715,
190 780, 850, 920};
191static const u16 oledb_pfm_curr_limit_ma[] = {130, 200, 270, 340};
192static const u16 oledb_nlimit_ma[] = {170, 300, 420, 550};
193
194static int qpnp_oledb_read(struct qpnp_oledb *oledb, u32 address,
195 u8 *val, int count)
196{
197 int rc = 0;
198 struct platform_device *pdev = oledb->pdev;
199
Kiran Gundab38cecc2017-02-13 19:55:40 +0530200 mutex_lock(&oledb->bus_lock);
David Collins8885f792017-01-26 14:36:34 -0800201 rc = regmap_bulk_read(oledb->regmap, address, val, count);
202 if (rc)
203 pr_err("Failed to read address=0x%02x sid=0x%02x rc=%d\n",
204 address, to_spmi_device(pdev->dev.parent)->usid, rc);
205
Kiran Gundab38cecc2017-02-13 19:55:40 +0530206 mutex_unlock(&oledb->bus_lock);
David Collins8885f792017-01-26 14:36:34 -0800207 return rc;
208}
209
210static int qpnp_oledb_masked_write(struct qpnp_oledb *oledb,
211 u32 address, u8 mask, u8 val)
212{
213 int rc;
214
Kiran Gundab38cecc2017-02-13 19:55:40 +0530215 mutex_lock(&oledb->bus_lock);
David Collins8885f792017-01-26 14:36:34 -0800216 rc = regmap_update_bits(oledb->regmap, address, mask, val);
217 if (rc < 0)
218 pr_err("Failed to write address 0x%04X, rc = %d\n",
219 address, rc);
220 else
221 pr_debug("Wrote 0x%02X to addr 0x%04X\n",
222 val, address);
223
Kiran Gundab38cecc2017-02-13 19:55:40 +0530224 mutex_unlock(&oledb->bus_lock);
225 return rc;
226}
227
228#define OLEDB_SEC_ACCESS 0xD0
229static int qpnp_oledb_sec_masked_write(struct qpnp_oledb *oledb, u16 address,
230 u8 mask, u8 val)
231{
232 int rc = 0;
233 u8 sec_val = OLEDB_SEC_UNLOCK_CODE;
234 u16 sec_reg_addr = (address & 0xFF00) | OLEDB_SEC_ACCESS;
235
236 mutex_lock(&oledb->bus_lock);
237 rc = regmap_write(oledb->regmap, sec_reg_addr, sec_val);
238 if (rc < 0) {
239 pr_err("register %x failed rc = %d\n", sec_reg_addr, rc);
240 goto error;
241 }
242
243 rc = regmap_update_bits(oledb->regmap, address, mask, val);
244 if (rc < 0)
245 pr_err("spmi write failed: addr=%03X, rc=%d\n", address, rc);
246
247error:
248 mutex_unlock(&oledb->bus_lock);
David Collins8885f792017-01-26 14:36:34 -0800249 return rc;
250}
251
252static int qpnp_oledb_write(struct qpnp_oledb *oledb, u16 address, u8 *val,
253 int count)
254{
255 int rc = 0;
256 struct platform_device *pdev = oledb->pdev;
257
Kiran Gundab38cecc2017-02-13 19:55:40 +0530258 mutex_lock(&oledb->bus_lock);
David Collins8885f792017-01-26 14:36:34 -0800259 rc = regmap_bulk_write(oledb->regmap, address, val, count);
260 if (rc)
261 pr_err("Failed to write address=0x%02x sid=0x%02x rc=%d\n",
262 address, to_spmi_device(pdev->dev.parent)->usid, rc);
263 else
264 pr_debug("Wrote 0x%02X to addr 0x%04X\n",
265 *val, address);
266
Kiran Gundab38cecc2017-02-13 19:55:40 +0530267 mutex_unlock(&oledb->bus_lock);
268 return rc;
David Collins8885f792017-01-26 14:36:34 -0800269}
270
271static int qpnp_oledb_regulator_enable(struct regulator_dev *rdev)
272{
273 int rc = 0;
274 u8 val = 0;
275
276 struct qpnp_oledb *oledb = rdev_get_drvdata(rdev);
277
278 if (oledb->ext_pin_control) {
279 rc = qpnp_oledb_read(oledb, oledb->base + OLEDB_EXT_PIN_CTL,
280 &val, 1);
281 if (rc < 0) {
282 pr_err("Failed to read EXT_PIN_CTL rc=%d\n", rc);
283 return rc;
284 }
285
286 /*
287 * Enable ext-pin-ctl after display-supply is turned on.
288 * This is to avoid glitches on the external pin.
289 */
290 if (!(val & OLEDB_EXT_PIN_CTL_BIT) &&
291 oledb->dynamic_ext_pinctl_config) {
292 val = OLEDB_EXT_PIN_CTL_BIT;
293 rc = qpnp_oledb_write(oledb, oledb->base +
294 OLEDB_EXT_PIN_CTL, &val, 1);
295 if (rc < 0) {
296 pr_err("Failed to write EXT_PIN_CTL rc=%d\n",
297 rc);
298 return rc;
299 }
300 }
301 pr_debug("ext-pin-ctrl mode enabled\n");
302 } else {
303 val = OLEDB_MODULE_ENABLE_BIT;
304 rc = qpnp_oledb_write(oledb, oledb->base + OLEDB_MODULE_ENABLE,
305 &val, 1);
306 if (rc < 0) {
307 pr_err("Failed to write MODULE_ENABLE rc=%d\n", rc);
308 return rc;
309 }
310
311 ndelay(oledb->warmup_delay);
312 pr_debug("register-control mode, module enabled\n");
313 }
314
315 oledb->mod_enable = true;
316 if (oledb->pbs_control) {
317 rc = qpnp_oledb_masked_write(oledb, oledb->base +
318 OLEDB_SWIRE_CONTROL, OLEDB_EN_SWIRE_PD_UPD_BIT |
319 OLEDB_EN_SWIRE_VOUT_UPD_BIT, 0);
320 if (rc < 0)
321 pr_err("Failed to write SWIRE_CTL for pbs mode rc=%d\n",
322 rc);
323 }
324
325 return rc;
326}
327
328static int qpnp_oledb_regulator_disable(struct regulator_dev *rdev)
329{
330 int rc = 0;
Kiran Gundab38cecc2017-02-13 19:55:40 +0530331 u8 trigger_bitmap = OLEDB_PD_PBS_TRIGGER_BIT;
332 u8 val;
David Collins8885f792017-01-26 14:36:34 -0800333
334 struct qpnp_oledb *oledb = rdev_get_drvdata(rdev);
335
336 /*
337 * Disable ext-pin-ctl after display-supply is turned off. This is to
338 * avoid glitches on the external pin.
339 */
340 if (oledb->ext_pin_control) {
341 if (oledb->dynamic_ext_pinctl_config) {
342 rc = qpnp_oledb_masked_write(oledb, oledb->base +
343 OLEDB_EXT_PIN_CTL, OLEDB_EXT_PIN_CTL_BIT, 0);
344 if (rc < 0) {
345 pr_err("Failed to write EXT_PIN_CTL rc=%d\n",
346 rc);
347 return rc;
348 }
349 }
350 pr_debug("ext-pin-ctrl mode disabled\n");
351 } else {
352 rc = qpnp_oledb_masked_write(oledb, oledb->base +
353 OLEDB_MODULE_ENABLE,
354 OLEDB_MODULE_ENABLE_BIT, 0);
355 if (rc < 0) {
356 pr_err("Failed to write MODULE_ENABLE rc=%d\n", rc);
357 return rc;
358 }
359 pr_debug("Register-control mode, module disabled\n");
360 }
361
Kiran Gundab38cecc2017-02-13 19:55:40 +0530362 if (oledb->force_pd_control) {
363 rc = qpnp_oledb_read(oledb, oledb->base + OLEDB_SPARE_CTL,
364 &val, 1);
365 if (rc < 0) {
366 pr_err("Failed to read OLEDB_SPARE_CTL rc=%d\n", rc);
367 return rc;
368 }
369
370 if (val & OLEDB_FORCE_PD_CTL_SPARE_BIT) {
371 rc = qpnp_pbs_trigger_event(oledb->pbs_dev_node,
372 trigger_bitmap);
373 if (rc < 0) {
374 pr_err("Failed to trigger the PBS sequence\n");
375 return rc;
376 }
377 pr_debug("PBS event triggered\n");
378 } else {
379 pr_debug("OLEDB_SPARE_CTL register bit not set\n");
380 }
381 }
382
David Collins8885f792017-01-26 14:36:34 -0800383 oledb->mod_enable = false;
384
385 return rc;
386}
387
388static int qpnp_oledb_regulator_is_enabled(struct regulator_dev *rdev)
389{
390 struct qpnp_oledb *oledb = rdev_get_drvdata(rdev);
391
392 return oledb->mod_enable;
393}
394
395static int qpnp_oledb_regulator_set_voltage(struct regulator_dev *rdev,
396 int min_uV, int max_uV, unsigned int *selector)
397{
398 u8 val;
399 int rc = 0;
400
401 struct qpnp_oledb *oledb = rdev_get_drvdata(rdev);
402
403 if (oledb->swire_control)
404 return 0;
405
406 val = DIV_ROUND_UP(min_uV - OLEDB_VOUT_MIN_MV, OLEDB_VOUT_STEP_MV);
407
408 rc = qpnp_oledb_write(oledb, oledb->base + OLEDB_VOUT_PGM,
409 &val, 1);
410 if (rc < 0) {
411 pr_err("Failed to write VOUT_PGM rc=%d\n", rc);
412 return rc;
413 }
414
415 oledb->current_voltage = min_uV;
416 pr_debug("register-control mode, current voltage %d\n",
417 oledb->current_voltage);
418
419 return 0;
420}
421
422static int qpnp_oledb_regulator_get_voltage(struct regulator_dev *rdev)
423{
424 struct qpnp_oledb *oledb = rdev_get_drvdata(rdev);
425
426 if (oledb->swire_control)
427 return 0;
428
429 return oledb->current_voltage;
430}
431
432static struct regulator_ops qpnp_oledb_ops = {
433 .enable = qpnp_oledb_regulator_enable,
434 .disable = qpnp_oledb_regulator_disable,
435 .is_enabled = qpnp_oledb_regulator_is_enabled,
436 .set_voltage = qpnp_oledb_regulator_set_voltage,
437 .get_voltage = qpnp_oledb_regulator_get_voltage,
438};
439
440static int qpnp_oledb_register_regulator(struct qpnp_oledb *oledb)
441{
442 int rc = 0;
443 struct platform_device *pdev = oledb->pdev;
444 struct regulator_init_data *init_data;
445 struct regulator_desc *rdesc = &oledb->rdesc;
446 struct regulator_config cfg = {};
447
448 init_data = of_get_regulator_init_data(&pdev->dev,
449 pdev->dev.of_node, rdesc);
450 if (!init_data) {
451 pr_err("Unable to get OLEDB regulator init data\n");
452 return -ENOMEM;
453 }
454
455 if (init_data->constraints.name) {
456 rdesc->owner = THIS_MODULE;
457 rdesc->type = REGULATOR_VOLTAGE;
458 rdesc->ops = &qpnp_oledb_ops;
459 rdesc->name = init_data->constraints.name;
460
461 cfg.dev = &pdev->dev;
462 cfg.init_data = init_data;
463 cfg.driver_data = oledb;
464 cfg.of_node = pdev->dev.of_node;
465
466 if (of_get_property(pdev->dev.of_node, "parent-supply",
467 NULL))
468 init_data->supply_regulator = "parent";
469
470 init_data->constraints.valid_ops_mask
471 |= REGULATOR_CHANGE_VOLTAGE |
472 REGULATOR_CHANGE_STATUS;
473
474 oledb->rdev = devm_regulator_register(oledb->dev, rdesc, &cfg);
475 if (IS_ERR(oledb->rdev)) {
476 rc = PTR_ERR(oledb->rdev);
477 oledb->rdev = NULL;
478 pr_err("Unable to register OLEDB regulator, rc = %d\n",
479 rc);
480 return rc;
481 }
482 } else {
483 pr_err("OLEDB regulator name missing\n");
484 return -EINVAL;
485 }
486
487 return 0;
488}
489
490static int qpnp_oledb_get_curr_voltage(struct qpnp_oledb *oledb,
491 u16 *current_voltage)
492{
493 int rc = 0;
494 u8 val;
495
496 if (!(oledb->mod_enable || oledb->ext_pinctl_state)) {
497 rc = qpnp_oledb_read(oledb, oledb->base + OLEDB_VOUT_DEFAULT,
498 &val, 1);
499 if (rc < 0) {
500 pr_err("Failed to read VOUT_DEFAULT rc=%d\n", rc);
501 return rc;
502 }
503 } else {
504 rc = qpnp_oledb_read(oledb, oledb->base +
505 OLEDB_VOUT_PGM, &val, 1);
506 if (rc < 0) {
507 pr_err("Failed to read VOUT_PGM rc=%d\n", rc);
508 return rc;
509 }
510 }
511
512 *current_voltage = (val * OLEDB_VOUT_STEP_MV) + OLEDB_VOUT_MIN_MV;
513
514 return rc;
515}
516
517static int qpnp_oledb_init_nlimit(struct qpnp_oledb *oledb)
518{
519 int rc = 0, i = 0;
520 u32 val, mask = 0;
521
522 if (oledb->nlimit_enable != -EINVAL) {
523 val = oledb->nlimit_enable <<
524 OLEDB_ENABLE_NLIMIT_BIT_SHIFT;
525 mask = OLEDB_ENABLE_NLIMIT_BIT;
526 if (oledb->negative_curr_limit != -EINVAL) {
527 for (i = 0; i < ARRAY_SIZE(oledb_nlimit_ma); i++) {
528 if (oledb->negative_curr_limit ==
529 oledb_nlimit_ma[i])
530 break;
531 }
532 val |= i;
533 mask |= OLEDB_NLIMIT_PGM_MASK;
534 }
535 rc = qpnp_oledb_masked_write(oledb, oledb->base +
536 OLEDB_NLIMIT, mask, val);
537 if (rc < 0)
538 pr_err("Failed to write NLIMT rc=%d\n", rc);
539 }
540
541 return rc;
542}
543
544static int qpnp_oledb_init_psm(struct qpnp_oledb *oledb)
545{
546 int rc = 0, i = 0;
547 u32 val = 0, mask = 0, temp = 0;
548 struct qpnp_oledb_psm_ctl *psm_ctl = &oledb->psm_ctl;
549
550 if (psm_ctl->psm_enable == -EINVAL)
551 return rc;
552
553 if (psm_ctl->psm_enable) {
554 val = OLEDB_PSM_ENABLE_BIT;
555 rc = qpnp_oledb_masked_write(oledb, oledb->base +
556 OLEDB_EN_PSM, OLEDB_PSM_ENABLE_BIT, val);
557 if (rc < 0) {
558 pr_err("Failed to write PSM_EN rc=%d\n", rc);
559 return rc;
560 }
561
562 val = 0;
563 if (psm_ctl->psm_vref != -EINVAL) {
564 for (i = 0; i < ARRAY_SIZE(oledb_psm_vref_mv); i++) {
565 if (psm_ctl->psm_vref ==
566 oledb_psm_vref_mv[i])
567 break;
568 }
569 val = i;
570 mask = OLEDB_VREF_PSM_MASK;
571 }
572
573 if (psm_ctl->psm_hys_ctl != -EINVAL) {
574 temp = PSM_HYSTERYSIS_MV_TO_VAL(psm_ctl->psm_hys_ctl);
575 val |= (temp << OLEDB_PSM_HYSTERYSIS_CTL_BIT_SHIFT);
576 mask |= OLEDB_PSM_HYSTERYSIS_CTL_BIT;
577 }
578 if (val) {
579 rc = qpnp_oledb_masked_write(oledb, oledb->base +
580 OLEDB_PSM_CTL, mask, val);
581 if (rc < 0)
582 pr_err("Failed to write PSM_CTL rc=%d\n", rc);
583 }
584 } else {
585 rc = qpnp_oledb_masked_write(oledb, oledb->base +
586 OLEDB_EN_PSM, OLEDB_PSM_ENABLE_BIT, 0);
587 if (rc < 0)
588 pr_err("Failed to write PSM_CTL rc=%d\n", rc);
589 }
590
591 return rc;
592}
593
594static int qpnp_oledb_init_pfm(struct qpnp_oledb *oledb)
595{
596 int rc = 0, i = 0;
597 u32 val = 0, temp = 0, mask = 0;
598 struct qpnp_oledb_pfm_ctl *pfm_ctl = &oledb->pfm_ctl;
599
600 if (pfm_ctl->pfm_enable == -EINVAL)
601 return rc;
602
603 if (pfm_ctl->pfm_enable) {
604 mask = val = OLEDB_PFM_ENABLE_BIT;
605 if (pfm_ctl->pfm_hys_ctl != -EINVAL) {
606 temp = PFM_HYSTERYSIS_MV_TO_VAL(pfm_ctl->pfm_hys_ctl);
607 val |= temp <<
608 OLEDB_PFM_HYSTERYSIS_CTL_BIT_SHIFT;
609 mask |= OLEDB_PFM_HYSTERYSIS_CTRL_BIT_MASK;
610 }
611
612 if (pfm_ctl->pfm_curr_limit != -EINVAL) {
613 for (i = 0; i < ARRAY_SIZE(oledb_pfm_curr_limit_ma);
614 i++) {
615 if (pfm_ctl->pfm_curr_limit ==
616 oledb_pfm_curr_limit_ma[i])
617 break;
618 }
619 val |= (i << OLEDB_PFM_CURR_LIMIT_SHIFT);
620 mask |= OLEDB_PFM_CURR_LIMIT_MASK;
621 }
622
623 if (pfm_ctl->pfm_off_time != -EINVAL) {
624 val |= PFM_OFF_TIME_NS_TO_VAL(pfm_ctl->pfm_off_time);
625 mask |= OLEDB_PFM_OFF_TIME_NS_MASK;
626 }
627
628 rc = qpnp_oledb_masked_write(oledb, oledb->base +
629 OLEDB_PFM_CTL, mask, val);
630 if (rc < 0)
631 pr_err("Failed to write PFM_CTL rc=%d\n", rc);
632 } else {
633 rc = qpnp_oledb_masked_write(oledb, oledb->base +
634 OLEDB_PFM_CTL, OLEDB_PFM_ENABLE_BIT, 0);
635 if (rc < 0)
636 pr_err("Failed to write PFM_CTL rc=%d\n", rc);
637 }
638
639 return rc;
640}
641
642static int qpnp_oledb_init_fast_precharge(struct qpnp_oledb *oledb)
643{
644 int rc = 0;
645 u32 val = 0, temp = 0, mask = 0;
646 struct qpnp_oledb_fast_precharge_ctl *prechg_ctl =
647 &oledb->fast_prechg_ctl;
648
649 if (prechg_ctl->fast_prechg_ppulse_en == -EINVAL)
650 return rc;
651
652 if (prechg_ctl->fast_prechg_ppulse_en) {
653 mask = val = OLEDB_FAST_PRECHG_PPULSE_EN_BIT;
654 if (prechg_ctl->prechg_debounce_time != -EINVAL) {
655 temp = PRECHG_DEBOUNCE_TIME_MS_TO_VAL(
656 prechg_ctl->prechg_debounce_time);
657 val |= temp << OLEDB_DBNC_PRECHARGE_SHIFT;
658 mask |= OLEDB_DBNC_PRECHARGE_MASK;
659 }
660
661 if (prechg_ctl->prechg_pulse_period != -EINVAL) {
662 temp = PRECHG_PULSE_PERIOD_US_TO_VAL(
663 prechg_ctl->prechg_pulse_period);
664 val |= temp << OLEDB_PRECHARGE_PULSE_PERIOD_SHIFT;
665 mask |= OLEDB_PRECHARGE_PULSE_PERIOD_MASK;
666 }
667
668 if (prechg_ctl->prechg_pulse_on_time != -EINVAL) {
669 val |= PRECHG_PULSE_ON_TIME_NS_TO_VAL(
670 prechg_ctl->prechg_pulse_on_time);
671 mask |= OLEDB_PRECHARGE_PULSE_TON_MASK;
672 }
673
674 rc = qpnp_oledb_masked_write(oledb, oledb->base +
675 OLEDB_FAST_PRECHARGE, mask, val);
676 if (rc < 0)
677 pr_err("Failed to write FAST_PRECHARGE rc=%d\n", rc);
678 } else {
679 rc = qpnp_oledb_masked_write(oledb, oledb->base +
680 OLEDB_FAST_PRECHARGE,
681 OLEDB_FAST_PRECHG_PPULSE_EN_BIT, 0);
682 if (rc < 0)
683 pr_err("Failed to write FAST_PRECHARGE rc=%d\n", rc);
684 }
685
686 return rc;
687}
688
689static int qpnp_oledb_hw_init(struct qpnp_oledb *oledb)
690{
691 int rc, i = 0;
692 u8 val = 0, mask = 0;
693 u16 current_voltage;
694
695 if (oledb->default_voltage != -EINVAL) {
696 val = (oledb->default_voltage - OLEDB_VOUT_MIN_MV) /
697 OLEDB_VOUT_STEP_MV;
698 rc = qpnp_oledb_write(oledb, oledb->base +
699 OLEDB_VOUT_DEFAULT, &val, 1);
700 if (rc < 0) {
701 pr_err("Failed to write VOUT_DEFAULT rc=%d\n", rc);
702 return rc;
703 }
704 }
705
706 rc = qpnp_oledb_read(oledb, oledb->base + OLEDB_MODULE_ENABLE,
707 &oledb->mod_enable, 1);
708 if (rc < 0) {
709 pr_err("Failed to read MODULE_ENABLE rc=%d\n", rc);
710 return rc;
711 }
712
713 rc = qpnp_oledb_read(oledb, oledb->base + OLEDB_EXT_PIN_CTL,
714 &oledb->ext_pinctl_state, 1);
715 if (rc < 0) {
716 pr_err("Failed to read EXT_PIN_CTL rc=%d\n", rc);
717 return rc;
718 }
719
720 rc = qpnp_oledb_get_curr_voltage(oledb, &current_voltage);
721 if (rc < 0)
722 return rc;
723
724 /*
725 * Go through if the module is not enabled either through
726 * external pin control or SPMI interface.
727 */
728 if (!((oledb->ext_pinctl_state & OLEDB_EXT_PIN_CTL_BIT)
729 || oledb->mod_enable)) {
730 if (oledb->warmup_delay != -EINVAL) {
731 for (i = 0; i < ARRAY_SIZE(oledb_warmup_dly_ns); i++) {
732 if (oledb->warmup_delay ==
733 oledb_warmup_dly_ns[i])
734 break;
735 }
736 val = i;
737 rc = qpnp_oledb_masked_write(oledb,
738 oledb->base + OLEDB_BIAS_GEN_WARMUP_DELAY,
739 OLEDB_BIAS_GEN_WARMUP_DELAY_MASK, val);
740 if (rc < 0) {
741 pr_err("Failed to write WARMUP_DELAY rc=%d\n",
742 rc);
743 return rc;
744 }
745 } else {
746 rc = qpnp_oledb_read(oledb, oledb->base +
747 OLEDB_BIAS_GEN_WARMUP_DELAY,
748 &val, 1);
749 if (rc < 0) {
750 pr_err("Failed to read WARMUP_DELAY rc=%d\n",
751 rc);
752 return rc;
753 }
754 oledb->warmup_delay = oledb_warmup_dly_ns[val];
755 }
756
757 if (oledb->peak_curr_limit != -EINVAL) {
758 for (i = 0; i < ARRAY_SIZE(oledb_peak_curr_limit_ma);
759 i++) {
760 if (oledb->peak_curr_limit ==
761 oledb_peak_curr_limit_ma[i])
762 break;
763 }
764 val = i;
765 rc = qpnp_oledb_write(oledb,
766 oledb->base + OLEDB_ILIM_NFET,
767 &val, 1);
768 if (rc < 0) {
769 pr_err("Failed to write ILIM_NEFT rc=%d\n", rc);
770 return rc;
771 }
772 }
773
774 if (oledb->pd_ctl != -EINVAL) {
775 val = oledb->pd_ctl;
776 rc = qpnp_oledb_write(oledb, oledb->base +
777 OLEDB_PD_CTL, &val, 1);
778 if (rc < 0) {
779 pr_err("Failed to write PD_CTL rc=%d\n", rc);
780 return rc;
781 }
782 }
783
784 if (oledb->sc_en != -EINVAL) {
785 val = oledb->sc_en ? OLEDB_ENABLE_SC_DETECTION_BIT : 0;
786 mask = OLEDB_ENABLE_SC_DETECTION_BIT;
787 if (oledb->sc_dbnc_time != -EINVAL) {
788 val |= SHORT_CIRCUIT_DEBOUNCE_TIME_TO_VAL(
789 oledb->sc_dbnc_time);
790 mask |= OLEDB_DBNC_PRECHARGE_MASK;
791 }
792
793 rc = qpnp_oledb_write(oledb, oledb->base +
794 OLEDB_SHORT_PROTECT, &val, 1);
795 if (rc < 0) {
796 pr_err("Failed to write SHORT_PROTECT rc=%d\n",
797 rc);
798 return rc;
799 }
800 }
801
802 rc = qpnp_oledb_init_nlimit(oledb);
803 if (rc < 0)
804 return rc;
805
806 rc = qpnp_oledb_init_psm(oledb);
807 if (rc < 0)
808 return rc;
809
810 rc = qpnp_oledb_init_pfm(oledb);
811 if (rc < 0)
812 return rc;
813
814 rc = qpnp_oledb_init_fast_precharge(oledb);
815 if (rc < 0)
816 return rc;
817
818 if (oledb->swire_control) {
819 val = OLEDB_EN_SWIRE_PD_UPD_BIT |
820 OLEDB_EN_SWIRE_VOUT_UPD_BIT;
821 rc = qpnp_oledb_masked_write(oledb, oledb->base +
822 OLEDB_SWIRE_CONTROL, OLEDB_EN_SWIRE_PD_UPD_BIT |
823 OLEDB_EN_SWIRE_VOUT_UPD_BIT, val);
824 if (rc < 0)
825 return rc;
826 }
827
828 rc = qpnp_oledb_read(oledb, oledb->base + OLEDB_MODULE_RDY,
829 &val, 1);
830 if (rc < 0) {
831 pr_err("Failed to read MODULE_RDY rc=%d\n", rc);
832 return rc;
833 }
834
835 if (!(val & OLEDB_MODULE_RDY_BIT)) {
836 val = OLEDB_MODULE_RDY_BIT;
837 rc = qpnp_oledb_write(oledb, oledb->base +
838 OLEDB_MODULE_RDY, &val, 1);
839 if (rc < 0) {
840 pr_err("Failed to write MODULE_RDY rc=%d\n",
841 rc);
842 return rc;
843 }
844 }
845
846 if (!oledb->dynamic_ext_pinctl_config) {
847 if (oledb->ext_pin_control) {
848 val = OLEDB_EXT_PIN_CTL_BIT;
849 rc = qpnp_oledb_write(oledb, oledb->base +
850 OLEDB_EXT_PIN_CTL, &val, 1);
851 if (rc < 0) {
852 pr_err("Failed to write EXT_PIN_CTL rc=%d\n",
853 rc);
854 return rc;
855 }
856 } else {
857 val = OLEDB_MODULE_ENABLE_BIT;
858 rc = qpnp_oledb_write(oledb, oledb->base +
859 OLEDB_MODULE_ENABLE, &val, 1);
860 if (rc < 0) {
861 pr_err("Failed to write MODULE_ENABLE rc=%d\n",
862 rc);
863 return rc;
864 }
865
866 ndelay(oledb->warmup_delay);
867 }
868
869 oledb->mod_enable = true;
870 if (oledb->pbs_control) {
871 rc = qpnp_oledb_masked_write(oledb,
872 oledb->base + OLEDB_SWIRE_CONTROL,
873 OLEDB_EN_SWIRE_PD_UPD_BIT |
874 OLEDB_EN_SWIRE_VOUT_UPD_BIT, 0);
875 if (rc < 0) {
876 pr_err("Failed to write SWIRE_CTL rc=%d\n",
877 rc);
878 return rc;
879 }
880 }
881 }
882
883 oledb->current_voltage = current_voltage;
884 } else {
885 /* module is enabled */
886 if (oledb->current_voltage == -EINVAL) {
887 oledb->current_voltage = current_voltage;
888 } else if (!oledb->swire_control) {
889 if (oledb->current_voltage < OLEDB_VOUT_MIN_MV) {
890 pr_err("current_voltage %d is less than min_volt %d\n",
891 oledb->current_voltage, OLEDB_VOUT_MIN_MV);
892 return -EINVAL;
893 }
894 val = DIV_ROUND_UP(oledb->current_voltage -
895 OLEDB_VOUT_MIN_MV, OLEDB_VOUT_STEP_MV);
896 rc = qpnp_oledb_write(oledb, oledb->base +
897 OLEDB_VOUT_PGM, &val, 1);
898 if (rc < 0) {
899 pr_err("Failed to write VOUT_PGM rc=%d\n",
900 rc);
901 return rc;
902 }
903 }
904
905 oledb->mod_enable = true;
906 }
907
908 return rc;
909}
910
911static int qpnp_oledb_parse_nlimit(struct qpnp_oledb *oledb)
912{
913 int rc = 0;
914 struct device_node *of_node = oledb->dev->of_node;
915
916 oledb->nlimit_enable = -EINVAL;
917 rc = of_property_read_u32(of_node, "qcom,negative-curr-limit-enable",
918 &oledb->nlimit_enable);
919 if (!rc) {
920 oledb->negative_curr_limit = -EINVAL;
921 rc = of_property_read_u32(of_node,
922 "qcom,negative-curr-limit-ma",
923 &oledb->negative_curr_limit);
924 if (!rc) {
925 u16 min_curr_limit = oledb_nlimit_ma[0];
926 u16 max_curr_limit = oledb_nlimit_ma[ARRAY_SIZE(
927 oledb_nlimit_ma) - 1];
928 if (oledb->negative_curr_limit < min_curr_limit ||
929 oledb->negative_curr_limit > max_curr_limit) {
930 pr_err("Invalid value in qcom,negative-curr-limit-ma\n");
931 return -EINVAL;
932 }
933 }
934 }
935
936 return 0;
937}
938
939static int qpnp_oledb_parse_psm(struct qpnp_oledb *oledb)
940{
941 int rc = 0;
942 struct qpnp_oledb_psm_ctl *psm_ctl = &oledb->psm_ctl;
943 struct device_node *of_node = oledb->dev->of_node;
944
945 psm_ctl->psm_enable = -EINVAL;
946 rc = of_property_read_u32(of_node, "qcom,psm-enable",
947 &psm_ctl->psm_enable);
948 if (!rc) {
949 psm_ctl->psm_hys_ctl = -EINVAL;
950 rc = of_property_read_u32(of_node, "qcom,psm-hys-mv",
951 &psm_ctl->psm_hys_ctl);
952 if (!rc) {
953 if (psm_ctl->psm_hys_ctl < OLEDB_PSM_HYS_CTRL_MIN ||
954 psm_ctl->psm_hys_ctl > OLEDB_PSM_HYS_CTRL_MAX) {
955 pr_err("Invalid value in qcom,psm-hys-mv\n");
956 return -EINVAL;
957 }
958 }
959
960 psm_ctl->psm_vref = -EINVAL;
961 rc = of_property_read_u32(of_node, "qcom,psm-vref-mv",
962 &psm_ctl->psm_vref);
963 if (!rc) {
964 u16 min_vref = oledb_psm_vref_mv[0];
965 u16 max_vref = oledb_psm_vref_mv[ARRAY_SIZE(
966 oledb_psm_vref_mv) - 1];
967 if (psm_ctl->psm_vref < min_vref ||
968 psm_ctl->psm_vref > max_vref) {
969 pr_err("Invalid value in qcom,psm-vref-mv\n");
970 return -EINVAL;
971 }
972 }
973 }
974
975 return 0;
976}
977
978static int qpnp_oledb_parse_pfm(struct qpnp_oledb *oledb)
979{
980 int rc = 0;
981 struct qpnp_oledb_pfm_ctl *pfm_ctl = &oledb->pfm_ctl;
982 struct device_node *of_node = oledb->dev->of_node;
983
984 pfm_ctl->pfm_enable = -EINVAL;
985 rc = of_property_read_u32(of_node, "qcom,pfm-enable",
986 &pfm_ctl->pfm_enable);
987 if (!rc) {
988 pfm_ctl->pfm_hys_ctl = -EINVAL;
989 rc = of_property_read_u32(of_node, "qcom,pfm-hys-mv",
990 &pfm_ctl->pfm_hys_ctl);
991 if (!rc) {
992 if (pfm_ctl->pfm_hys_ctl < OLEDB_PFM_HYS_CTRL_MIN ||
993 pfm_ctl->pfm_hys_ctl > OLEDB_PFM_HYS_CTRL_MAX) {
994 pr_err("Invalid value in qcom,pfm-hys-mv\n");
995 return -EINVAL;
996 }
997 }
998
999 pfm_ctl->pfm_curr_limit = -EINVAL;
1000 rc = of_property_read_u32(of_node,
1001 "qcom,pfm-curr-limit-ma", &pfm_ctl->pfm_curr_limit);
1002 if (!rc) {
1003 u16 min_limit = oledb_pfm_curr_limit_ma[0];
1004 u16 max_limit = oledb_pfm_curr_limit_ma[ARRAY_SIZE(
1005 oledb_pfm_curr_limit_ma) - 1];
1006 if (pfm_ctl->pfm_curr_limit < min_limit ||
1007 pfm_ctl->pfm_curr_limit > max_limit) {
1008 pr_err("Invalid value in qcom,pfm-curr-limit-ma\n");
1009 return -EINVAL;
1010 }
1011 }
1012
1013 pfm_ctl->pfm_off_time = -EINVAL;
1014 rc = of_property_read_u32(of_node, "qcom,pfm-off-time-ns",
1015 &pfm_ctl->pfm_off_time);
1016 if (!rc) {
1017 if (pfm_ctl->pfm_off_time < OLEDB_PFM_OFF_TIME_MIN ||
1018 pfm_ctl->pfm_off_time > OLEDB_PFM_OFF_TIME_MAX) {
1019 pr_err("Invalid value in qcom,pfm-off-time-ns\n");
1020 return -EINVAL;
1021 }
1022 }
1023 }
1024
1025 return 0;
1026}
1027
1028static int qpnp_oledb_parse_fast_precharge(struct qpnp_oledb *oledb)
1029{
1030 int rc = 0;
1031 struct device_node *of_node = oledb->dev->of_node;
1032 struct qpnp_oledb_fast_precharge_ctl *fast_prechg =
1033 &oledb->fast_prechg_ctl;
1034
1035 fast_prechg->fast_prechg_ppulse_en = -EINVAL;
1036 rc = of_property_read_u32(of_node, "qcom,fast-precharge-ppulse-enable",
1037 &fast_prechg->fast_prechg_ppulse_en);
1038 if (!rc) {
1039 fast_prechg->prechg_debounce_time = -EINVAL;
1040 rc = of_property_read_u32(of_node,
1041 "qcom,precharge-debounce-time-ms",
1042 &fast_prechg->prechg_debounce_time);
1043 if (!rc) {
1044 int dbnc_time = fast_prechg->prechg_debounce_time;
1045
1046 if (dbnc_time < OLEDB_PRECHG_TIME_MIN || dbnc_time >
1047 OLEDB_PRECHG_TIME_MAX) {
1048 pr_err("Invalid value in qcom,precharge-debounce-time-ms\n");
1049 return -EINVAL;
1050 }
1051 }
1052
1053 fast_prechg->prechg_pulse_period = -EINVAL;
1054 rc = of_property_read_u32(of_node,
1055 "qcom,precharge-pulse-period-us",
1056 &fast_prechg->prechg_pulse_period);
1057 if (!rc) {
1058 int pulse_period = fast_prechg->prechg_pulse_period;
1059
1060 if (pulse_period < OLEDB_PRECHG_PULSE_PERIOD_MIN ||
1061 pulse_period > OLEDB_PRECHG_PULSE_PERIOD_MAX) {
1062 pr_err("Invalid value in qcom,precharge-pulse-period-us\n");
1063 return -EINVAL;
1064 }
1065 }
1066
1067 fast_prechg->prechg_pulse_on_time = -EINVAL;
1068 rc = of_property_read_u32(of_node,
1069 "qcom,precharge-pulse-on-time-ns",
1070 &fast_prechg->prechg_pulse_on_time);
1071 if (!rc) {
1072 int pulse_on_time = fast_prechg->prechg_pulse_on_time;
1073
1074 if (pulse_on_time < OLEDB_PRECHG_PULSE_ON_TIME_MIN ||
1075 pulse_on_time > OLEDB_PRECHG_PULSE_ON_TIME_MAX) {
1076 pr_err("Invalid value in qcom,precharge-pulse-on-time-ns\n");
1077 return -EINVAL;
1078 }
1079 }
1080 }
1081
1082 return 0;
1083}
1084
1085static int qpnp_oledb_parse_dt(struct qpnp_oledb *oledb)
1086{
1087 int rc = 0;
1088 struct device_node *of_node = oledb->dev->of_node;
1089
1090 oledb->swire_control =
1091 of_property_read_bool(of_node, "qcom,swire-control");
1092
1093 oledb->ext_pin_control =
1094 of_property_read_bool(of_node, "qcom,ext-pin-control");
1095
1096 if (oledb->ext_pin_control)
1097 oledb->dynamic_ext_pinctl_config =
1098 of_property_read_bool(of_node,
1099 "qcom,dynamic-ext-pinctl-config");
1100 oledb->pbs_control =
1101 of_property_read_bool(of_node, "qcom,pbs-control");
1102
Kiran Gundab38cecc2017-02-13 19:55:40 +05301103 oledb->force_pd_control =
1104 of_property_read_bool(of_node, "qcom,force-pd-control");
1105
1106 if (oledb->force_pd_control) {
1107 oledb->pbs_dev_node = of_parse_phandle(of_node,
1108 "qcom,pbs-client", 0);
1109 if (!oledb->pbs_dev_node) {
1110 pr_err("Missing qcom,pbs-client property\n");
1111 return -EINVAL;
1112 }
1113 }
1114
David Collins8885f792017-01-26 14:36:34 -08001115 oledb->current_voltage = -EINVAL;
1116 rc = of_property_read_u32(of_node, "qcom,oledb-init-voltage-mv",
1117 &oledb->current_voltage);
1118 if (!rc && (oledb->current_voltage < OLEDB_VOUT_MIN_MV ||
1119 oledb->current_voltage > OLEDB_VOUT_MAX_MV)) {
1120 pr_err("Invalid value in qcom,oledb-init-voltage-mv\n");
1121 return -EINVAL;
1122 }
1123
1124 oledb->default_voltage = -EINVAL;
1125 rc = of_property_read_u32(of_node, "qcom,oledb-default-voltage-mv",
1126 &oledb->default_voltage);
1127 if (!rc && (oledb->default_voltage < OLEDB_VOUT_MIN_MV ||
1128 oledb->default_voltage > OLEDB_VOUT_MAX_MV)) {
1129 pr_err("Invalid value in qcom,oledb-default-voltage-mv\n");
1130 return -EINVAL;
1131 }
1132
1133 oledb->warmup_delay = -EINVAL;
1134 rc = of_property_read_u32(of_node, "qcom,bias-gen-warmup-delay-ns",
1135 &oledb->warmup_delay);
1136 if (!rc) {
1137 u16 min_delay = oledb_warmup_dly_ns[0];
1138 u16 max_delay = oledb_warmup_dly_ns[ARRAY_SIZE(
1139 oledb_warmup_dly_ns) - 1];
1140 if (oledb->warmup_delay < min_delay ||
1141 oledb->warmup_delay > max_delay) {
1142 pr_err("Invalid value in qcom,bias-gen-warmup-delay-ns\n");
1143 return -EINVAL;
1144 }
1145 }
1146
1147 oledb->peak_curr_limit = -EINVAL;
1148 rc = of_property_read_u32(of_node, "qcom,peak-curr-limit-ma",
1149 &oledb->peak_curr_limit);
1150 if (!rc) {
1151 u16 min_limit = oledb_peak_curr_limit_ma[0];
1152 u16 max_limit = oledb_peak_curr_limit_ma[ARRAY_SIZE(
1153 oledb_peak_curr_limit_ma) - 1];
1154 if (oledb->peak_curr_limit < min_limit ||
1155 oledb->peak_curr_limit > max_limit) {
1156 pr_err("Invalid value in qcom,peak-curr-limit-ma\n");
1157 return -EINVAL;
1158 }
1159 }
1160
1161 oledb->pd_ctl = -EINVAL;
1162 of_property_read_u32(of_node, "qcom,pull-down-enable", &oledb->pd_ctl);
1163
1164 oledb->sc_en = -EINVAL;
1165 rc = of_property_read_u32(of_node, "qcom,enable-short-circuit",
1166 &oledb->sc_en);
1167 if (!rc) {
1168 oledb->sc_dbnc_time = -EINVAL;
1169 rc = of_property_read_u32(of_node,
1170 "qcom,short-circuit-dbnc-time", &oledb->sc_dbnc_time);
1171 if (!rc) {
1172 if (oledb->sc_dbnc_time < OLEDB_MIN_SC_DBNC_TIME_FSW ||
1173 oledb->sc_dbnc_time > OLEDB_MAX_SC_DBNC_TIME_FSW) {
1174 pr_err("Invalid value in qcom,short-circuit-dbnc-time\n");
1175 return -EINVAL;
1176 }
1177 }
1178 }
1179
1180 rc = qpnp_oledb_parse_nlimit(oledb);
1181 if (rc < 0)
1182 return rc;
1183
1184 rc = qpnp_oledb_parse_psm(oledb);
1185 if (rc < 0)
1186 return rc;
1187
1188 rc = qpnp_oledb_parse_pfm(oledb);
1189 if (rc < 0)
1190 return rc;
1191
1192 rc = qpnp_oledb_parse_fast_precharge(oledb);
1193
1194 return rc;
1195}
1196
Kiran Gundab38cecc2017-02-13 19:55:40 +05301197static int qpnp_oledb_force_pulldown_config(struct qpnp_oledb *oledb)
1198{
1199 int rc = 0;
1200 u8 val;
1201
1202 rc = qpnp_oledb_sec_masked_write(oledb, oledb->base +
1203 OLEDB_SPARE_CTL, OLEDB_FORCE_PD_CTL_SPARE_BIT, 0);
1204 if (rc < 0) {
1205 pr_err("Failed to write SPARE_CTL rc=%d\n", rc);
1206 return rc;
1207 }
1208
1209 val = 1;
1210 rc = qpnp_oledb_write(oledb, oledb->base + OLEDB_PD_CTL,
1211 &val, 1);
1212 if (rc < 0) {
1213 pr_err("Failed to write PD_CTL rc=%d\n", rc);
1214 return rc;
1215 }
1216
1217 rc = qpnp_oledb_masked_write(oledb, oledb->base +
1218 OLEDB_SWIRE_CONTROL, OLEDB_EN_SWIRE_PD_UPD_BIT, 0);
1219 if (rc < 0)
1220 pr_err("Failed to write SWIRE_CTL for pbs mode rc=%d\n",
1221 rc);
1222
1223 return rc;
1224}
1225
1226static int qpnp_labibb_notifier_cb(struct notifier_block *nb,
1227 unsigned long action, void *data)
1228{
1229 int rc = 0;
1230 struct qpnp_oledb *oledb = container_of(nb, struct qpnp_oledb,
1231 oledb_nb);
1232
1233 if (action == LAB_VREG_OK) {
1234 /* Disable SWIRE pull down control and enable via spmi mode */
1235 rc = qpnp_oledb_force_pulldown_config(oledb);
1236 if (rc < 0)
1237 return NOTIFY_STOP;
1238 }
1239
1240 return NOTIFY_OK;
1241}
1242
David Collins8885f792017-01-26 14:36:34 -08001243static int qpnp_oledb_regulator_probe(struct platform_device *pdev)
1244{
1245 int rc = 0;
1246 u32 val;
1247 struct qpnp_oledb *oledb;
1248 struct device_node *of_node = pdev->dev.of_node;
1249
1250 oledb = devm_kzalloc(&pdev->dev,
1251 sizeof(struct qpnp_oledb), GFP_KERNEL);
1252 if (!oledb)
1253 return -ENOMEM;
1254
1255 oledb->pdev = pdev;
1256 oledb->dev = &pdev->dev;
1257 oledb->regmap = dev_get_regmap(pdev->dev.parent, NULL);
1258 dev_set_drvdata(&pdev->dev, oledb);
1259 if (!oledb->regmap) {
1260 pr_err("Couldn't get parent's regmap\n");
1261 return -EINVAL;
1262 }
1263
1264 rc = of_property_read_u32(of_node, "reg", &val);
1265 if (rc < 0) {
1266 pr_err("Couldn't find reg in node, rc = %d\n", rc);
1267 return rc;
1268 }
1269
Kiran Gundab38cecc2017-02-13 19:55:40 +05301270 mutex_init(&(oledb->bus_lock));
David Collins8885f792017-01-26 14:36:34 -08001271 oledb->base = val;
1272 rc = qpnp_oledb_parse_dt(oledb);
1273 if (rc < 0) {
1274 pr_err("Failed to parse common OLEDB device tree\n");
1275 return rc;
1276 }
1277
1278 rc = qpnp_oledb_hw_init(oledb);
1279 if (rc < 0) {
1280 pr_err("Failed to initialize OLEDB, rc=%d\n", rc);
1281 return rc;
1282 }
1283
Kiran Gundab38cecc2017-02-13 19:55:40 +05301284 if (oledb->force_pd_control) {
1285 oledb->oledb_nb.notifier_call = qpnp_labibb_notifier_cb;
1286 rc = qpnp_labibb_notifier_register(&oledb->oledb_nb);
1287 if (rc < 0) {
1288 pr_err("Failed to register qpnp_labibb_notifier_cb\n");
1289 return rc;
1290 }
1291 }
1292
David Collins8885f792017-01-26 14:36:34 -08001293 rc = qpnp_oledb_register_regulator(oledb);
Kiran Gundab38cecc2017-02-13 19:55:40 +05301294 if (rc < 0) {
1295 pr_err("Failed to register regulator rc=%d\n", rc);
1296 goto out;
1297 }
1298 pr_info("OLEDB registered successfully, ext_pin_en=%d mod_en=%d current_voltage=%d mV\n",
David Collins8885f792017-01-26 14:36:34 -08001299 oledb->ext_pin_control, oledb->mod_enable,
1300 oledb->current_voltage);
Kiran Gundab38cecc2017-02-13 19:55:40 +05301301 return 0;
1302
1303out:
1304 if (oledb->force_pd_control) {
1305 rc = qpnp_labibb_notifier_unregister(&oledb->oledb_nb);
1306 if (rc < 0)
1307 pr_err("Failed to unregister lab_vreg_ok notifier\n");
1308 }
David Collins8885f792017-01-26 14:36:34 -08001309
1310 return rc;
1311}
1312
1313static int qpnp_oledb_regulator_remove(struct platform_device *pdev)
1314{
Kiran Gundab38cecc2017-02-13 19:55:40 +05301315 int rc = 0;
1316 struct qpnp_oledb *oledb = platform_get_drvdata(pdev);
1317
1318 if (oledb->force_pd_control) {
1319 rc = qpnp_labibb_notifier_unregister(&oledb->oledb_nb);
1320 if (rc < 0)
1321 pr_err("Failed to unregister lab_vreg_ok notifier\n");
1322 }
1323
1324 return rc;
David Collins8885f792017-01-26 14:36:34 -08001325}
1326
1327const struct of_device_id qpnp_oledb_regulator_match_table[] = {
1328 { .compatible = QPNP_OLEDB_REGULATOR_DRIVER_NAME,},
1329 { },
1330};
1331
1332static struct platform_driver qpnp_oledb_regulator_driver = {
1333 .driver = {
1334 .name = QPNP_OLEDB_REGULATOR_DRIVER_NAME,
1335 .of_match_table = qpnp_oledb_regulator_match_table,
1336 },
1337 .probe = qpnp_oledb_regulator_probe,
1338 .remove = qpnp_oledb_regulator_remove,
1339};
1340
1341static int __init qpnp_oledb_regulator_init(void)
1342{
1343 return platform_driver_register(&qpnp_oledb_regulator_driver);
1344}
1345arch_initcall(qpnp_oledb_regulator_init);
1346
1347static void __exit qpnp_oledb_regulator_exit(void)
1348{
1349 platform_driver_unregister(&qpnp_oledb_regulator_driver);
1350}
1351module_exit(qpnp_oledb_regulator_exit);
1352
1353MODULE_DESCRIPTION("QPNP OLEDB driver");
1354MODULE_LICENSE("GPL v2");
1355MODULE_ALIAS("qpnp-oledb-regulator");