blob: fb778db752b5276b81934cf57f9615b52bdbe0a3 [file] [log] [blame]
Abhijeet Dharmapurikar21f9af1d2016-05-10 18:48:39 -07001/* Copyright (c) 2016 The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/device.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/regmap.h>
17#include <linux/power_supply.h>
18#include <linux/interrupt.h>
19#include <linux/of.h>
20#include <linux/of_irq.h>
21#include <linux/qpnp/qpnp-revid.h>
22#include "pmic-voter.h"
23
24#define QNOVO_REVISION1 0x00
25#define QNOVO_REVISION2 0x01
26#define QNOVO_PERPH_TYPE 0x04
27#define QNOVO_PERPH_SUBTYPE 0x05
28#define QNOVO_PTTIME_STS 0x07
29#define QNOVO_PTRAIN_STS 0x08
30#define QNOVO_ERROR_STS 0x09
31#define QNOVO_ERROR_BIT BIT(0)
32#define QNOVO_INT_RT_STS 0x10
33#define QNOVO_INT_SET_TYPE 0x11
34#define QNOVO_INT_POLARITY_HIGH 0x12
35#define QNOVO_INT_POLARITY_LOW 0x13
36#define QNOVO_INT_LATCHED_CLR 0x14
37#define QNOVO_INT_EN_SET 0x15
38#define QNOVO_INT_EN_CLR 0x16
39#define QNOVO_INT_LATCHED_STS 0x18
40#define QNOVO_INT_PENDING_STS 0x19
41#define QNOVO_INT_MID_SEL 0x1A
42#define QNOVO_INT_PRIORITY 0x1B
43#define QNOVO_PE_CTRL 0x40
44#define QNOVO_PREST1_CTRL 0x41
45#define QNOVO_PPULS1_LSB_CTRL 0x42
46#define QNOVO_PPULS1_MSB_CTRL 0x43
47#define QNOVO_NREST1_CTRL 0x44
48#define QNOVO_NPULS1_CTRL 0x45
49#define QNOVO_PPCNT_CTRL 0x46
50#define QNOVO_VLIM1_LSB_CTRL 0x47
51#define QNOVO_VLIM1_MSB_CTRL 0x48
52#define QNOVO_PTRAIN_EN 0x49
53#define QNOVO_PTRAIN_EN_BIT BIT(0)
54#define QNOVO_PE_CTRL2 0x4A
55#define QNOVO_PREST2_LSB_CTRL 0x50
56#define QNOVO_PREST2_MSB_CTRL 0x51
57#define QNOVO_PPULS2_LSB_CTRL 0x52
58#define QNOVO_PPULS2_MSB_CTRL 0x53
59#define QNOVO_NREST2_CTRL 0x54
60#define QNOVO_NPULS2_CTRL 0x55
61#define QNOVO_VLIM2_LSB_CTRL 0x56
62#define QNOVO_VLIM2_MSB_CTRL 0x57
63#define QNOVO_PVOLT1_LSB 0x60
64#define QNOVO_PVOLT1_MSB 0x61
65#define QNOVO_PCUR1_LSB 0x62
66#define QNOVO_PCUR1_MSB 0x63
67#define QNOVO_PVOLT2_LSB 0x70
68#define QNOVO_PVOLT2_MSB 0x71
69#define QNOVO_RVOLT2_LSB 0x72
70#define QNOVO_RVOLT2_MSB 0x73
71#define QNOVO_PCUR2_LSB 0x74
72#define QNOVO_PCUR2_MSB 0x75
73#define QNOVO_SCNT 0x80
74#define QNOVO_VMAX_LSB 0x90
75#define QNOVO_VMAX_MSB 0x91
76#define QNOVO_SNUM 0x92
77
78/* Registers ending in 0 imply external rsense */
79#define QNOVO_IADC_OFFSET_0 0xA0
80#define QNOVO_IADC_OFFSET_1 0xA1
81#define QNOVO_IADC_GAIN_0 0xA2
82#define QNOVO_IADC_GAIN_1 0xA3
83#define QNOVO_VADC_OFFSET 0xA4
84#define QNOVO_VADC_GAIN 0xA5
85#define QNOVO_IADC_GAIN_2 0xA6
86#define QNOVO_SPARE 0xA7
87#define QNOVO_STRM_CTRL 0xA8
88#define QNOVO_IADC_OFFSET_OVR_VAL 0xA9
89#define QNOVO_IADC_OFFSET_OVR 0xAA
90#define QNOVO_DISABLE_CHARGING 0xAB
91
92#define QNOVO_TR_IADC_OFFSET_0 0xF1
93#define QNOVO_TR_IADC_OFFSET_1 0xF2
94
95#define DRV_MAJOR_VERSION 1
96#define DRV_MINOR_VERSION 0
97
98#define IADC_LSB_NA 2441400
99#define VADC_LSB_NA 1220700
100#define GAIN_LSB_FACTOR 976560
101
102#define MIN_EN_UA 1000000
103
104#define USER_VOTER "user_voter"
105#define OK_TO_QNOVO_VOTER "ok_to_qnovo_voter"
106
107#define QNOVO_VOTER "qnovo_voter"
108
109struct qnovo_dt_props {
110 bool external_rsense;
111 struct device_node *revid_dev_node;
112};
113
114enum {
115 QNOVO_ERASE_OFFSET_WA_BIT = BIT(0),
116 QNOVO_NO_ERR_STS_BIT = BIT(1),
117};
118
119struct chg_props {
120 bool charging;
121 bool usb_online;
122 int usb_input_uA;
123 bool dc_online;
124 int dc_input_uA;
125};
126
127struct chg_status {
128 bool ok_to_qnovo;
129};
130
131struct qnovo {
132 int base;
133 struct mutex write_lock;
134 struct regmap *regmap;
135 struct qnovo_dt_props dt;
136 struct device *dev;
137 struct votable *disable_votable;
138 struct class qnovo_class;
139 struct pmic_revid_data *pmic_rev_id;
140 u32 wa_flags;
141 s64 external_offset_nA;
142 s64 internal_offset_nA;
143 s64 offset_nV;
144 s64 external_i_gain_mega;
145 s64 internal_i_gain_mega;
146 s64 v_gain_mega;
147 struct notifier_block nb;
148 struct power_supply *batt_psy;
149 struct power_supply *usb_psy;
150 struct power_supply *dc_psy;
151 struct chg_props cp;
152 struct chg_status cs;
153 struct work_struct status_change_work;
154 int fv_uV_request;
155 int fcc_uA_request;
Abhijeet Dharmapurikar99fb8942016-07-08 11:39:23 -0700156 struct votable *fcc_max_votable;
Abhijeet Dharmapurikar21f9af1d2016-05-10 18:48:39 -0700157 struct votable *fv_votable;
158};
159
160static int debug_mask;
161module_param_named(debug_mask, debug_mask, int, 0600);
162
163#define qnovo_dbg(chip, reason, fmt, ...) \
164 do { \
165 if (debug_mask & (reason)) \
166 dev_info(chip->dev, fmt, ##__VA_ARGS__); \
167 else \
168 dev_dbg(chip->dev, fmt, ##__VA_ARGS__); \
169 } while (0)
170
171static bool is_secure(struct qnovo *chip, int addr)
172{
173 /* assume everything above 0x40 is secure */
174 return (bool)(addr >= 0x40);
175}
176
177static int qnovo_read(struct qnovo *chip, u16 addr, u8 *buf, int len)
178{
179 return regmap_bulk_read(chip->regmap, chip->base + addr, buf, len);
180}
181
182static int qnovo_masked_write(struct qnovo *chip, u16 addr, u8 mask, u8 val)
183{
184 int rc = 0;
185
186 mutex_lock(&chip->write_lock);
187 if (is_secure(chip, addr)) {
188 rc = regmap_write(chip->regmap,
189 ((chip->base + addr) & ~(0xFF)) | 0xD0, 0xA5);
190 if (rc < 0)
191 goto unlock;
192 }
193
194 rc = regmap_update_bits(chip->regmap, chip->base + addr, mask, val);
195
196unlock:
197 mutex_unlock(&chip->write_lock);
198 return rc;
199}
200
201static int qnovo_write(struct qnovo *chip, u16 addr, u8 *buf, int len)
202{
203 int i, rc = 0;
204 bool is_start_secure, is_end_secure;
205
206 is_start_secure = is_secure(chip, addr);
207 is_end_secure = is_secure(chip, addr + len);
208
209 if (!is_start_secure && !is_end_secure) {
210 mutex_lock(&chip->write_lock);
211 rc = regmap_bulk_write(chip->regmap, chip->base + addr,
212 buf, len);
213 goto unlock;
214 }
215
216 mutex_lock(&chip->write_lock);
217 for (i = addr; i < addr + len; i++) {
218 if (is_secure(chip, i)) {
219 rc = regmap_write(chip->regmap,
220 ((chip->base + i) & ~(0xFF)) | 0xD0, 0xA5);
221 if (rc < 0)
222 goto unlock;
223 }
224 rc = regmap_write(chip->regmap, chip->base + i, buf[i - addr]);
225 if (rc < 0)
226 goto unlock;
227 }
228
229unlock:
230 mutex_unlock(&chip->write_lock);
231 return rc;
232}
233
234static int qnovo_disable_cb(struct votable *votable, void *data, int disable,
235 const char *client)
236{
237 struct qnovo *chip = data;
238 int rc = 0;
239
240 if (disable) {
241 if (chip->fv_uV_request != -EINVAL) {
242 if (chip->fv_votable)
243 vote(chip->fv_votable, QNOVO_VOTER, false, 0);
244 }
245 if (chip->fcc_uA_request != -EINVAL) {
Abhijeet Dharmapurikar99fb8942016-07-08 11:39:23 -0700246 if (chip->fcc_max_votable)
247 vote(chip->fcc_max_votable, QNOVO_VOTER,
248 false, 0);
Abhijeet Dharmapurikar21f9af1d2016-05-10 18:48:39 -0700249 }
250 }
251
252 rc = qnovo_masked_write(chip, QNOVO_PTRAIN_EN, QNOVO_PTRAIN_EN_BIT,
253 disable ? 0 : QNOVO_PTRAIN_EN_BIT);
254 if (rc < 0) {
255 dev_err(chip->dev, "Couldn't %s pulse train rc=%d\n",
256 disable ? "disable" : "enable", rc);
257 return rc;
258 }
259
260 if (!disable) {
261 if (chip->fv_uV_request != -EINVAL) {
262 if (!chip->fv_votable)
263 chip->fv_votable = find_votable("FV");
264 if (chip->fv_votable)
265 vote(chip->fv_votable, QNOVO_VOTER,
266 true, chip->fv_uV_request);
267 }
268 if (chip->fcc_uA_request != -EINVAL) {
Abhijeet Dharmapurikar99fb8942016-07-08 11:39:23 -0700269 if (!chip->fcc_max_votable)
270 chip->fcc_max_votable = find_votable("FCC_MAX");
271 if (chip->fcc_max_votable)
272 vote(chip->fcc_max_votable, QNOVO_VOTER,
Abhijeet Dharmapurikar21f9af1d2016-05-10 18:48:39 -0700273 true, chip->fcc_uA_request);
274 }
275 }
276
277 return rc;
278}
279
280static int qnovo_parse_dt(struct qnovo *chip)
281{
282 struct device_node *node = chip->dev->of_node;
283 int rc;
284
285 if (!node) {
286 pr_err("device tree node missing\n");
287 return -EINVAL;
288 }
289
290 rc = of_property_read_u32(node, "reg", &chip->base);
291 if (rc < 0) {
292 pr_err("Couldn't read base rc = %d\n", rc);
293 return rc;
294 }
295
296 chip->dt.external_rsense = of_property_read_bool(node,
297 "qcom,external-rsense");
298
299 chip->dt.revid_dev_node = of_parse_phandle(node, "qcom,pmic-revid", 0);
300 if (!chip->dt.revid_dev_node) {
301 pr_err("Missing qcom,pmic-revid property - driver failed\n");
302 return -EINVAL;
303 }
304
305 return 0;
306}
307
308static int qnovo_check_chg_version(struct qnovo *chip)
309{
310 int rc;
311
312 chip->pmic_rev_id = get_revid_data(chip->dt.revid_dev_node);
313 if (IS_ERR(chip->pmic_rev_id)) {
314 rc = PTR_ERR(chip->pmic_rev_id);
315 if (rc != -EPROBE_DEFER)
316 pr_err("Unable to get pmic_revid rc=%d\n", rc);
317 return rc;
318 }
319
Harry Yang2452b272017-03-06 13:56:14 -0800320 if ((chip->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE)
321 && (chip->pmic_rev_id->rev4 < PMI8998_V2P0_REV4)) {
Abhijeet Dharmapurikar21f9af1d2016-05-10 18:48:39 -0700322 chip->wa_flags |= QNOVO_ERASE_OFFSET_WA_BIT;
323 chip->wa_flags |= QNOVO_NO_ERR_STS_BIT;
324 }
325
326 return 0;
327}
328
329enum {
330 VER = 0,
331 OK_TO_QNOVO,
332 ENABLE,
333 FV_REQUEST,
334 FCC_REQUEST,
335 PE_CTRL_REG,
336 PE_CTRL2_REG,
337 PTRAIN_STS_REG,
338 INT_RT_STS_REG,
339 PREST1,
340 PPULS1,
341 NREST1,
342 NPULS1,
343 PPCNT,
344 VLIM1,
345 PVOLT1,
346 PCUR1,
347 PTTIME,
348 PREST2,
349 PPULS2,
350 NREST2,
351 NPULS2,
352 VLIM2,
353 PVOLT2,
354 RVOLT2,
355 PCUR2,
356 SCNT,
357 VMAX,
358 SNUM,
359 VBATT,
360 IBATT,
361 BATTTEMP,
362 BATTSOC,
363};
364
365struct param_info {
366 char *name;
367 int start_addr;
368 int num_regs;
369 int reg_to_unit_multiplier;
370 int reg_to_unit_divider;
371 int reg_to_unit_offset;
372 int min_val;
373 int max_val;
374 char *units_str;
375};
376
377static struct param_info params[] = {
378 [FV_REQUEST] = {
379 .units_str = "uV",
380 },
381 [FCC_REQUEST] = {
382 .units_str = "uA",
383 },
384 [PE_CTRL_REG] = {
385 .name = "CTRL_REG",
386 .start_addr = QNOVO_PE_CTRL,
387 .num_regs = 1,
388 .units_str = "",
389 },
390 [PE_CTRL2_REG] = {
391 .name = "PE_CTRL2_REG",
392 .start_addr = QNOVO_PE_CTRL2,
393 .num_regs = 1,
394 .units_str = "",
395 },
396 [PTRAIN_STS_REG] = {
397 .name = "PTRAIN_STS",
398 .start_addr = QNOVO_PTRAIN_STS,
399 .num_regs = 1,
400 .units_str = "",
401 },
402 [INT_RT_STS_REG] = {
403 .name = "INT_RT_STS",
404 .start_addr = QNOVO_INT_RT_STS,
405 .num_regs = 1,
406 .units_str = "",
407 },
408 [PREST1] = {
409 .name = "PREST1",
410 .start_addr = QNOVO_PREST1_CTRL,
411 .num_regs = 1,
412 .reg_to_unit_multiplier = 5,
413 .reg_to_unit_divider = 1,
414 .min_val = 5,
415 .max_val = 1275,
416 .units_str = "mS",
417 },
418 [PPULS1] = {
419 .name = "PPULS1",
420 .start_addr = QNOVO_PPULS1_LSB_CTRL,
421 .num_regs = 2,
422 .reg_to_unit_multiplier = 1600, /* converts to uC */
423 .reg_to_unit_divider = 1,
424 .min_val = 0,
425 .max_val = 104856000,
426 .units_str = "uC",
427 },
428 [NREST1] = {
429 .name = "NREST1",
430 .start_addr = QNOVO_NREST1_CTRL,
431 .num_regs = 1,
432 .reg_to_unit_multiplier = 5,
433 .reg_to_unit_divider = 1,
434 .min_val = 5,
435 .max_val = 1275,
436 .units_str = "mS",
437 },
438 [NPULS1] = {
439 .name = "NPULS1",
440 .start_addr = QNOVO_NPULS1_CTRL,
441 .num_regs = 1,
442 .reg_to_unit_multiplier = 5,
443 .reg_to_unit_divider = 1,
444 .min_val = 5,
445 .max_val = 1275,
446 .units_str = "mS",
447 },
448 [PPCNT] = {
449 .name = "PPCNT",
450 .start_addr = QNOVO_PPCNT_CTRL,
451 .num_regs = 1,
452 .reg_to_unit_multiplier = 1,
453 .reg_to_unit_divider = 1,
454 .units_str = "pulses",
455 },
456 [VLIM1] = {
457 .name = "VLIM1",
458 .start_addr = QNOVO_VLIM1_LSB_CTRL,
459 .num_regs = 2,
460 .reg_to_unit_multiplier = 610350, /* converts to nV */
461 .reg_to_unit_divider = 1,
462 .min_val = 0,
463 .max_val = 5000000,
464 .units_str = "uV",
465 },
466 [PVOLT1] = {
467 .name = "PVOLT1",
468 .start_addr = QNOVO_PVOLT1_LSB,
469 .num_regs = 2,
470 .reg_to_unit_multiplier = 610350, /* converts to nV */
471 .reg_to_unit_divider = 1,
472 .units_str = "uV",
473 },
474 [PCUR1] = {
475 .name = "PCUR1",
476 .start_addr = QNOVO_PCUR1_LSB,
477 .num_regs = 2,
478 .reg_to_unit_multiplier = 1220700, /* converts to nA */
479 .reg_to_unit_divider = 1,
480 .units_str = "uA",
481 },
482 [PTTIME] = {
483 .name = "PTTIME",
484 .start_addr = QNOVO_PTTIME_STS,
485 .num_regs = 1,
486 .reg_to_unit_multiplier = 2,
487 .reg_to_unit_divider = 1,
488 .min_val = 5,
489 .max_val = 1275,
490 .units_str = "S",
491 },
492 [PREST2] = {
493 .name = "PREST2",
494 .start_addr = QNOVO_PREST2_LSB_CTRL,
495 .num_regs = 2,
496 .reg_to_unit_multiplier = 5,
497 .reg_to_unit_divider = 1,
498 .min_val = 5,
499 .max_val = 327675,
500 .units_str = "mS",
501 },
502 [PPULS2] = {
503 .name = "PPULS2",
504 .start_addr = QNOVO_PPULS2_LSB_CTRL,
505 .num_regs = 2,
506 .reg_to_unit_multiplier = 1600, /* converts to uC */
507 .reg_to_unit_divider = 1,
508 .min_val = 0,
509 .max_val = 104856000,
510 .units_str = "uC",
511 },
512 [NREST2] = {
513 .name = "NREST2",
514 .start_addr = QNOVO_NREST2_CTRL,
515 .num_regs = 1,
516 .reg_to_unit_multiplier = 5,
517 .reg_to_unit_divider = 1,
518 .reg_to_unit_offset = -5,
519 .min_val = 5,
520 .max_val = 1280,
521 .units_str = "mS",
522 },
523 [NPULS2] = {
524 .name = "NPULS2",
525 .start_addr = QNOVO_NPULS2_CTRL,
526 .num_regs = 1,
527 .reg_to_unit_multiplier = 5,
528 .reg_to_unit_divider = 1,
529 .min_val = 5,
530 .max_val = 1275,
531 .units_str = "mS",
532 },
533 [VLIM2] = {
534 .name = "VLIM1",
535 .start_addr = QNOVO_VLIM2_LSB_CTRL,
536 .num_regs = 2,
537 .reg_to_unit_multiplier = 610350, /* converts to nV */
538 .reg_to_unit_divider = 1,
539 .min_val = 0,
540 .max_val = 5000000,
541 .units_str = "uV",
542 },
543 [PVOLT2] = {
544 .name = "PVOLT2",
545 .start_addr = QNOVO_PVOLT2_LSB,
546 .num_regs = 2,
547 .reg_to_unit_multiplier = 610350, /* converts to nV */
548 .reg_to_unit_divider = 1,
549 .units_str = "uV",
550 },
551 [RVOLT2] = {
552 .name = "RVOLT2",
553 .start_addr = QNOVO_RVOLT2_LSB,
554 .num_regs = 2,
555 .reg_to_unit_multiplier = 610350,
556 .reg_to_unit_divider = 1,
557 .units_str = "uV",
558 },
559 [PCUR2] = {
560 .name = "PCUR2",
561 .start_addr = QNOVO_PCUR2_LSB,
562 .num_regs = 2,
563 .reg_to_unit_multiplier = 1220700, /* converts to nA */
564 .reg_to_unit_divider = 1,
565 .units_str = "uA",
566 },
567 [SCNT] = {
568 .name = "SCNT",
569 .start_addr = QNOVO_SCNT,
570 .num_regs = 1,
571 .reg_to_unit_multiplier = 1,
572 .reg_to_unit_divider = 1,
573 .units_str = "pulses",
574 },
575 [VMAX] = {
576 .name = "VMAX",
577 .start_addr = QNOVO_VMAX_LSB,
578 .num_regs = 2,
579 .reg_to_unit_multiplier = 814000, /* converts to nV */
580 .reg_to_unit_divider = 1,
581 .units_str = "uV",
582 },
583 [SNUM] = {
584 .name = "SNUM",
585 .start_addr = QNOVO_SNUM,
586 .num_regs = 1,
587 .reg_to_unit_multiplier = 1,
588 .reg_to_unit_divider = 1,
589 .units_str = "pulses",
590 },
591 [VBATT] = {
592 .name = "POWER_SUPPLY_PROP_VOLTAGE_NOW",
593 .start_addr = POWER_SUPPLY_PROP_VOLTAGE_NOW,
594 .units_str = "uV",
595 },
596 [IBATT] = {
597 .name = "POWER_SUPPLY_PROP_CURRENT_NOW",
598 .start_addr = POWER_SUPPLY_PROP_CURRENT_NOW,
599 .units_str = "uA",
600 },
601 [BATTTEMP] = {
602 .name = "POWER_SUPPLY_PROP_TEMP",
603 .start_addr = POWER_SUPPLY_PROP_TEMP,
604 .units_str = "uV",
605 },
606 [BATTSOC] = {
607 .name = "POWER_SUPPLY_PROP_CAPACITY",
608 .start_addr = POWER_SUPPLY_PROP_CAPACITY,
609 .units_str = "%",
610 },
611};
612
613static struct class_attribute qnovo_attributes[];
614
615static ssize_t version_show(struct class *c, struct class_attribute *attr,
616 char *buf)
617{
618 return snprintf(buf, PAGE_SIZE, "%d.%d\n",
619 DRV_MAJOR_VERSION, DRV_MINOR_VERSION);
620}
621
622static ssize_t ok_to_qnovo_show(struct class *c, struct class_attribute *attr,
623 char *buf)
624{
625 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
626
627 return snprintf(buf, PAGE_SIZE, "%d\n", chip->cs.ok_to_qnovo);
628}
629
630static ssize_t enable_show(struct class *c, struct class_attribute *attr,
631 char *ubuf)
632{
633 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
634 int val;
635
636 val = get_client_vote(chip->disable_votable, USER_VOTER);
637 return snprintf(ubuf, PAGE_SIZE, "%d\n", val);
638}
639
640static ssize_t enable_store(struct class *c, struct class_attribute *attr,
641 const char *ubuf, size_t count)
642{
643 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
644 unsigned long val;
645 bool disable;
646
647 if (kstrtoul(ubuf, 10, &val))
648 return -EINVAL;
649
650 disable = !val;
651
652 vote(chip->disable_votable, USER_VOTER, disable, 0);
653 return count;
654}
655
656static ssize_t val_show(struct class *c, struct class_attribute *attr,
657 char *ubuf)
658{
659 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
660 int i = attr - qnovo_attributes;
661 int val = 0;
662
663 if (i == FV_REQUEST)
664 val = chip->fv_uV_request;
665
666 if (i == FCC_REQUEST)
667 val = chip->fcc_uA_request;
668
669 return snprintf(ubuf, PAGE_SIZE, "%d%s\n", val, params[i].units_str);
670}
671
672static ssize_t val_store(struct class *c, struct class_attribute *attr,
673 const char *ubuf, size_t count)
674{
675 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
676 int i = attr - qnovo_attributes;
677 unsigned long val;
678
679 if (kstrtoul(ubuf, 10, &val))
680 return -EINVAL;
681
682 if (i == FV_REQUEST)
683 chip->fv_uV_request = val;
684
685 if (i == FCC_REQUEST)
686 chip->fcc_uA_request = val;
687
688 return count;
689}
690
691static ssize_t reg_show(struct class *c, struct class_attribute *attr,
692 char *ubuf)
693{
694 int i = attr - qnovo_attributes;
695 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
696 u8 buf[2] = {0, 0};
697 u16 regval;
698 int rc;
699
700 rc = qnovo_read(chip, params[i].start_addr, buf, params[i].num_regs);
701 if (rc < 0) {
702 pr_err("Couldn't read %s rc = %d\n", params[i].name, rc);
703 return -EINVAL;
704 }
705 regval = buf[1] << 8 | buf[0];
706
707 return snprintf(ubuf, PAGE_SIZE, "0x%04x%s\n",
708 regval, params[i].units_str);
709}
710
711static ssize_t reg_store(struct class *c, struct class_attribute *attr,
712 const char *ubuf, size_t count)
713{
714 int i = attr - qnovo_attributes;
715 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
716 u8 buf[2] = {0, 0};
717 unsigned long val;
718 int rc;
719
720 if (kstrtoul(ubuf, 16, &val))
721 return -EINVAL;
722
723 buf[0] = val & 0xFF;
724 buf[1] = (val >> 8) & 0xFF;
725
726 rc = qnovo_write(chip, params[i].start_addr, buf, params[i].num_regs);
727 if (rc < 0) {
728 pr_err("Couldn't write %s rc = %d\n", params[i].name, rc);
729 return -EINVAL;
730 }
731 return count;
732}
733
734static ssize_t time_show(struct class *c, struct class_attribute *attr,
735 char *ubuf)
736{
737 int i = attr - qnovo_attributes;
738 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
739 u8 buf[2] = {0, 0};
740 u16 regval;
741 int val;
742 int rc;
743
744 rc = qnovo_read(chip, params[i].start_addr, buf, params[i].num_regs);
745 if (rc < 0) {
746 pr_err("Couldn't read %s rc = %d\n", params[i].name, rc);
747 return -EINVAL;
748 }
749 regval = buf[1] << 8 | buf[0];
750
751 val = ((regval * params[i].reg_to_unit_multiplier)
752 / params[i].reg_to_unit_divider)
753 - params[i].reg_to_unit_offset;
754
755 return snprintf(ubuf, PAGE_SIZE, "%d%s\n", val, params[i].units_str);
756}
757
758static ssize_t time_store(struct class *c, struct class_attribute *attr,
759 const char *ubuf, size_t count)
760{
761 int i = attr - qnovo_attributes;
762 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
763 u8 buf[2] = {0, 0};
764 u16 regval;
765 unsigned long val;
766 int rc;
767
768 if (kstrtoul(ubuf, 10, &val))
769 return -EINVAL;
770
771 if (val < params[i].min_val || val > params[i].max_val) {
772 pr_err("Out of Range %d%s for %s\n", (int)val,
773 params[i].units_str,
774 params[i].name);
775 return -ERANGE;
776 }
777
778 regval = (((int)val + params[i].reg_to_unit_offset)
779 * params[i].reg_to_unit_divider)
780 / params[i].reg_to_unit_multiplier;
781 buf[0] = regval & 0xFF;
782 buf[1] = (regval >> 8) & 0xFF;
783
784 rc = qnovo_write(chip, params[i].start_addr, buf, params[i].num_regs);
785 if (rc < 0) {
786 pr_err("Couldn't write %s rc = %d\n", params[i].name, rc);
787 return -EINVAL;
788 }
789
790 return count;
791}
792
793static ssize_t current_show(struct class *c, struct class_attribute *attr,
794 char *ubuf)
795{
796 int i = attr - qnovo_attributes;
797 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
798 u8 buf[2] = {0, 0};
799 int rc;
800 int comp_val_uA;
801 s64 regval_nA;
802 s64 gain, offset_nA, comp_val_nA;
803
804 rc = qnovo_read(chip, params[i].start_addr, buf, params[i].num_regs);
805 if (rc < 0) {
806 pr_err("Couldn't read %s rc = %d\n", params[i].name, rc);
807 return -EINVAL;
808 }
809 regval_nA = buf[1] << 8 | buf[0];
810 regval_nA = div_s64(regval_nA * params[i].reg_to_unit_multiplier,
811 params[i].reg_to_unit_divider)
812 - params[i].reg_to_unit_offset;
813
814 if (chip->dt.external_rsense) {
815 offset_nA = chip->external_offset_nA;
816 gain = chip->external_i_gain_mega;
817 } else {
818 offset_nA = chip->internal_offset_nA;
819 gain = chip->internal_i_gain_mega;
820 }
821
822 comp_val_nA = div_s64(regval_nA * gain, 1000000) + offset_nA;
823 comp_val_uA = comp_val_nA / 1000;
824
825 return snprintf(ubuf, PAGE_SIZE, "%d%s\n",
826 comp_val_uA, params[i].units_str);
827}
828
829static ssize_t voltage_show(struct class *c, struct class_attribute *attr,
830 char *ubuf)
831{
832 int i = attr - qnovo_attributes;
833 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
834 u8 buf[2] = {0, 0};
835 int rc;
836 int comp_val_uV;
837 s64 regval_nV;
838 s64 gain, offset_nV, comp_val_nV;
839
840 rc = qnovo_read(chip, params[i].start_addr, buf, params[i].num_regs);
841 if (rc < 0) {
842 pr_err("Couldn't read %s rc = %d\n", params[i].name, rc);
843 return -EINVAL;
844 }
845 regval_nV = buf[1] << 8 | buf[0];
846 regval_nV = div_s64(regval_nV * params[i].reg_to_unit_multiplier,
847 params[i].reg_to_unit_divider)
848 - params[i].reg_to_unit_offset;
849
850 offset_nV = chip->offset_nV;
851 gain = chip->v_gain_mega;
852
853 comp_val_nV = div_s64(regval_nV * gain, 1000000) + offset_nV;
854 comp_val_uV = comp_val_nV / 1000;
855
856 return snprintf(ubuf, PAGE_SIZE, "%d%s\n",
857 comp_val_uV, params[i].units_str);
858}
859
860static ssize_t voltage_store(struct class *c, struct class_attribute *attr,
861 const char *ubuf, size_t count)
862{
863 int i = attr - qnovo_attributes;
864 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
865 u8 buf[2] = {0, 0};
866 int rc;
867 unsigned long val_uV;
868 s64 regval_nV;
869 s64 gain, offset_nV;
870
871 if (kstrtoul(ubuf, 10, &val_uV))
872 return -EINVAL;
873
874 if (val_uV < params[i].min_val || val_uV > params[i].max_val) {
875 pr_err("Out of Range %d%s for %s\n", (int)val_uV,
876 params[i].units_str,
877 params[i].name);
878 return -ERANGE;
879 }
880
881 offset_nV = chip->offset_nV;
882 gain = chip->v_gain_mega;
883
884 regval_nV = (s64)val_uV * 1000 - offset_nV;
885 regval_nV = div_s64(regval_nV * 1000000, gain);
886
887 regval_nV = div_s64((regval_nV + params[i].reg_to_unit_offset)
888 * params[i].reg_to_unit_divider,
889 params[i].reg_to_unit_multiplier);
890 buf[0] = regval_nV & 0xFF;
891 buf[1] = ((u64)regval_nV >> 8) & 0xFF;
892
893 rc = qnovo_write(chip, params[i].start_addr, buf, params[i].num_regs);
894 if (rc < 0) {
895 pr_err("Couldn't write %s rc = %d\n", params[i].name, rc);
896 return -EINVAL;
897 }
898
899 return count;
900}
901
902static ssize_t coulomb_show(struct class *c, struct class_attribute *attr,
903 char *ubuf)
904{
905 int i = attr - qnovo_attributes;
906 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
907 u8 buf[2] = {0, 0};
908 int rc;
909 int comp_val_uC;
910 s64 regval_uC, gain;
911
912 rc = qnovo_read(chip, params[i].start_addr, buf, params[i].num_regs);
913 if (rc < 0) {
914 pr_err("Couldn't read %s rc = %d\n", params[i].name, rc);
915 return -EINVAL;
916 }
917 regval_uC = buf[1] << 8 | buf[0];
918 regval_uC = div_s64(regval_uC * params[i].reg_to_unit_multiplier,
919 params[i].reg_to_unit_divider)
920 - params[i].reg_to_unit_offset;
921
922 if (chip->dt.external_rsense)
923 gain = chip->external_i_gain_mega;
924 else
925 gain = chip->internal_i_gain_mega;
926
927 comp_val_uC = div_s64(regval_uC * gain, 1000000);
928 return snprintf(ubuf, PAGE_SIZE, "%d%s\n",
929 comp_val_uC, params[i].units_str);
930}
931
932static ssize_t coulomb_store(struct class *c, struct class_attribute *attr,
933 const char *ubuf, size_t count)
934{
935 int i = attr - qnovo_attributes;
936 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
937 u8 buf[2] = {0, 0};
938 int rc;
939 unsigned long val_uC;
940 s64 regval;
941 s64 gain;
942
943 if (kstrtoul(ubuf, 10, &val_uC))
944 return -EINVAL;
945
946 if (val_uC < params[i].min_val || val_uC > params[i].max_val) {
947 pr_err("Out of Range %d%s for %s\n", (int)val_uC,
948 params[i].units_str,
949 params[i].name);
950 return -ERANGE;
951 }
952
953 if (chip->dt.external_rsense)
954 gain = chip->external_i_gain_mega;
955 else
956 gain = chip->internal_i_gain_mega;
957
958 regval = div_s64((s64)val_uC * 1000000, gain);
959
960 regval = div_s64((regval + params[i].reg_to_unit_offset)
961 * params[i].reg_to_unit_divider,
962 params[i].reg_to_unit_multiplier);
963
964 buf[0] = regval & 0xFF;
965 buf[1] = ((u64)regval >> 8) & 0xFF;
966
967 rc = qnovo_write(chip, params[i].start_addr, buf, params[i].num_regs);
968 if (rc < 0) {
969 pr_err("Couldn't write %s rc = %d\n", params[i].name, rc);
970 return -EINVAL;
971 }
972
973 return count;
974}
975
976static ssize_t batt_prop_show(struct class *c, struct class_attribute *attr,
977 char *ubuf)
978{
979 int i = attr - qnovo_attributes;
980 struct qnovo *chip = container_of(c, struct qnovo, qnovo_class);
981 int rc = -EINVAL;
982 int prop = params[i].start_addr;
983 union power_supply_propval pval = {0};
984
985 if (!chip->batt_psy)
986 chip->batt_psy = power_supply_get_by_name("battery");
987
988 if (!chip->batt_psy)
989 return -EINVAL;
990
991 rc = power_supply_get_property(chip->batt_psy, prop, &pval);
992 if (rc < 0) {
993 pr_err("Couldn't read battery prop %s rc = %d\n",
994 params[i].name, rc);
995 return -EINVAL;
996 }
997
998 return snprintf(ubuf, PAGE_SIZE, "%d%s\n",
999 pval.intval, params[i].units_str);
1000}
1001
1002static struct class_attribute qnovo_attributes[] = {
1003 [VER] = __ATTR_RO(version),
1004 [OK_TO_QNOVO] = __ATTR_RO(ok_to_qnovo),
1005 [ENABLE] = __ATTR(enable, 0644,
1006 enable_show, enable_store),
1007 [FV_REQUEST] = __ATTR(fv_uV_request, 0644,
1008 val_show, val_store),
1009 [FCC_REQUEST] = __ATTR(fcc_uA_request, 0644,
1010 val_show, val_store),
1011 [PE_CTRL_REG] = __ATTR(PE_CTRL_REG, 0644,
1012 reg_show, reg_store),
1013 [PE_CTRL2_REG] = __ATTR(PE_CTRL2_REG, 0644,
1014 reg_show, reg_store),
1015 [PTRAIN_STS_REG] = __ATTR(PTRAIN_STS_REG, 0644,
1016 reg_show, reg_store),
1017 [INT_RT_STS_REG] = __ATTR(INT_RT_STS_REG, 0644,
1018 reg_show, reg_store),
1019 [PREST1] = __ATTR(PREST1_mS, 0644,
1020 time_show, time_store),
1021 [PPULS1] = __ATTR(PPULS1_uC, 0644,
1022 coulomb_show, coulomb_store),
1023 [NREST1] = __ATTR(NREST1_mS, 0644,
1024 time_show, time_store),
1025 [NPULS1] = __ATTR(NPULS1_mS, 0644,
1026 time_show, time_store),
1027 [PPCNT] = __ATTR(PPCNT, 0644,
1028 time_show, time_store),
1029 [VLIM1] = __ATTR(VLIM1_uV, 0644,
1030 voltage_show, voltage_store),
1031 [PVOLT1] = __ATTR(PVOLT1_uV, 0444,
1032 voltage_show, NULL),
1033 [PCUR1] = __ATTR(PCUR1_uA, 0444,
1034 current_show, NULL),
1035 [PTTIME] = __ATTR(PTTIME_S, 0444,
1036 time_show, NULL),
1037 [PREST2] = __ATTR(PREST2_mS, 0644,
1038 time_show, time_store),
1039 [PPULS2] = __ATTR(PPULS2_mS, 0644,
1040 coulomb_show, coulomb_store),
1041 [NREST2] = __ATTR(NREST2_mS, 0644,
1042 time_show, time_store),
1043 [NPULS2] = __ATTR(NPULS2_mS, 0644,
1044 time_show, time_store),
1045 [VLIM2] = __ATTR(VLIM2_uV, 0644,
1046 voltage_show, voltage_store),
1047 [PVOLT2] = __ATTR(PVOLT2_uV, 0444,
1048 voltage_show, NULL),
1049 [RVOLT2] = __ATTR(RVOLT2_uV, 0444,
1050 voltage_show, NULL),
1051 [PCUR2] = __ATTR(PCUR2_uA, 0444,
1052 current_show, NULL),
1053 [SCNT] = __ATTR(SCNT, 0644,
1054 time_show, time_store),
1055 [VMAX] = __ATTR(VMAX_uV, 0444,
1056 voltage_show, NULL),
1057 [SNUM] = __ATTR(SNUM, 0644,
1058 time_show, time_store),
1059 [VBATT] = __ATTR(VBATT_uV, 0444,
1060 batt_prop_show, NULL),
1061 [IBATT] = __ATTR(IBATT_uA, 0444,
1062 batt_prop_show, NULL),
1063 [BATTTEMP] = __ATTR(BATTTEMP_deciDegC, 0444,
1064 batt_prop_show, NULL),
1065 [BATTSOC] = __ATTR(BATTSOC, 0444,
1066 batt_prop_show, NULL),
1067 __ATTR_NULL,
1068};
1069
1070static void get_chg_props(struct qnovo *chip, struct chg_props *cp)
1071{
1072 union power_supply_propval pval;
1073 u8 val = 0;
1074 int rc;
1075
1076 cp->charging = true;
1077 rc = qnovo_read(chip, QNOVO_ERROR_STS, &val, 1);
1078 if (rc < 0) {
1079 pr_err("Couldn't read error sts rc = %d\n", rc);
1080 cp->charging = false;
1081 } else {
1082 cp->charging = (!(val & QNOVO_ERROR_BIT));
1083 }
1084
1085 if (chip->wa_flags & QNOVO_NO_ERR_STS_BIT) {
1086 /*
1087 * on v1.0 and v1.1 pmic's force charging to true
1088 * if things are not good to charge s/w gets a PTRAIN_DONE
1089 * interrupt
1090 */
1091 cp->charging = true;
1092 }
1093
1094 cp->usb_online = false;
1095 cp->usb_input_uA = 0;
1096 if (!chip->usb_psy)
1097 chip->usb_psy = power_supply_get_by_name("usb");
1098 if (chip->usb_psy) {
1099 rc = power_supply_get_property(chip->usb_psy,
1100 POWER_SUPPLY_PROP_ONLINE, &pval);
1101 if (rc < 0)
1102 pr_err("Couldn't read usb online rc = %d\n", rc);
1103 else
1104 cp->usb_online = (bool)pval.intval;
1105
1106 rc = power_supply_get_property(chip->usb_psy,
1107 POWER_SUPPLY_PROP_CURRENT_MAX, &pval);
1108 if (rc < 0)
1109 pr_err("Couldn't read usb current max rc = %d\n", rc);
1110 else
1111 cp->usb_input_uA = pval.intval;
1112 }
1113
1114 cp->dc_online = false;
1115 cp->dc_input_uA = 0;
1116 if (!chip->dc_psy)
1117 chip->dc_psy = power_supply_get_by_name("dc");
1118 if (chip->dc_psy) {
1119 rc = power_supply_get_property(chip->dc_psy,
1120 POWER_SUPPLY_PROP_ONLINE, &pval);
1121 if (rc < 0)
1122 pr_err("Couldn't read dc online rc = %d\n", rc);
1123 else
1124 cp->dc_online = (bool)pval.intval;
1125
1126 rc = power_supply_get_property(chip->dc_psy,
1127 POWER_SUPPLY_PROP_CURRENT_MAX, &pval);
1128 if (rc < 0)
1129 pr_err("Couldn't read dc current max rc = %d\n", rc);
1130 else
1131 cp->dc_input_uA = pval.intval;
1132 }
1133}
1134
1135static void get_chg_status(struct qnovo *chip, const struct chg_props *cp,
1136 struct chg_status *cs)
1137{
1138 cs->ok_to_qnovo = false;
1139
1140 if (cp->charging &&
1141 ((cp->usb_online && cp->usb_input_uA >= MIN_EN_UA)
1142 || (cp->dc_online && cp->dc_input_uA >= MIN_EN_UA)))
1143 cs->ok_to_qnovo = true;
1144}
1145
1146static void status_change_work(struct work_struct *work)
1147{
1148 struct qnovo *chip = container_of(work,
1149 struct qnovo, status_change_work);
1150 bool notify_uevent = false;
1151 struct chg_props cp;
1152 struct chg_status cs;
1153
1154 get_chg_props(chip, &cp);
1155 get_chg_status(chip, &cp, &cs);
1156
1157 if (cs.ok_to_qnovo ^ chip->cs.ok_to_qnovo) {
1158 /*
1159 * when it is not okay to Qnovo charge, disable both voters,
1160 * so that when it becomes okay to Qnovo charge the user voter
1161 * has to specifically enable its vote to being Qnovo charging
1162 */
1163 if (!cs.ok_to_qnovo) {
1164 vote(chip->disable_votable, OK_TO_QNOVO_VOTER, 1, 0);
1165 vote(chip->disable_votable, USER_VOTER, 1, 0);
1166 } else {
1167 vote(chip->disable_votable, OK_TO_QNOVO_VOTER, 0, 0);
1168 }
1169 notify_uevent = true;
1170 }
1171
1172 memcpy(&chip->cp, &cp, sizeof(struct chg_props));
1173 memcpy(&chip->cs, &cs, sizeof(struct chg_status));
1174
1175 if (notify_uevent)
1176 kobject_uevent(&chip->dev->kobj, KOBJ_CHANGE);
1177}
1178
1179static int qnovo_notifier_call(struct notifier_block *nb,
1180 unsigned long ev, void *v)
1181{
1182 struct power_supply *psy = v;
1183 struct qnovo *chip = container_of(nb, struct qnovo, nb);
1184
1185 if (ev != PSY_EVENT_PROP_CHANGED)
1186 return NOTIFY_OK;
1187 if ((strcmp(psy->desc->name, "battery") == 0)
1188 || (strcmp(psy->desc->name, "usb") == 0))
1189 schedule_work(&chip->status_change_work);
1190
1191 return NOTIFY_OK;
1192}
1193
1194static irqreturn_t handle_ptrain_done(int irq, void *data)
1195{
1196 struct qnovo *chip = data;
1197
1198 /* disable user voter here */
1199 vote(chip->disable_votable, USER_VOTER, 0, 0);
1200 kobject_uevent(&chip->dev->kobj, KOBJ_CHANGE);
1201 return IRQ_HANDLED;
1202}
1203
1204static int qnovo_hw_init(struct qnovo *chip)
1205{
1206 int rc;
1207 u8 iadc_offset_external, iadc_offset_internal;
1208 u8 iadc_gain_external, iadc_gain_internal;
1209 u8 vadc_offset, vadc_gain;
1210 u8 buf[2] = {0, 0};
1211
1212 vote(chip->disable_votable, USER_VOTER, 1, 0);
1213
1214 rc = qnovo_read(chip, QNOVO_IADC_OFFSET_0, &iadc_offset_external, 1);
1215 if (rc < 0) {
1216 pr_err("Couldn't read iadc exernal offset rc = %d\n", rc);
1217 return rc;
1218 }
1219
1220 rc = qnovo_read(chip, QNOVO_IADC_OFFSET_1, &iadc_offset_internal, 1);
1221 if (rc < 0) {
1222 pr_err("Couldn't read iadc internal offset rc = %d\n", rc);
1223 return rc;
1224 }
1225
1226 rc = qnovo_read(chip, QNOVO_IADC_GAIN_0, &iadc_gain_external, 1);
1227 if (rc < 0) {
1228 pr_err("Couldn't read iadc external gain rc = %d\n", rc);
1229 return rc;
1230 }
1231
1232 rc = qnovo_read(chip, QNOVO_IADC_GAIN_1, &iadc_gain_internal, 1);
1233 if (rc < 0) {
1234 pr_err("Couldn't read iadc internal gain rc = %d\n", rc);
1235 return rc;
1236 }
1237
1238 rc = qnovo_read(chip, QNOVO_VADC_OFFSET, &vadc_offset, 1);
1239 if (rc < 0) {
1240 pr_err("Couldn't read vadc offset rc = %d\n", rc);
1241 return rc;
1242 }
1243
1244 rc = qnovo_read(chip, QNOVO_VADC_GAIN, &vadc_gain, 1);
1245 if (rc < 0) {
1246 pr_err("Couldn't read vadc external gain rc = %d\n", rc);
1247 return rc;
1248 }
1249
1250 chip->external_offset_nA = (s64)iadc_offset_external * IADC_LSB_NA;
1251 chip->internal_offset_nA = (s64)iadc_offset_internal * IADC_LSB_NA;
1252 chip->offset_nV = (s64)vadc_offset * VADC_LSB_NA;
1253 chip->external_i_gain_mega
1254 = 1000000000 + (s64)iadc_gain_external * GAIN_LSB_FACTOR;
1255 chip->external_i_gain_mega
1256 = div_s64(chip->external_i_gain_mega, 1000);
1257 chip->internal_i_gain_mega
1258 = 1000000000 + (s64)iadc_gain_internal * GAIN_LSB_FACTOR;
1259 chip->internal_i_gain_mega
1260 = div_s64(chip->internal_i_gain_mega, 1000);
1261 chip->v_gain_mega = 1000000000 + (s64)vadc_gain * GAIN_LSB_FACTOR;
1262 chip->v_gain_mega = div_s64(chip->v_gain_mega, 1000);
1263
1264 if (chip->wa_flags & QNOVO_ERASE_OFFSET_WA_BIT) {
1265 rc = qnovo_write(chip, QNOVO_TR_IADC_OFFSET_0, buf, 2);
1266 if (rc < 0) {
1267 pr_err("Couldn't erase offset rc = %d\n", rc);
1268 return rc;
1269 }
1270 }
1271 return 0;
1272}
1273
1274static int qnovo_register_notifier(struct qnovo *chip)
1275{
1276 int rc;
1277
1278 chip->nb.notifier_call = qnovo_notifier_call;
1279 rc = power_supply_reg_notifier(&chip->nb);
1280 if (rc < 0) {
1281 pr_err("Couldn't register psy notifier rc = %d\n", rc);
1282 return rc;
1283 }
1284
1285 return 0;
1286}
1287
1288static int qnovo_determine_initial_status(struct qnovo *chip)
1289{
1290 status_change_work(&chip->status_change_work);
1291 return 0;
1292}
1293
1294static int qnovo_request_interrupts(struct qnovo *chip)
1295{
1296 int rc = 0;
1297 int irq_ptrain_done = of_irq_get_byname(chip->dev->of_node,
1298 "ptrain-done");
1299
1300 rc = devm_request_threaded_irq(chip->dev, irq_ptrain_done, NULL,
1301 handle_ptrain_done,
1302 IRQF_ONESHOT, "ptrain-done", chip);
1303 if (rc < 0) {
1304 pr_err("Couldn't request irq %d rc = %d\n",
1305 irq_ptrain_done, rc);
1306 return rc;
1307 }
1308 return rc;
1309}
1310
1311static int qnovo_probe(struct platform_device *pdev)
1312{
1313 struct qnovo *chip;
1314 int rc = 0;
1315
1316 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
1317 if (!chip)
1318 return -ENOMEM;
1319
1320 chip->fv_uV_request = -EINVAL;
1321 chip->fcc_uA_request = -EINVAL;
1322 chip->dev = &pdev->dev;
1323 mutex_init(&chip->write_lock);
1324
1325 chip->regmap = dev_get_regmap(chip->dev->parent, NULL);
1326 if (!chip->regmap) {
1327 pr_err("parent regmap is missing\n");
1328 return -EINVAL;
1329 }
1330
1331 rc = qnovo_parse_dt(chip);
1332 if (rc < 0) {
1333 pr_err("Couldn't parse device tree rc=%d\n", rc);
1334 return rc;
1335 }
1336
1337 rc = qnovo_check_chg_version(chip);
1338 if (rc < 0) {
1339 if (rc != -EPROBE_DEFER)
1340 pr_err("Couldn't check version rc=%d\n", rc);
1341 return rc;
1342 }
1343
1344 /* set driver data before resources request it */
1345 platform_set_drvdata(pdev, chip);
1346
1347 chip->disable_votable = create_votable("QNOVO_DISABLE", VOTE_SET_ANY,
1348 qnovo_disable_cb, chip);
1349 if (IS_ERR(chip->disable_votable)) {
1350 rc = PTR_ERR(chip->disable_votable);
1351 goto cleanup;
1352 }
1353
1354 INIT_WORK(&chip->status_change_work, status_change_work);
1355
1356 rc = qnovo_hw_init(chip);
1357 if (rc < 0) {
1358 pr_err("Couldn't initialize hardware rc=%d\n", rc);
1359 goto destroy_votable;
1360 }
1361
1362 rc = qnovo_register_notifier(chip);
1363 if (rc < 0) {
1364 pr_err("Couldn't register psy notifier rc = %d\n", rc);
1365 goto unreg_notifier;
1366 }
1367
1368 rc = qnovo_determine_initial_status(chip);
1369 if (rc < 0) {
1370 pr_err("Couldn't determine initial status rc=%d\n", rc);
1371 goto unreg_notifier;
1372 }
1373
1374 rc = qnovo_request_interrupts(chip);
1375 if (rc < 0) {
1376 pr_err("Couldn't request interrupts rc=%d\n", rc);
1377 goto unreg_notifier;
1378 }
1379 chip->qnovo_class.name = "qnovo",
1380 chip->qnovo_class.owner = THIS_MODULE,
1381 chip->qnovo_class.class_attrs = qnovo_attributes;
1382
1383 rc = class_register(&chip->qnovo_class);
1384 if (rc < 0) {
1385 pr_err("couldn't register qnovo sysfs class rc = %d\n", rc);
1386 goto unreg_notifier;
1387 }
1388
1389 return rc;
1390
1391unreg_notifier:
1392 power_supply_unreg_notifier(&chip->nb);
1393destroy_votable:
1394 destroy_votable(chip->disable_votable);
1395cleanup:
1396 platform_set_drvdata(pdev, NULL);
1397 return rc;
1398}
1399
1400static int qnovo_remove(struct platform_device *pdev)
1401{
1402 struct qnovo *chip = platform_get_drvdata(pdev);
1403
1404 class_unregister(&chip->qnovo_class);
1405 power_supply_unreg_notifier(&chip->nb);
1406 destroy_votable(chip->disable_votable);
1407 platform_set_drvdata(pdev, NULL);
1408 return 0;
1409}
1410
1411static const struct of_device_id match_table[] = {
1412 { .compatible = "qcom,qpnp-qnovo", },
1413 { },
1414};
1415
1416static struct platform_driver qnovo_driver = {
1417 .driver = {
1418 .name = "qcom,qnovo-driver",
1419 .owner = THIS_MODULE,
1420 .of_match_table = match_table,
1421 },
1422 .probe = qnovo_probe,
1423 .remove = qnovo_remove,
1424};
1425module_platform_driver(qnovo_driver);
1426
1427MODULE_DESCRIPTION("QPNP Qnovo Driver");
1428MODULE_LICENSE("GPL v2");