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