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