blob: aef28dbeb9319602ece23d63f53210b6c997d565 [file] [log] [blame]
David Collins8885f792017-01-26 14:36:34 -08001/*
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#define pr_fmt(fmt) "LCDB: %s: " fmt, __func__
15
16#include <linux/delay.h>
17#include <linux/device.h>
18#include <linux/interrupt.h>
Anirudh Ghayal264f9272017-03-05 22:34:37 +053019#include <linux/ktime.h>
David Collins8885f792017-01-26 14:36:34 -080020#include <linux/module.h>
21#include <linux/of_irq.h>
22#include <linux/platform_device.h>
23#include <linux/regmap.h>
24#include <linux/regulator/driver.h>
25#include <linux/regulator/of_regulator.h>
26#include <linux/regulator/machine.h>
27
28#define QPNP_LCDB_REGULATOR_DRIVER_NAME "qcom,qpnp-lcdb-regulator"
29
30/* LCDB */
31#define LCDB_STS1_REG 0x08
32
33#define INT_RT_STATUS_REG 0x10
34#define VREG_OK_RT_STS_BIT BIT(0)
Anirudh Ghayal264f9272017-03-05 22:34:37 +053035#define SC_ERROR_RT_STS_BIT BIT(1)
36
37#define LCDB_STS3_REG 0x0A
38#define LDO_VREG_OK_BIT BIT(7)
39
40#define LCDB_STS4_REG 0x0B
41#define NCP_VREG_OK_BIT BIT(7)
David Collins8885f792017-01-26 14:36:34 -080042
43#define LCDB_AUTO_TOUCH_WAKE_CTL_REG 0x40
44#define EN_AUTO_TOUCH_WAKE_BIT BIT(7)
45#define ATTW_TOFF_TIME_MASK GENMASK(3, 2)
46#define ATTW_TON_TIME_MASK GENMASK(1, 0)
47#define ATTW_TOFF_TIME_SHIFT 2
48#define ATTW_MIN_MS 4
49#define ATTW_MAX_MS 32
50
51#define LCDB_BST_OUTPUT_VOLTAGE_REG 0x41
52
53#define LCDB_MODULE_RDY_REG 0x45
54#define MODULE_RDY_BIT BIT(7)
55
56#define LCDB_ENABLE_CTL1_REG 0x46
57#define MODULE_EN_BIT BIT(7)
58#define HWEN_RDY_BIT BIT(6)
59
60/* BST */
61#define LCDB_BST_PD_CTL_REG 0x47
62#define BOOST_DIS_PULLDOWN_BIT BIT(1)
63#define BOOST_PD_STRENGTH_BIT BIT(0)
64
65#define LCDB_BST_ILIM_CTL_REG 0x4B
66#define EN_BST_ILIM_BIT BIT(7)
67#define SET_BST_ILIM_MASK GENMASK(2, 0)
68#define MIN_BST_ILIM_MA 200
69#define MAX_BST_ILIM_MA 1600
70
71#define LCDB_PS_CTL_REG 0x50
72#define EN_PS_BIT BIT(7)
73#define PS_THRESHOLD_MASK GENMASK(1, 0)
74#define MIN_BST_PS_MA 50
75#define MAX_BST_PS_MA 80
76
77#define LCDB_RDSON_MGMNT_REG 0x53
78#define NFET_SW_SIZE_MASK GENMASK(3, 2)
79#define NFET_SW_SIZE_SHIFT 2
80#define PFET_SW_SIZE_MASK GENMASK(1, 0)
81
82#define LCDB_BST_VREG_OK_CTL_REG 0x55
83#define BST_VREG_OK_DEB_MASK GENMASK(1, 0)
84
85#define LCDB_SOFT_START_CTL_REG 0x5F
86
87#define LCDB_MISC_CTL_REG 0x60
88#define AUTO_GM_EN_BIT BIT(4)
89#define EN_TOUCH_WAKE_BIT BIT(3)
90#define DIS_SCP_BIT BIT(0)
91
92#define LCDB_PFM_CTL_REG 0x62
93#define EN_PFM_BIT BIT(7)
94#define BYP_BST_SOFT_START_COMP_BIT BIT(0)
95#define PFM_HYSTERESIS_SHIFT 4
96#define PFM_CURRENT_SHIFT 2
97
98#define LCDB_PWRUP_PWRDN_CTL_REG 0x66
99
100/* LDO */
101#define LCDB_LDO_OUTPUT_VOLTAGE_REG 0x71
102#define SET_OUTPUT_VOLTAGE_MASK GENMASK(4, 0)
103
104#define LCDB_LDO_VREG_OK_CTL_REG 0x75
105#define VREG_OK_DEB_MASK GENMASK(1, 0)
106
107#define LCDB_LDO_PD_CTL_REG 0x77
108#define LDO_DIS_PULLDOWN_BIT BIT(1)
109#define LDO_PD_STRENGTH_BIT BIT(0)
110
111#define LCDB_LDO_ILIM_CTL1_REG 0x7B
112#define EN_LDO_ILIM_BIT BIT(7)
113#define SET_LDO_ILIM_MASK GENMASK(2, 0)
114#define MIN_LDO_ILIM_MA 110
115#define MAX_LDO_ILIM_MA 460
116#define LDO_ILIM_STEP_MA 50
117
118#define LCDB_LDO_ILIM_CTL2_REG 0x7C
119
120#define LCDB_LDO_SOFT_START_CTL_REG 0x7F
121#define SOFT_START_MASK GENMASK(1, 0)
122
123/* NCP */
124#define LCDB_NCP_OUTPUT_VOLTAGE_REG 0x81
125
126#define LCDB_NCP_VREG_OK_CTL_REG 0x85
127
128#define LCDB_NCP_PD_CTL_REG 0x87
129#define NCP_DIS_PULLDOWN_BIT BIT(1)
130#define NCP_PD_STRENGTH_BIT BIT(0)
131
132#define LCDB_NCP_ILIM_CTL1_REG 0x8B
133#define EN_NCP_ILIM_BIT BIT(7)
134#define SET_NCP_ILIM_MASK GENMASK(1, 0)
135#define MIN_NCP_ILIM_MA 260
136#define MAX_NCP_ILIM_MA 810
137
138#define LCDB_NCP_ILIM_CTL2_REG 0x8C
139
140#define LCDB_NCP_SOFT_START_CTL_REG 0x8F
141
142/* common for BST/NCP/LDO */
143#define MIN_DBC_US 2
144#define MAX_DBC_US 32
145
146#define MIN_SOFT_START_US 0
147#define MAX_SOFT_START_US 2000
148
149struct ldo_regulator {
150 struct regulator_desc rdesc;
151 struct regulator_dev *rdev;
152 struct device_node *node;
153
154 /* LDO DT params */
155 int pd;
156 int pd_strength;
157 int ilim_ma;
158 int soft_start_us;
159 int vreg_ok_dbc_us;
160 int voltage_mv;
161};
162
163struct ncp_regulator {
164 struct regulator_desc rdesc;
165 struct regulator_dev *rdev;
166 struct device_node *node;
167
168 /* NCP DT params */
169 int pd;
170 int pd_strength;
171 int ilim_ma;
172 int soft_start_us;
173 int vreg_ok_dbc_us;
174 int voltage_mv;
175};
176
177struct bst_params {
178 struct device_node *node;
179
180 /* BST DT params */
181 int pd;
182 int pd_strength;
183 int ilim_ma;
184 int ps;
185 int ps_threshold;
186 int soft_start_us;
187 int vreg_ok_dbc_us;
188 int voltage_mv;
189};
190
191struct qpnp_lcdb {
192 struct device *dev;
193 struct platform_device *pdev;
194 struct regmap *regmap;
195 u32 base;
Anirudh Ghayal264f9272017-03-05 22:34:37 +0530196 int sc_irq;
David Collins8885f792017-01-26 14:36:34 -0800197
198 /* TTW params */
199 bool ttw_enable;
200 bool ttw_mode_sw;
201
Anirudh Ghayal941c0c22017-02-23 14:31:29 +0530202 /* top level DT params */
203 bool force_module_reenable;
204
David Collins8885f792017-01-26 14:36:34 -0800205 /* status parameters */
206 bool lcdb_enabled;
207 bool settings_saved;
Anirudh Ghayal264f9272017-03-05 22:34:37 +0530208 bool lcdb_sc_disable;
209 int sc_count;
210 ktime_t sc_module_enable_time;
David Collins8885f792017-01-26 14:36:34 -0800211
212 struct mutex lcdb_mutex;
213 struct mutex read_write_mutex;
214 struct bst_params bst;
215 struct ldo_regulator ldo;
216 struct ncp_regulator ncp;
217};
218
219struct settings {
220 u16 address;
221 u8 value;
222 bool sec_access;
223};
224
225enum lcdb_module {
226 LDO,
227 NCP,
228 BST,
229};
230
231enum pfm_hysteresis {
232 PFM_HYST_15MV,
233 PFM_HYST_25MV,
234 PFM_HYST_35MV,
235 PFM_HYST_45MV,
236};
237
238enum pfm_peak_current {
239 PFM_PEAK_CURRENT_300MA,
240 PFM_PEAK_CURRENT_400MA,
241 PFM_PEAK_CURRENT_500MA,
242 PFM_PEAK_CURRENT_600MA,
243};
244
245enum rdson_fet_size {
246 RDSON_QUARTER,
247 RDSON_HALF,
248 RDSON_THREE_FOURTH,
249 RDSON_FULLSIZE,
250};
251
252enum lcdb_settings_index {
253 LCDB_BST_PD_CTL = 0,
254 LCDB_RDSON_MGMNT,
255 LCDB_MISC_CTL,
256 LCDB_SOFT_START_CTL,
257 LCDB_PFM_CTL,
258 LCDB_PWRUP_PWRDN_CTL,
259 LCDB_LDO_PD_CTL,
260 LCDB_LDO_SOFT_START_CTL,
261 LCDB_NCP_PD_CTL,
262 LCDB_NCP_SOFT_START_CTL,
263 LCDB_SETTING_MAX,
264};
265
266static u32 soft_start_us[] = {
267 0,
268 500,
269 1000,
270 2000,
271};
272
273static u32 dbc_us[] = {
274 2,
275 4,
276 16,
277 32,
278};
279
280static u32 ncp_ilim_ma[] = {
281 260,
282 460,
283 640,
284 810,
285};
286
287#define SETTING(_id, _sec_access) \
288 [_id] = { \
289 .address = _id##_REG, \
290 .sec_access = _sec_access, \
291 } \
292
293static bool is_between(int value, int min, int max)
294{
295 if (value < min || value > max)
296 return false;
297 return true;
298}
299
300static int qpnp_lcdb_read(struct qpnp_lcdb *lcdb,
301 u16 addr, u8 *value, u8 count)
302{
303 int rc = 0;
304
305 mutex_lock(&lcdb->read_write_mutex);
306 rc = regmap_bulk_read(lcdb->regmap, addr, value, count);
307 if (rc < 0)
308 pr_err("Failed to read from addr=0x%02x rc=%d\n", addr, rc);
309 mutex_unlock(&lcdb->read_write_mutex);
310
311 return rc;
312}
313
314static int qpnp_lcdb_write(struct qpnp_lcdb *lcdb,
315 u16 addr, u8 *value, u8 count)
316{
317 int rc;
318
319 mutex_lock(&lcdb->read_write_mutex);
320 rc = regmap_bulk_write(lcdb->regmap, addr, value, count);
321 if (rc < 0)
322 pr_err("Failed to write to addr=0x%02x rc=%d\n", addr, rc);
323 mutex_unlock(&lcdb->read_write_mutex);
324
325 return rc;
326}
327
328#define SEC_ADDRESS_REG 0xD0
329#define SECURE_UNLOCK_VALUE 0xA5
330static int qpnp_lcdb_secure_write(struct qpnp_lcdb *lcdb,
331 u16 addr, u8 value)
332{
333 int rc;
334 u8 val = SECURE_UNLOCK_VALUE;
335
336 mutex_lock(&lcdb->read_write_mutex);
337 rc = regmap_write(lcdb->regmap, lcdb->base + SEC_ADDRESS_REG, val);
338 if (rc < 0) {
339 pr_err("Failed to unlock register rc=%d\n", rc);
340 goto fail_write;
341 }
342 rc = regmap_write(lcdb->regmap, addr, value);
343 if (rc < 0)
344 pr_err("Failed to write to addr=0x%02x rc=%d\n", addr, rc);
345
346fail_write:
347 mutex_unlock(&lcdb->read_write_mutex);
348 return rc;
349}
350
351static int qpnp_lcdb_masked_write(struct qpnp_lcdb *lcdb,
352 u16 addr, u8 mask, u8 value)
353{
354 int rc = 0;
355
356 mutex_lock(&lcdb->read_write_mutex);
357 rc = regmap_update_bits(lcdb->regmap, addr, mask, value);
358 if (rc < 0)
359 pr_err("Failed to write addr=0x%02x value=0x%02x rc=%d\n",
360 addr, value, rc);
361 mutex_unlock(&lcdb->read_write_mutex);
362
363 return rc;
364}
365
366static bool is_lcdb_enabled(struct qpnp_lcdb *lcdb)
367{
368 int rc;
369 u8 val = 0;
370
371 rc = qpnp_lcdb_read(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG, &val, 1);
372 if (rc < 0)
373 pr_err("Failed to read ENABLE_CTL1 rc=%d\n", rc);
374
375 return rc ? false : !!(val & MODULE_EN_BIT);
376}
377
378static int dump_status_registers(struct qpnp_lcdb *lcdb)
379{
380 int rc = 0;
381 u8 sts[6] = {0};
382
383 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_STS1_REG, &sts[0], 6);
384 if (rc < 0) {
385 pr_err("Failed to write to STS registers rc=%d\n", rc);
386 } else {
387 rc = qpnp_lcdb_read(lcdb, lcdb->base + LCDB_STS1_REG, sts, 6);
388 if (rc < 0)
389 pr_err("Failed to read lcdb status rc=%d\n", rc);
390 else
391 pr_err("STS1=0x%02x STS2=0x%02x STS3=0x%02x STS4=0x%02x STS5=0x%02x, STS6=0x%02x\n",
392 sts[0], sts[1], sts[2], sts[3], sts[4], sts[5]);
393 }
394
395 return rc;
396}
397
398static struct settings lcdb_settings[] = {
399 SETTING(LCDB_BST_PD_CTL, false),
400 SETTING(LCDB_RDSON_MGMNT, false),
401 SETTING(LCDB_MISC_CTL, false),
402 SETTING(LCDB_SOFT_START_CTL, false),
403 SETTING(LCDB_PFM_CTL, false),
404 SETTING(LCDB_PWRUP_PWRDN_CTL, true),
405 SETTING(LCDB_LDO_PD_CTL, false),
406 SETTING(LCDB_LDO_SOFT_START_CTL, false),
407 SETTING(LCDB_NCP_PD_CTL, false),
408 SETTING(LCDB_NCP_SOFT_START_CTL, false),
409};
410
411static int qpnp_lcdb_save_settings(struct qpnp_lcdb *lcdb)
412{
413 int i, rc = 0;
414
415 for (i = 0; i < ARRAY_SIZE(lcdb_settings); i++) {
416 rc = qpnp_lcdb_read(lcdb, lcdb->base +
417 lcdb_settings[i].address,
418 &lcdb_settings[i].value, 1);
419 if (rc < 0) {
420 pr_err("Failed to read lcdb register address=%x\n",
421 lcdb_settings[i].address);
422 return rc;
423 }
424 }
425
426 return rc;
427}
428
429static int qpnp_lcdb_restore_settings(struct qpnp_lcdb *lcdb)
430{
431 int i, rc = 0;
432
433 for (i = 0; i < ARRAY_SIZE(lcdb_settings); i++) {
434 if (lcdb_settings[i].sec_access)
435 rc = qpnp_lcdb_secure_write(lcdb, lcdb->base +
436 lcdb_settings[i].address,
437 lcdb_settings[i].value);
438 else
439 rc = qpnp_lcdb_write(lcdb, lcdb->base +
440 lcdb_settings[i].address,
441 &lcdb_settings[i].value, 1);
442 if (rc < 0) {
443 pr_err("Failed to write register address=%x\n",
444 lcdb_settings[i].address);
445 return rc;
446 }
447 }
448
449 return rc;
450}
451
452static int qpnp_lcdb_ttw_enter(struct qpnp_lcdb *lcdb)
453{
454 int rc;
455 u8 val;
456
457 if (!lcdb->settings_saved) {
458 rc = qpnp_lcdb_save_settings(lcdb);
459 if (rc < 0) {
460 pr_err("Failed to save LCDB settings rc=%d\n", rc);
461 return rc;
462 }
463 lcdb->settings_saved = true;
464 }
465
466 val = BOOST_DIS_PULLDOWN_BIT;
467 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_BST_PD_CTL_REG,
468 &val, 1);
469 if (rc < 0) {
470 pr_err("Failed to set BST PD rc=%d\n", rc);
471 return rc;
472 }
473
474 val = (RDSON_HALF << NFET_SW_SIZE_SHIFT) | RDSON_HALF;
475 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_RDSON_MGMNT_REG,
476 &val, 1);
477 if (rc < 0) {
478 pr_err("Failed to set RDSON MGMT rc=%d\n", rc);
479 return rc;
480 }
481
482 val = AUTO_GM_EN_BIT | EN_TOUCH_WAKE_BIT | DIS_SCP_BIT;
483 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_MISC_CTL_REG,
484 &val, 1);
485 if (rc < 0) {
486 pr_err("Failed to set MISC CTL rc=%d\n", rc);
487 return rc;
488 }
489
490 val = 0;
491 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_SOFT_START_CTL_REG,
492 &val, 1);
493 if (rc < 0) {
494 pr_err("Failed to set LCDB_SOFT_START rc=%d\n", rc);
495 return rc;
496 }
497
498 val = EN_PFM_BIT | (PFM_HYST_25MV << PFM_HYSTERESIS_SHIFT) |
499 (PFM_PEAK_CURRENT_400MA << PFM_CURRENT_SHIFT) |
500 BYP_BST_SOFT_START_COMP_BIT;
501 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_PFM_CTL_REG,
502 &val, 1);
503 if (rc < 0) {
504 pr_err("Failed to set PFM_CTL rc=%d\n", rc);
505 return rc;
506 }
507
508 val = 0;
509 rc = qpnp_lcdb_secure_write(lcdb, lcdb->base + LCDB_PWRUP_PWRDN_CTL_REG,
510 val);
511 if (rc < 0) {
512 pr_err("Failed to set PWRUP_PWRDN_CTL rc=%d\n", rc);
513 return rc;
514 }
515
516 val = LDO_DIS_PULLDOWN_BIT;
517 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_LDO_PD_CTL_REG,
518 &val, 1);
519 if (rc < 0) {
520 pr_err("Failed to set LDO_PD_CTL rc=%d\n", rc);
521 return rc;
522 }
523
524 val = 0;
525 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_LDO_SOFT_START_CTL_REG,
526 &val, 1);
527 if (rc < 0) {
528 pr_err("Failed to set LDO_SOFT_START rc=%d\n", rc);
529 return rc;
530 }
531
532 val = NCP_DIS_PULLDOWN_BIT;
533 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_NCP_PD_CTL_REG,
534 &val, 1);
535 if (rc < 0) {
536 pr_err("Failed to set NCP_PD_CTL rc=%d\n", rc);
537 return rc;
538 }
539
540 val = 0;
541 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_NCP_SOFT_START_CTL_REG,
542 &val, 1);
543 if (rc < 0) {
544 pr_err("Failed to set NCP_SOFT_START rc=%d\n", rc);
545 return rc;
546 }
547
548 if (lcdb->ttw_mode_sw) {
549 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
550 LCDB_AUTO_TOUCH_WAKE_CTL_REG,
551 EN_AUTO_TOUCH_WAKE_BIT,
552 EN_AUTO_TOUCH_WAKE_BIT);
553 if (rc < 0)
554 pr_err("Failed to enable auto(sw) TTW\n rc = %d\n", rc);
555 } else {
556 val = HWEN_RDY_BIT;
557 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
558 &val, 1);
559 if (rc < 0)
560 pr_err("Failed to hw_enable lcdb rc= %d\n", rc);
561 }
562
563 return rc;
564}
565
566static int qpnp_lcdb_ttw_exit(struct qpnp_lcdb *lcdb)
567{
568 int rc;
569
570 if (lcdb->settings_saved) {
571 rc = qpnp_lcdb_restore_settings(lcdb);
572 if (rc < 0) {
573 pr_err("Failed to restore lcdb settings rc=%d\n", rc);
574 return rc;
575 }
576 lcdb->settings_saved = false;
577 }
578
579 return 0;
580}
581
582static int qpnp_lcdb_enable(struct qpnp_lcdb *lcdb)
583{
584 int rc = 0, timeout, delay;
585 u8 val = 0;
586
Anirudh Ghayal264f9272017-03-05 22:34:37 +0530587 if (lcdb->lcdb_enabled || lcdb->lcdb_sc_disable) {
588 pr_debug("lcdb_enabled=%d lcdb_sc_disable=%d\n",
589 lcdb->lcdb_enabled, lcdb->lcdb_sc_disable);
David Collins8885f792017-01-26 14:36:34 -0800590 return 0;
Anirudh Ghayal264f9272017-03-05 22:34:37 +0530591 }
David Collins8885f792017-01-26 14:36:34 -0800592
593 if (lcdb->ttw_enable) {
594 rc = qpnp_lcdb_ttw_exit(lcdb);
595 if (rc < 0) {
596 pr_err("Failed to exit TTW mode rc=%d\n", rc);
597 return rc;
598 }
599 }
600
601 val = MODULE_EN_BIT;
602 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
603 &val, 1);
604 if (rc < 0) {
605 pr_err("Failed to enable lcdb rc= %d\n", rc);
606 goto fail_enable;
607 }
608
Anirudh Ghayal941c0c22017-02-23 14:31:29 +0530609 if (lcdb->force_module_reenable) {
610 val = 0;
611 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
612 &val, 1);
613 if (rc < 0) {
614 pr_err("Failed to enable lcdb rc= %d\n", rc);
615 goto fail_enable;
616 }
617 val = MODULE_EN_BIT;
618 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
619 &val, 1);
620 if (rc < 0) {
621 pr_err("Failed to disable lcdb rc= %d\n", rc);
622 goto fail_enable;
623 }
624 }
625
David Collins8885f792017-01-26 14:36:34 -0800626 /* poll for vreg_ok */
627 timeout = 10;
628 delay = lcdb->bst.soft_start_us + lcdb->ldo.soft_start_us +
629 lcdb->ncp.soft_start_us;
630 delay += lcdb->bst.vreg_ok_dbc_us + lcdb->ldo.vreg_ok_dbc_us +
631 lcdb->ncp.vreg_ok_dbc_us;
632 while (timeout--) {
633 rc = qpnp_lcdb_read(lcdb, lcdb->base + INT_RT_STATUS_REG,
634 &val, 1);
635 if (rc < 0) {
636 pr_err("Failed to poll for vreg-ok status rc=%d\n", rc);
637 break;
638 }
639 if (val & VREG_OK_RT_STS_BIT)
640 break;
641
642 usleep_range(delay, delay + 100);
643 }
644
645 if (rc || !timeout) {
646 if (!timeout) {
647 pr_err("lcdb-vreg-ok status failed to change\n");
648 rc = -ETIMEDOUT;
649 }
650 goto fail_enable;
651 }
652
653 lcdb->lcdb_enabled = true;
654 pr_debug("lcdb enabled successfully!\n");
655
656 return 0;
657
658fail_enable:
659 dump_status_registers(lcdb);
660 pr_err("Failed to enable lcdb rc=%d\n", rc);
661 return rc;
662}
663
664static int qpnp_lcdb_disable(struct qpnp_lcdb *lcdb)
665{
666 int rc = 0;
667 u8 val;
668
669 if (!lcdb->lcdb_enabled)
670 return 0;
671
672 if (lcdb->ttw_enable) {
673 rc = qpnp_lcdb_ttw_enter(lcdb);
674 if (rc < 0) {
675 pr_err("Failed to enable TTW mode rc=%d\n", rc);
676 return rc;
677 }
678 lcdb->lcdb_enabled = false;
679
680 return 0;
681 }
682
683 val = 0;
684 rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
685 &val, 1);
686 if (rc < 0)
687 pr_err("Failed to disable lcdb rc= %d\n", rc);
688 else
689 lcdb->lcdb_enabled = false;
690
691 return rc;
692}
693
Anirudh Ghayal264f9272017-03-05 22:34:37 +0530694#define LCDB_SC_RESET_CNT_DLY_US 1000000
695#define LCDB_SC_CNT_MAX 10
696static int qpnp_lcdb_handle_sc_event(struct qpnp_lcdb *lcdb)
697{
698 int rc = 0;
699 s64 elapsed_time_us;
700
701 mutex_lock(&lcdb->lcdb_mutex);
702 rc = qpnp_lcdb_disable(lcdb);
703 if (rc < 0) {
704 pr_err("Failed to disable lcdb rc=%d\n", rc);
705 goto unlock_mutex;
706 }
707
708 /* Check if the SC re-occurred immediately */
709 elapsed_time_us = ktime_us_delta(ktime_get(),
710 lcdb->sc_module_enable_time);
711 if (elapsed_time_us > LCDB_SC_RESET_CNT_DLY_US) {
712 lcdb->sc_count = 0;
713 } else if (lcdb->sc_count > LCDB_SC_CNT_MAX) {
714 pr_err("SC trigged %d times, disabling LCDB forever!\n",
715 lcdb->sc_count);
716 lcdb->lcdb_sc_disable = true;
717 goto unlock_mutex;
718 }
719 lcdb->sc_count++;
720 lcdb->sc_module_enable_time = ktime_get();
721
722 /* delay for SC to clear */
723 usleep_range(10000, 10100);
724
725 rc = qpnp_lcdb_enable(lcdb);
726 if (rc < 0)
727 pr_err("Failed to enable lcdb rc=%d\n", rc);
728
729unlock_mutex:
730 mutex_unlock(&lcdb->lcdb_mutex);
731 return rc;
732}
733
734static irqreturn_t qpnp_lcdb_sc_irq_handler(int irq, void *data)
735{
736 struct qpnp_lcdb *lcdb = data;
737 int rc;
738 u8 val, val2[2] = {0};
739
740 rc = qpnp_lcdb_read(lcdb, lcdb->base + INT_RT_STATUS_REG, &val, 1);
741 if (rc < 0)
742 goto irq_handled;
743
744 if (val & SC_ERROR_RT_STS_BIT) {
745 rc = qpnp_lcdb_read(lcdb,
746 lcdb->base + LCDB_MISC_CTL_REG, &val, 1);
747 if (rc < 0)
748 goto irq_handled;
749
750 if (val & EN_TOUCH_WAKE_BIT) {
751 /* blanking time */
752 usleep_range(300, 310);
753 /*
754 * The status registers need to written with any value
755 * before reading
756 */
757 rc = qpnp_lcdb_write(lcdb,
758 lcdb->base + LCDB_STS3_REG, val2, 2);
759 if (rc < 0)
760 goto irq_handled;
761
762 rc = qpnp_lcdb_read(lcdb,
763 lcdb->base + LCDB_STS3_REG, val2, 2);
764 if (rc < 0)
765 goto irq_handled;
766
767 if (!(val2[0] & LDO_VREG_OK_BIT) ||
768 !(val2[1] & NCP_VREG_OK_BIT)) {
769 rc = qpnp_lcdb_handle_sc_event(lcdb);
770 if (rc < 0) {
771 pr_err("Failed to handle SC rc=%d\n",
772 rc);
773 goto irq_handled;
774 }
775 }
776 } else {
777 /* blanking time */
778 usleep_range(2000, 2100);
779 /* Read the SC status again to confirm true SC */
780 rc = qpnp_lcdb_read(lcdb,
781 lcdb->base + INT_RT_STATUS_REG, &val, 1);
782 if (rc < 0)
783 goto irq_handled;
784
785 if (val & SC_ERROR_RT_STS_BIT) {
786 rc = qpnp_lcdb_handle_sc_event(lcdb);
787 if (rc < 0) {
788 pr_err("Failed to handle SC rc=%d\n",
789 rc);
790 goto irq_handled;
791 }
792 }
793 }
794 }
795irq_handled:
796 return IRQ_HANDLED;
797}
798
David Collins8885f792017-01-26 14:36:34 -0800799#define MIN_BST_VOLTAGE_MV 4700
800#define MAX_BST_VOLTAGE_MV 6250
801#define MIN_VOLTAGE_MV 4000
802#define MAX_VOLTAGE_MV 6000
803#define VOLTAGE_MIN_STEP_100_MV 4000
804#define VOLTAGE_MIN_STEP_50_MV 4950
805#define VOLTAGE_STEP_100_MV 100
806#define VOLTAGE_STEP_50_MV 50
807#define VOLTAGE_STEP_50MV_OFFSET 0xA
808static int qpnp_lcdb_set_bst_voltage(struct qpnp_lcdb *lcdb,
809 int voltage_mv)
810{
811 int rc = 0;
812 u8 val = 0;
813
814 if (voltage_mv < MIN_BST_VOLTAGE_MV)
815 voltage_mv = MIN_BST_VOLTAGE_MV;
816 else if (voltage_mv > MAX_BST_VOLTAGE_MV)
817 voltage_mv = MAX_BST_VOLTAGE_MV;
818
819 val = DIV_ROUND_UP(voltage_mv - MIN_BST_VOLTAGE_MV,
820 VOLTAGE_STEP_50_MV);
821
822 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
823 LCDB_BST_OUTPUT_VOLTAGE_REG,
824 SET_OUTPUT_VOLTAGE_MASK, val);
825 if (rc < 0)
826 pr_err("Failed to set boost voltage %d mv rc=%d\n",
827 voltage_mv, rc);
828 else
829 pr_debug("Boost voltage set = %d mv (0x%02x = 0x%02x)\n",
830 voltage_mv, LCDB_BST_OUTPUT_VOLTAGE_REG, val);
831
832 return rc;
833}
834
835static int qpnp_lcdb_get_bst_voltage(struct qpnp_lcdb *lcdb,
836 int *voltage_mv)
837{
838 int rc;
839 u8 val = 0;
840
841 rc = qpnp_lcdb_read(lcdb, lcdb->base + LCDB_BST_OUTPUT_VOLTAGE_REG,
842 &val, 1);
843 if (rc < 0) {
844 pr_err("Failed to reat BST voltage rc=%d\n", rc);
845 return rc;
846 }
847
848 val &= SET_OUTPUT_VOLTAGE_MASK;
849 *voltage_mv = (val * VOLTAGE_STEP_50_MV) + MIN_BST_VOLTAGE_MV;
850
851 return 0;
852}
853
854static int qpnp_lcdb_set_voltage(struct qpnp_lcdb *lcdb,
855 int voltage_mv, u8 type)
856{
857 int rc = 0;
858 u16 offset = LCDB_LDO_OUTPUT_VOLTAGE_REG;
859 u8 val = 0;
860
861 if (type == BST)
862 return qpnp_lcdb_set_bst_voltage(lcdb, voltage_mv);
863
864 if (type == NCP)
865 offset = LCDB_NCP_OUTPUT_VOLTAGE_REG;
866
867 if (!is_between(voltage_mv, MIN_VOLTAGE_MV, MAX_VOLTAGE_MV)) {
868 pr_err("Invalid voltage %dmv (min=%d max=%d)\n",
869 voltage_mv, MIN_VOLTAGE_MV, MAX_VOLTAGE_MV);
870 return -EINVAL;
871 }
872
873 /* Change the BST voltage to LDO + 100mV */
874 if (type == LDO) {
875 rc = qpnp_lcdb_set_bst_voltage(lcdb, voltage_mv + 100);
876 if (rc < 0) {
877 pr_err("Failed to set boost voltage rc=%d\n", rc);
878 return rc;
879 }
880 }
881
882 /* Below logic is only valid for LDO and NCP type */
883 if (voltage_mv < VOLTAGE_MIN_STEP_50_MV) {
884 val = DIV_ROUND_UP(voltage_mv - VOLTAGE_MIN_STEP_100_MV,
885 VOLTAGE_STEP_100_MV);
886 } else {
887 val = DIV_ROUND_UP(voltage_mv - VOLTAGE_MIN_STEP_50_MV,
888 VOLTAGE_STEP_50_MV);
889 val += VOLTAGE_STEP_50MV_OFFSET;
890 }
891
892 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base + offset,
893 SET_OUTPUT_VOLTAGE_MASK, val);
894 if (rc < 0)
895 pr_err("Failed to set output voltage %d mv for %s rc=%d\n",
896 voltage_mv, (type == LDO) ? "LDO" : "NCP", rc);
897 else
898 pr_debug("%s voltage set = %d mv (0x%02x = 0x%02x)\n",
899 (type == LDO) ? "LDO" : "NCP", voltage_mv, offset, val);
900
901 return rc;
902}
903
904static int qpnp_lcdb_get_voltage(struct qpnp_lcdb *lcdb,
905 u32 *voltage_mv, u8 type)
906{
907 int rc = 0;
908 u16 offset = LCDB_LDO_OUTPUT_VOLTAGE_REG;
909 u8 val = 0;
910
911 if (type == BST)
912 return qpnp_lcdb_get_bst_voltage(lcdb, voltage_mv);
913
914 if (type == NCP)
915 offset = LCDB_NCP_OUTPUT_VOLTAGE_REG;
916
917 rc = qpnp_lcdb_read(lcdb, lcdb->base + offset, &val, 1);
918 if (rc < 0) {
919 pr_err("Failed to read %s volatge rc=%d\n",
920 (type == LDO) ? "LDO" : "NCP", rc);
921 return rc;
922 }
923
924 if (val < VOLTAGE_STEP_50MV_OFFSET) {
925 *voltage_mv = VOLTAGE_MIN_STEP_100_MV +
926 (val * VOLTAGE_STEP_100_MV);
927 } else {
928 *voltage_mv = VOLTAGE_MIN_STEP_50_MV +
929 ((val - VOLTAGE_STEP_50MV_OFFSET) * VOLTAGE_STEP_50_MV);
930 }
931
932 if (!rc)
933 pr_debug("%s voltage read-back = %d mv (0x%02x = 0x%02x)\n",
934 (type == LDO) ? "LDO" : "NCP",
935 *voltage_mv, offset, val);
936
937 return rc;
938}
939
940static int qpnp_lcdb_set_soft_start(struct qpnp_lcdb *lcdb,
941 u32 ss_us, u8 type)
942{
943 int rc = 0, i = 0;
944 u16 offset = LCDB_LDO_SOFT_START_CTL_REG;
945 u8 val = 0;
946
947 if (type == NCP)
948 offset = LCDB_NCP_SOFT_START_CTL_REG;
949
950 if (!is_between(ss_us, MIN_SOFT_START_US, MAX_SOFT_START_US)) {
951 pr_err("Invalid soft_start_us %d (min=%d max=%d)\n",
952 ss_us, MIN_SOFT_START_US, MAX_SOFT_START_US);
953 return -EINVAL;
954 }
955
956 i = 0;
957 while (ss_us > soft_start_us[i])
958 i++;
959 val = ((i == 0) ? 0 : i - 1) & SOFT_START_MASK;
960
961 rc = qpnp_lcdb_masked_write(lcdb,
962 lcdb->base + offset, SOFT_START_MASK, val);
963 if (rc < 0)
964 pr_err("Failed to write %s soft-start time %d rc=%d",
965 (type == LDO) ? "LDO" : "NCP", soft_start_us[i], rc);
966
967 return rc;
968}
969
970static int qpnp_lcdb_ldo_regulator_enable(struct regulator_dev *rdev)
971{
972 int rc = 0;
973 struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
974
975 mutex_lock(&lcdb->lcdb_mutex);
976 rc = qpnp_lcdb_enable(lcdb);
977 if (rc < 0)
978 pr_err("Failed to enable lcdb rc=%d\n", rc);
979 mutex_unlock(&lcdb->lcdb_mutex);
980
981 return rc;
982}
983
984static int qpnp_lcdb_ldo_regulator_disable(struct regulator_dev *rdev)
985{
986 int rc = 0;
987 struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
988
989 mutex_lock(&lcdb->lcdb_mutex);
990 rc = qpnp_lcdb_disable(lcdb);
991 if (rc < 0)
992 pr_err("Failed to disable lcdb rc=%d\n", rc);
993 mutex_unlock(&lcdb->lcdb_mutex);
994
995 return rc;
996}
997
998static int qpnp_lcdb_ldo_regulator_is_enabled(struct regulator_dev *rdev)
999{
1000 struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
1001
1002 return lcdb->lcdb_enabled;
1003}
1004
1005static int qpnp_lcdb_ldo_regulator_set_voltage(struct regulator_dev *rdev,
1006 int min_uV, int max_uV, unsigned int *selector)
1007{
1008 int rc = 0;
1009 struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
1010
1011 rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, LDO);
1012 if (rc < 0)
1013 pr_err("Failed to set LDO voltage rc=%c\n", rc);
1014
1015 return rc;
1016}
1017
1018static int qpnp_lcdb_ldo_regulator_get_voltage(struct regulator_dev *rdev)
1019{
1020 int rc = 0;
1021 u32 voltage_mv = 0;
1022 struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
1023
1024 rc = qpnp_lcdb_get_voltage(lcdb, &voltage_mv, LDO);
1025 if (rc < 0) {
1026 pr_err("Failed to get ldo voltage rc=%d\n", rc);
1027 return rc;
1028 }
1029
1030 return voltage_mv * 1000;
1031}
1032
1033static struct regulator_ops qpnp_lcdb_ldo_ops = {
1034 .enable = qpnp_lcdb_ldo_regulator_enable,
1035 .disable = qpnp_lcdb_ldo_regulator_disable,
1036 .is_enabled = qpnp_lcdb_ldo_regulator_is_enabled,
1037 .set_voltage = qpnp_lcdb_ldo_regulator_set_voltage,
1038 .get_voltage = qpnp_lcdb_ldo_regulator_get_voltage,
1039};
1040
1041static int qpnp_lcdb_ncp_regulator_enable(struct regulator_dev *rdev)
1042{
1043 int rc = 0;
1044 struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
1045
1046 mutex_lock(&lcdb->lcdb_mutex);
1047 rc = qpnp_lcdb_enable(lcdb);
1048 if (rc < 0)
1049 pr_err("Failed to enable lcdb rc=%d\n", rc);
1050 mutex_unlock(&lcdb->lcdb_mutex);
1051
1052 return rc;
1053}
1054
1055static int qpnp_lcdb_ncp_regulator_disable(struct regulator_dev *rdev)
1056{
1057 int rc = 0;
1058 struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
1059
1060 mutex_lock(&lcdb->lcdb_mutex);
1061 rc = qpnp_lcdb_disable(lcdb);
1062 if (rc < 0)
1063 pr_err("Failed to disable lcdb rc=%d\n", rc);
1064 mutex_unlock(&lcdb->lcdb_mutex);
1065
1066 return rc;
1067}
1068
1069static int qpnp_lcdb_ncp_regulator_is_enabled(struct regulator_dev *rdev)
1070{
1071 struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
1072
1073 return lcdb->lcdb_enabled;
1074}
1075
1076static int qpnp_lcdb_ncp_regulator_set_voltage(struct regulator_dev *rdev,
1077 int min_uV, int max_uV, unsigned int *selector)
1078{
1079 int rc = 0;
1080 struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
1081
1082 rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, NCP);
1083 if (rc < 0)
1084 pr_err("Failed to set LDO voltage rc=%c\n", rc);
1085
1086 return rc;
1087}
1088
1089static int qpnp_lcdb_ncp_regulator_get_voltage(struct regulator_dev *rdev)
1090{
1091 int rc;
1092 u32 voltage_mv = 0;
1093 struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
1094
1095 rc = qpnp_lcdb_get_voltage(lcdb, &voltage_mv, NCP);
1096 if (rc < 0) {
1097 pr_err("Failed to get ncp voltage rc=%d\n", rc);
1098 return rc;
1099 }
1100
1101 return voltage_mv * 1000;
1102}
1103
1104static struct regulator_ops qpnp_lcdb_ncp_ops = {
1105 .enable = qpnp_lcdb_ncp_regulator_enable,
1106 .disable = qpnp_lcdb_ncp_regulator_disable,
1107 .is_enabled = qpnp_lcdb_ncp_regulator_is_enabled,
1108 .set_voltage = qpnp_lcdb_ncp_regulator_set_voltage,
1109 .get_voltage = qpnp_lcdb_ncp_regulator_get_voltage,
1110};
1111
1112static int qpnp_lcdb_regulator_register(struct qpnp_lcdb *lcdb, u8 type)
1113{
1114 int rc = 0;
1115 struct regulator_init_data *init_data;
1116 struct regulator_config cfg = {};
1117 struct regulator_desc *rdesc;
1118 struct regulator_dev *rdev;
1119 struct device_node *node;
1120
1121 if (type == LDO) {
1122 node = lcdb->ldo.node;
1123 rdesc = &lcdb->ldo.rdesc;
1124 rdesc->ops = &qpnp_lcdb_ldo_ops;
1125 rdev = lcdb->ldo.rdev;
1126 } else if (type == NCP) {
1127 node = lcdb->ncp.node;
1128 rdesc = &lcdb->ncp.rdesc;
1129 rdesc->ops = &qpnp_lcdb_ncp_ops;
1130 rdev = lcdb->ncp.rdev;
1131 } else {
1132 pr_err("Invalid regulator type %d\n", type);
1133 return -EINVAL;
1134 }
1135
1136 init_data = of_get_regulator_init_data(lcdb->dev, node, rdesc);
1137 if (!init_data) {
1138 pr_err("Failed to get regulator_init_data for %s\n",
1139 (type == LDO) ? "LDO" : "NCP");
1140 return -ENOMEM;
1141 }
1142
1143 if (init_data->constraints.name) {
1144 rdesc->owner = THIS_MODULE;
1145 rdesc->type = REGULATOR_VOLTAGE;
1146 rdesc->name = init_data->constraints.name;
1147
1148 cfg.dev = lcdb->dev;
1149 cfg.init_data = init_data;
1150 cfg.driver_data = lcdb;
1151 cfg.of_node = node;
1152
1153 if (of_get_property(lcdb->dev->of_node, "parent-supply", NULL))
1154 init_data->supply_regulator = "parent";
1155
1156 init_data->constraints.valid_ops_mask
1157 |= REGULATOR_CHANGE_VOLTAGE
1158 | REGULATOR_CHANGE_STATUS;
1159
1160 rdev = devm_regulator_register(lcdb->dev, rdesc, &cfg);
1161 if (IS_ERR(rdev)) {
1162 rc = PTR_ERR(rdev);
1163 rdev = NULL;
1164 pr_err("Failed to register lcdb_%s regulator rc = %d\n",
1165 (type == LDO) ? "LDO" : "NCP", rc);
1166 return rc;
1167 }
1168 } else {
1169 pr_err("%s_regulator name missing\n",
1170 (type == LDO) ? "LDO" : "NCP");
1171 return -EINVAL;
1172 }
1173
1174 return rc;
1175}
1176
1177static int qpnp_lcdb_parse_ttw(struct qpnp_lcdb *lcdb)
1178{
1179 int rc = 0;
1180 u32 temp;
1181 u8 val = 0;
1182 struct device_node *node = lcdb->dev->of_node;
1183
1184 if (of_property_read_bool(node, "qcom,ttw-mode-sw")) {
1185 lcdb->ttw_mode_sw = true;
1186 rc = of_property_read_u32(node, "qcom,attw-toff-ms", &temp);
1187 if (!rc) {
1188 if (!is_between(temp, ATTW_MIN_MS, ATTW_MAX_MS)) {
1189 pr_err("Invalid TOFF val %d (min=%d max=%d)\n",
1190 temp, ATTW_MIN_MS, ATTW_MAX_MS);
1191 return -EINVAL;
1192 }
1193 val = ilog2(temp / 4) << ATTW_TOFF_TIME_SHIFT;
1194 } else {
1195 pr_err("qcom,attw-toff-ms not specified for TTW SW mode\n");
1196 return rc;
1197 }
1198
1199 rc = of_property_read_u32(node, "qcom,attw-ton-ms", &temp);
1200 if (!rc) {
1201 if (!is_between(temp, ATTW_MIN_MS, ATTW_MAX_MS)) {
1202 pr_err("Invalid TON value %d (min=%d max=%d)\n",
1203 temp, ATTW_MIN_MS, ATTW_MAX_MS);
1204 return -EINVAL;
1205 }
1206 val |= ilog2(temp / 4);
1207 } else {
1208 pr_err("qcom,attw-ton-ms not specified for TTW SW mode\n");
1209 return rc;
1210 }
1211 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
1212 LCDB_AUTO_TOUCH_WAKE_CTL_REG,
1213 ATTW_TON_TIME_MASK | ATTW_TOFF_TIME_MASK, val);
1214 if (rc < 0) {
1215 pr_err("Failed to write ATTW ON/OFF rc=%d\n", rc);
1216 return rc;
1217 }
1218 }
1219
1220 return 0;
1221}
1222
1223static int qpnp_lcdb_ldo_dt_init(struct qpnp_lcdb *lcdb)
1224{
1225 int rc = 0;
1226 struct device_node *node = lcdb->ldo.node;
1227
1228 /* LDO output voltage */
1229 lcdb->ldo.voltage_mv = -EINVAL;
1230 rc = of_property_read_u32(node, "qcom,ldo-voltage-mv",
1231 &lcdb->ldo.voltage_mv);
1232 if (!rc && !is_between(lcdb->ldo.voltage_mv, MIN_VOLTAGE_MV,
1233 MAX_VOLTAGE_MV)) {
1234 pr_err("Invalid LDO voltage %dmv (min=%d max=%d)\n",
1235 lcdb->ldo.voltage_mv, MIN_VOLTAGE_MV, MAX_VOLTAGE_MV);
1236 return -EINVAL;
1237 }
1238
1239 /* LDO PD configuration */
1240 lcdb->ldo.pd = -EINVAL;
1241 of_property_read_u32(node, "qcom,ldo-pd", &lcdb->ldo.pd);
1242
1243 lcdb->ldo.pd_strength = -EINVAL;
1244 of_property_read_u32(node, "qcom,ldo-pd-strength",
1245 &lcdb->ldo.pd_strength);
1246
1247 /* LDO ILIM configuration */
1248 lcdb->ldo.ilim_ma = -EINVAL;
1249 rc = of_property_read_u32(node, "qcom,ldo-ilim-ma", &lcdb->ldo.ilim_ma);
1250 if (!rc && !is_between(lcdb->ldo.ilim_ma, MIN_LDO_ILIM_MA,
1251 MAX_LDO_ILIM_MA)) {
1252 pr_err("Invalid ilim_ma %d (min=%d, max=%d)\n",
1253 lcdb->ldo.ilim_ma, MIN_LDO_ILIM_MA,
1254 MAX_LDO_ILIM_MA);
1255 return -EINVAL;
1256 }
1257
1258 /* LDO soft-start (SS) configuration */
1259 lcdb->ldo.soft_start_us = -EINVAL;
1260 of_property_read_u32(node, "qcom,ldo-soft-start-us",
1261 &lcdb->ldo.soft_start_us);
1262
1263 return 0;
1264}
1265
1266static int qpnp_lcdb_ncp_dt_init(struct qpnp_lcdb *lcdb)
1267{
1268 int rc = 0;
1269 struct device_node *node = lcdb->ncp.node;
1270
1271 /* NCP output voltage */
1272 lcdb->ncp.voltage_mv = -EINVAL;
1273 rc = of_property_read_u32(node, "qcom,ncp-voltage-mv",
1274 &lcdb->ncp.voltage_mv);
1275 if (!rc && !is_between(lcdb->ncp.voltage_mv, MIN_VOLTAGE_MV,
1276 MAX_VOLTAGE_MV)) {
1277 pr_err("Invalid NCP voltage %dmv (min=%d max=%d)\n",
1278 lcdb->ldo.voltage_mv, MIN_VOLTAGE_MV, MAX_VOLTAGE_MV);
1279 return -EINVAL;
1280 }
1281
1282 /* NCP PD configuration */
1283 lcdb->ncp.pd = -EINVAL;
1284 of_property_read_u32(node, "qcom,ncp-pd", &lcdb->ncp.pd);
1285
1286 lcdb->ncp.pd_strength = -EINVAL;
1287 of_property_read_u32(node, "qcom,ncp-pd-strength",
1288 &lcdb->ncp.pd_strength);
1289
1290 /* NCP ILIM configuration */
1291 lcdb->ncp.ilim_ma = -EINVAL;
1292 rc = of_property_read_u32(node, "qcom,ncp-ilim-ma", &lcdb->ncp.ilim_ma);
1293 if (!rc && !is_between(lcdb->ncp.ilim_ma, MIN_NCP_ILIM_MA,
1294 MAX_NCP_ILIM_MA)) {
1295 pr_err("Invalid ilim_ma %d (min=%d, max=%d)\n",
1296 lcdb->ncp.ilim_ma, MIN_NCP_ILIM_MA, MAX_NCP_ILIM_MA);
1297 return -EINVAL;
1298 }
1299
1300 /* NCP soft-start (SS) configuration */
1301 lcdb->ncp.soft_start_us = -EINVAL;
1302 of_property_read_u32(node, "qcom,ncp-soft-start-us",
1303 &lcdb->ncp.soft_start_us);
1304
1305 return 0;
1306}
1307
1308static int qpnp_lcdb_bst_dt_init(struct qpnp_lcdb *lcdb)
1309{
1310 int rc = 0;
1311 struct device_node *node = lcdb->bst.node;
1312
1313 /* Boost PD configuration */
1314 lcdb->bst.pd = -EINVAL;
1315 of_property_read_u32(node, "qcom,bst-pd", &lcdb->bst.pd);
1316
1317 lcdb->bst.pd_strength = -EINVAL;
1318 of_property_read_u32(node, "qcom,bst-pd-strength",
1319 &lcdb->bst.pd_strength);
1320
1321 /* Boost ILIM */
1322 lcdb->bst.ilim_ma = -EINVAL;
1323 rc = of_property_read_u32(node, "qcom,bst-ilim-ma", &lcdb->bst.ilim_ma);
1324 if (!rc && !is_between(lcdb->bst.ilim_ma, MIN_BST_ILIM_MA,
1325 MAX_BST_ILIM_MA)) {
1326 pr_err("Invalid ilim_ma %d (min=%d, max=%d)\n",
1327 lcdb->bst.ilim_ma, MIN_BST_ILIM_MA, MAX_BST_ILIM_MA);
1328 return -EINVAL;
1329 }
1330
1331 /* Boost PS configuration */
1332 lcdb->bst.ps = -EINVAL;
1333 of_property_read_u32(node, "qcom,bst-ps", &lcdb->bst.ps);
1334
1335 lcdb->bst.ps_threshold = -EINVAL;
1336 rc = of_property_read_u32(node, "qcom,bst-ps-threshold-ma",
1337 &lcdb->bst.ps_threshold);
1338 if (!rc && !is_between(lcdb->bst.ps_threshold,
1339 MIN_BST_PS_MA, MAX_BST_PS_MA)) {
1340 pr_err("Invalid bst ps_threshold %d (min=%d, max=%d)\n",
1341 lcdb->bst.ps_threshold, MIN_BST_PS_MA, MAX_BST_PS_MA);
1342 return -EINVAL;
1343 }
1344
1345 return 0;
1346}
1347
1348static int qpnp_lcdb_init_ldo(struct qpnp_lcdb *lcdb)
1349{
1350 int rc = 0, ilim_ma;
1351 u8 val = 0;
1352
1353 /* configure parameters only if LCDB is disabled */
1354 if (!is_lcdb_enabled(lcdb)) {
1355 if (lcdb->ldo.voltage_mv != -EINVAL) {
1356 rc = qpnp_lcdb_set_voltage(lcdb,
1357 lcdb->ldo.voltage_mv, LDO);
1358 if (rc < 0) {
1359 pr_err("Failed to set voltage rc=%d\n", rc);
1360 return rc;
1361 }
1362 }
1363
1364 if (lcdb->ldo.pd != -EINVAL) {
1365 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
1366 LCDB_LDO_PD_CTL_REG, LDO_DIS_PULLDOWN_BIT,
1367 lcdb->ldo.pd ? 0 : LDO_DIS_PULLDOWN_BIT);
1368 if (rc < 0) {
1369 pr_err("Failed to configure LDO PD rc=%d\n",
1370 rc);
1371 return rc;
1372 }
1373 }
1374
1375 if (lcdb->ldo.pd_strength != -EINVAL) {
1376 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
1377 LCDB_LDO_PD_CTL_REG, LDO_PD_STRENGTH_BIT,
1378 lcdb->ldo.pd_strength ?
1379 LDO_PD_STRENGTH_BIT : 0);
1380 if (rc < 0) {
1381 pr_err("Failed to configure LDO PD strength %s rc=%d",
1382 lcdb->ldo.pd_strength ?
1383 "(strong)" : "(weak)", rc);
1384 return rc;
1385 }
1386 }
1387
1388 if (lcdb->ldo.ilim_ma != -EINVAL) {
1389 ilim_ma = lcdb->ldo.ilim_ma - MIN_LDO_ILIM_MA;
1390 ilim_ma /= LDO_ILIM_STEP_MA;
1391 val = (ilim_ma & SET_LDO_ILIM_MASK) | EN_LDO_ILIM_BIT;
1392 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
1393 LCDB_LDO_ILIM_CTL1_REG,
1394 SET_LDO_ILIM_MASK | EN_LDO_ILIM_BIT,
1395 val);
1396 if (rc < 0) {
1397 pr_err("Failed to configure LDO ilim_ma (CTL1=%d) rc=%d",
1398 val, rc);
1399 return rc;
1400 }
1401
1402 val = ilim_ma & SET_LDO_ILIM_MASK;
1403 rc = qpnp_lcdb_masked_write(lcdb,
1404 lcdb->base + LCDB_LDO_ILIM_CTL2_REG,
1405 SET_LDO_ILIM_MASK, val);
1406 if (rc < 0) {
1407 pr_err("Failed to configure LDO ilim_ma (CTL2=%d) rc=%d",
1408 val, rc);
1409 return rc;
1410 }
1411 }
1412
1413 if (lcdb->ldo.soft_start_us != -EINVAL) {
1414 rc = qpnp_lcdb_set_soft_start(lcdb,
1415 lcdb->ldo.soft_start_us, LDO);
1416 if (rc < 0) {
1417 pr_err("Failed to set LDO soft_start rc=%d\n",
1418 rc);
1419 return rc;
1420 }
1421 }
1422 }
1423
1424 rc = qpnp_lcdb_get_voltage(lcdb, &lcdb->ldo.voltage_mv, LDO);
1425 if (rc < 0) {
1426 pr_err("Failed to get LDO volatge rc=%d\n", rc);
1427 return rc;
1428 }
1429
1430 rc = qpnp_lcdb_read(lcdb, lcdb->base +
1431 LCDB_LDO_VREG_OK_CTL_REG, &val, 1);
1432 if (rc < 0) {
1433 pr_err("Failed to read ldo_vreg_ok rc=%d\n", rc);
1434 return rc;
1435 }
1436 lcdb->ldo.vreg_ok_dbc_us = dbc_us[val & VREG_OK_DEB_MASK];
1437
1438 rc = qpnp_lcdb_read(lcdb, lcdb->base +
1439 LCDB_LDO_SOFT_START_CTL_REG, &val, 1);
1440 if (rc < 0) {
1441 pr_err("Failed to read ldo_soft_start_ctl rc=%d\n", rc);
1442 return rc;
1443 }
1444 lcdb->ldo.soft_start_us = soft_start_us[val & SOFT_START_MASK];
1445
1446 rc = qpnp_lcdb_regulator_register(lcdb, LDO);
1447 if (rc < 0)
1448 pr_err("Failed to register ldo rc=%d\n", rc);
1449
1450 return rc;
1451}
1452
1453static int qpnp_lcdb_init_ncp(struct qpnp_lcdb *lcdb)
1454{
1455 int rc = 0, i = 0;
1456 u8 val = 0;
1457
1458 /* configure parameters only if LCDB is disabled */
1459 if (!is_lcdb_enabled(lcdb)) {
1460 if (lcdb->ncp.voltage_mv != -EINVAL) {
1461 rc = qpnp_lcdb_set_voltage(lcdb,
1462 lcdb->ncp.voltage_mv, NCP);
1463 if (rc < 0) {
1464 pr_err("Failed to set voltage rc=%d\n", rc);
1465 return rc;
1466 }
1467 }
1468
1469 if (lcdb->ncp.pd != -EINVAL) {
1470 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
1471 LCDB_NCP_PD_CTL_REG, NCP_DIS_PULLDOWN_BIT,
1472 lcdb->ncp.pd ? 0 : NCP_DIS_PULLDOWN_BIT);
1473 if (rc < 0) {
1474 pr_err("Failed to configure NCP PD rc=%d\n",
1475 rc);
1476 return rc;
1477 }
1478 }
1479
1480 if (lcdb->ncp.pd_strength != -EINVAL) {
1481 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
1482 LCDB_NCP_PD_CTL_REG, NCP_PD_STRENGTH_BIT,
1483 lcdb->ncp.pd_strength ?
1484 NCP_PD_STRENGTH_BIT : 0);
1485 if (rc < 0) {
1486 pr_err("Failed to configure NCP PD strength %s rc=%d",
1487 lcdb->ncp.pd_strength ?
1488 "(strong)" : "(weak)", rc);
1489 return rc;
1490 }
1491 }
1492
1493 if (lcdb->ncp.ilim_ma != -EINVAL) {
1494 while (lcdb->ncp.ilim_ma > ncp_ilim_ma[i])
1495 i++;
1496 val = (i == 0) ? 0 : i - 1;
1497 val = (lcdb->ncp.ilim_ma & SET_NCP_ILIM_MASK) |
1498 EN_NCP_ILIM_BIT;
1499 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
1500 LCDB_NCP_ILIM_CTL1_REG,
1501 SET_NCP_ILIM_MASK | EN_NCP_ILIM_BIT, val);
1502 if (rc < 0) {
1503 pr_err("Failed to configure NCP ilim_ma (CTL1=%d) rc=%d",
1504 val, rc);
1505 return rc;
1506 }
1507 val = lcdb->ncp.ilim_ma & SET_NCP_ILIM_MASK;
1508 rc = qpnp_lcdb_masked_write(lcdb,
1509 lcdb->base + LCDB_NCP_ILIM_CTL2_REG,
1510 SET_NCP_ILIM_MASK, val);
1511 if (rc < 0) {
1512 pr_err("Failed to configure NCP ilim_ma (CTL2=%d) rc=%d",
1513 val, rc);
1514 return rc;
1515 }
1516 }
1517
1518 if (lcdb->ncp.soft_start_us != -EINVAL) {
1519 rc = qpnp_lcdb_set_soft_start(lcdb,
1520 lcdb->ncp.soft_start_us, NCP);
1521 if (rc < 0) {
1522 pr_err("Failed to set NCP soft_start rc=%d\n",
1523 rc);
1524 return rc;
1525 }
1526 }
1527 }
1528
1529 rc = qpnp_lcdb_get_voltage(lcdb, &lcdb->ncp.voltage_mv, NCP);
1530 if (rc < 0) {
1531 pr_err("Failed to get NCP volatge rc=%d\n", rc);
1532 return rc;
1533 }
1534
1535 rc = qpnp_lcdb_read(lcdb, lcdb->base +
1536 LCDB_NCP_VREG_OK_CTL_REG, &val, 1);
1537 if (rc < 0) {
1538 pr_err("Failed to read ncp_vreg_ok rc=%d\n", rc);
1539 return rc;
1540 }
1541 lcdb->ncp.vreg_ok_dbc_us = dbc_us[val & VREG_OK_DEB_MASK];
1542
1543 rc = qpnp_lcdb_read(lcdb, lcdb->base +
1544 LCDB_NCP_SOFT_START_CTL_REG, &val, 1);
1545 if (rc < 0) {
1546 pr_err("Failed to read ncp_soft_start_ctl rc=%d\n", rc);
1547 return rc;
1548 }
1549 lcdb->ncp.soft_start_us = soft_start_us[val & SOFT_START_MASK];
1550
1551 rc = qpnp_lcdb_regulator_register(lcdb, NCP);
1552 if (rc < 0)
1553 pr_err("Failed to register NCP rc=%d\n", rc);
1554
1555 return rc;
1556}
1557
1558static int qpnp_lcdb_init_bst(struct qpnp_lcdb *lcdb)
1559{
1560 int rc = 0;
1561 u8 val = 0;
1562
1563 /* configure parameters only if LCDB is disabled */
1564 if (!is_lcdb_enabled(lcdb)) {
1565 if (lcdb->bst.pd != -EINVAL) {
1566 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
1567 LCDB_BST_PD_CTL_REG, BOOST_DIS_PULLDOWN_BIT,
1568 lcdb->bst.pd ? 0 : BOOST_DIS_PULLDOWN_BIT);
1569 if (rc < 0) {
1570 pr_err("Failed to configure BST PD rc=%d\n",
1571 rc);
1572 return rc;
1573 }
1574 }
1575
1576 if (lcdb->bst.pd_strength != -EINVAL) {
1577 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
1578 LCDB_NCP_PD_CTL_REG, BOOST_PD_STRENGTH_BIT,
1579 lcdb->bst.pd_strength ?
1580 BOOST_PD_STRENGTH_BIT : 0);
1581 if (rc < 0) {
1582 pr_err("Failed to configure NCP PD strength %s rc=%d",
1583 lcdb->bst.pd_strength ?
1584 "(strong)" : "(weak)", rc);
1585 return rc;
1586 }
1587 }
1588
1589 if (lcdb->bst.ilim_ma != -EINVAL) {
1590 val = (lcdb->bst.ilim_ma / MIN_BST_ILIM_MA) - 1;
1591 val = (lcdb->bst.ilim_ma & SET_BST_ILIM_MASK) |
1592 EN_BST_ILIM_BIT;
1593 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
1594 LCDB_BST_ILIM_CTL_REG,
1595 SET_BST_ILIM_MASK | EN_BST_ILIM_BIT, val);
1596 if (rc < 0) {
1597 pr_err("Failed to configure BST ilim_ma rc=%d",
1598 rc);
1599 return rc;
1600 }
1601 }
1602
1603 if (lcdb->bst.ps != -EINVAL) {
1604 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
1605 LCDB_PS_CTL_REG, EN_PS_BIT,
1606 &lcdb->bst.ps ? EN_PS_BIT : 0);
1607 if (rc < 0) {
1608 pr_err("Failed to disable BST PS rc=%d", rc);
1609 return rc;
1610 }
1611 }
1612
1613 if (lcdb->bst.ps_threshold != -EINVAL) {
1614 val = (lcdb->bst.ps_threshold - MIN_BST_PS_MA) / 10;
1615 val = (lcdb->bst.ps_threshold & PS_THRESHOLD_MASK) |
1616 EN_PS_BIT;
1617 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
1618 LCDB_PS_CTL_REG,
1619 PS_THRESHOLD_MASK | EN_PS_BIT,
1620 val);
1621 if (rc < 0) {
1622 pr_err("Failed to configure BST PS threshold rc=%d",
1623 rc);
1624 return rc;
1625 }
1626 }
1627 }
1628
1629 rc = qpnp_lcdb_get_voltage(lcdb, &lcdb->bst.voltage_mv, BST);
1630 if (rc < 0) {
1631 pr_err("Failed to get BST volatge rc=%d\n", rc);
1632 return rc;
1633 }
1634
1635 rc = qpnp_lcdb_read(lcdb, lcdb->base +
1636 LCDB_BST_VREG_OK_CTL_REG, &val, 1);
1637 if (rc < 0) {
1638 pr_err("Failed to read bst_vreg_ok rc=%d\n", rc);
1639 return rc;
1640 }
1641 lcdb->bst.vreg_ok_dbc_us = dbc_us[val & VREG_OK_DEB_MASK];
1642
1643 rc = qpnp_lcdb_read(lcdb, lcdb->base +
1644 LCDB_SOFT_START_CTL_REG, &val, 1);
1645 if (rc < 0) {
1646 pr_err("Failed to read ncp_soft_start_ctl rc=%d\n", rc);
1647 return rc;
1648 }
1649 lcdb->bst.soft_start_us = (val & SOFT_START_MASK) * 200 + 200;
1650
1651 return 0;
1652}
1653
1654static int qpnp_lcdb_hw_init(struct qpnp_lcdb *lcdb)
1655{
1656 int rc = 0;
1657 u8 val = 0;
1658
1659 rc = qpnp_lcdb_init_bst(lcdb);
1660 if (rc < 0) {
1661 pr_err("Failed to initialize BOOST rc=%d\n", rc);
1662 return rc;
1663 }
1664
1665 rc = qpnp_lcdb_init_ldo(lcdb);
1666 if (rc < 0) {
1667 pr_err("Failed to initialize LDO rc=%d\n", rc);
1668 return rc;
1669 }
1670
1671 rc = qpnp_lcdb_init_ncp(lcdb);
1672 if (rc < 0) {
1673 pr_err("Failed to initialize NCP rc=%d\n", rc);
1674 return rc;
1675 }
1676
Anirudh Ghayal264f9272017-03-05 22:34:37 +05301677 if (lcdb->sc_irq >= 0) {
1678 lcdb->sc_count = 0;
1679 rc = devm_request_threaded_irq(lcdb->dev, lcdb->sc_irq,
1680 NULL, qpnp_lcdb_sc_irq_handler, IRQF_ONESHOT,
1681 "qpnp_lcdb_sc_irq", lcdb);
1682 if (rc < 0) {
1683 pr_err("Unable to request sc(%d) irq rc=%d\n",
1684 lcdb->sc_irq, rc);
1685 return rc;
1686 }
1687 }
1688
David Collins8885f792017-01-26 14:36:34 -08001689 if (!is_lcdb_enabled(lcdb)) {
1690 rc = qpnp_lcdb_read(lcdb, lcdb->base +
1691 LCDB_MODULE_RDY_REG, &val, 1);
1692 if (rc < 0) {
1693 pr_err("Failed to read MODULE_RDY rc=%d\n", rc);
1694 return rc;
1695 }
1696 if (!(val & MODULE_RDY_BIT)) {
1697 rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
1698 LCDB_MODULE_RDY_REG, MODULE_RDY_BIT,
1699 MODULE_RDY_BIT);
1700 if (rc < 0) {
1701 pr_err("Failed to set MODULE RDY rc=%d\n", rc);
1702 return rc;
1703 }
1704 }
1705 } else {
1706 /* module already enabled */
1707 lcdb->lcdb_enabled = true;
1708 }
1709
1710 return 0;
1711}
1712
1713static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb)
1714{
1715 int rc = 0;
1716 const char *label;
1717 struct device_node *temp, *node = lcdb->dev->of_node;
1718
1719 for_each_available_child_of_node(node, temp) {
1720 rc = of_property_read_string(temp, "label", &label);
1721 if (rc < 0) {
1722 pr_err("Failed to read label rc=%d\n", rc);
1723 return rc;
1724 }
1725
1726 if (!strcmp(label, "ldo")) {
1727 lcdb->ldo.node = temp;
1728 rc = qpnp_lcdb_ldo_dt_init(lcdb);
1729 } else if (!strcmp(label, "ncp")) {
1730 lcdb->ncp.node = temp;
1731 rc = qpnp_lcdb_ncp_dt_init(lcdb);
1732 } else if (!strcmp(label, "bst")) {
1733 lcdb->bst.node = temp;
1734 rc = qpnp_lcdb_bst_dt_init(lcdb);
1735 } else {
1736 pr_err("Failed to identify label %s\n", label);
1737 return -EINVAL;
1738 }
1739 if (rc < 0) {
1740 pr_err("Failed to register %s module\n", label);
1741 return rc;
1742 }
1743 }
1744
Anirudh Ghayal941c0c22017-02-23 14:31:29 +05301745 lcdb->force_module_reenable = of_property_read_bool(node,
1746 "qcom,force-module-reenable");
1747
David Collins8885f792017-01-26 14:36:34 -08001748 if (of_property_read_bool(node, "qcom,ttw-enable")) {
1749 rc = qpnp_lcdb_parse_ttw(lcdb);
1750 if (rc < 0) {
1751 pr_err("Failed to parse ttw-params rc=%d\n", rc);
1752 return rc;
1753 }
1754 lcdb->ttw_enable = true;
1755 }
1756
Anirudh Ghayal264f9272017-03-05 22:34:37 +05301757 lcdb->sc_irq = platform_get_irq_byname(lcdb->pdev, "sc-irq");
1758 if (lcdb->sc_irq < 0)
1759 pr_debug("sc irq is not defined\n");
1760
David Collins8885f792017-01-26 14:36:34 -08001761 return rc;
1762}
1763
1764static int qpnp_lcdb_regulator_probe(struct platform_device *pdev)
1765{
1766 int rc;
1767 struct device_node *node;
1768 struct qpnp_lcdb *lcdb;
1769
1770 node = pdev->dev.of_node;
1771 if (!node) {
1772 pr_err("No nodes defined\n");
1773 return -ENODEV;
1774 }
1775
1776 lcdb = devm_kzalloc(&pdev->dev, sizeof(*lcdb), GFP_KERNEL);
1777 if (!lcdb)
1778 return -ENOMEM;
1779
1780 rc = of_property_read_u32(node, "reg", &lcdb->base);
1781 if (rc < 0) {
1782 pr_err("Failed to find reg node rc=%d\n", rc);
1783 return rc;
1784 }
1785
1786 lcdb->regmap = dev_get_regmap(pdev->dev.parent, NULL);
1787 if (!lcdb->regmap) {
1788 pr_err("Failed to get the regmap handle rc=%d\n", rc);
1789 return -EINVAL;
1790 }
1791
1792 lcdb->dev = &pdev->dev;
1793 lcdb->pdev = pdev;
1794 mutex_init(&lcdb->lcdb_mutex);
1795 mutex_init(&lcdb->read_write_mutex);
1796
1797 rc = qpnp_lcdb_parse_dt(lcdb);
1798 if (rc < 0) {
1799 pr_err("Failed to parse dt rc=%d\n", rc);
1800 return rc;
1801 }
1802
1803 rc = qpnp_lcdb_hw_init(lcdb);
1804 if (rc < 0)
1805 pr_err("Failed to initialize LCDB module rc=%d\n", rc);
1806 else
1807 pr_info("LCDB module successfully registered! lcdb_en=%d ldo_voltage=%dmV ncp_voltage=%dmV bst_voltage=%dmV\n",
1808 lcdb->lcdb_enabled, lcdb->ldo.voltage_mv,
1809 lcdb->ncp.voltage_mv, lcdb->bst.voltage_mv);
1810
1811 return rc;
1812}
1813
1814static int qpnp_lcdb_regulator_remove(struct platform_device *pdev)
1815{
1816 struct qpnp_lcdb *lcdb = dev_get_drvdata(&pdev->dev);
1817
1818 mutex_destroy(&lcdb->lcdb_mutex);
1819 mutex_destroy(&lcdb->read_write_mutex);
1820
1821 return 0;
1822}
1823
1824static const struct of_device_id lcdb_match_table[] = {
1825 { .compatible = QPNP_LCDB_REGULATOR_DRIVER_NAME, },
1826 { },
1827};
1828
1829static struct platform_driver qpnp_lcdb_regulator_driver = {
1830 .driver = {
1831 .name = QPNP_LCDB_REGULATOR_DRIVER_NAME,
1832 .of_match_table = lcdb_match_table,
1833 },
1834 .probe = qpnp_lcdb_regulator_probe,
1835 .remove = qpnp_lcdb_regulator_remove,
1836};
1837
1838static int __init qpnp_lcdb_regulator_init(void)
1839{
1840 return platform_driver_register(&qpnp_lcdb_regulator_driver);
1841}
1842arch_initcall(qpnp_lcdb_regulator_init);
1843
1844static void __exit qpnp_lcdb_regulator_exit(void)
1845{
1846 platform_driver_unregister(&qpnp_lcdb_regulator_driver);
1847}
1848module_exit(qpnp_lcdb_regulator_exit);
1849
1850MODULE_DESCRIPTION("QPNP LCDB regulator driver");
1851MODULE_LICENSE("GPL v2");