blob: 1c592f1491f668326e8050840e45494dd7f6ddf8 [file] [log] [blame]
Nicholas Troast96886052016-02-25 15:42:17 -08001/* 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/regulator/driver.h>
22#include <linux/regulator/of_regulator.h>
23#include <linux/regulator/machine.h>
24#include "smb-reg.h"
25#include "smb-lib.h"
26#include "pmic-voter.h"
27
28#define SMB2_DEFAULT_FCC_UA 1000000
Abhijeet Dharmapurikarf9805d42016-05-17 18:38:42 -070029#define SMB2_DEFAULT_FV_UV 4350000
Nicholas Troast96886052016-02-25 15:42:17 -080030#define SMB2_DEFAULT_ICL_UA 1500000
31
32static struct smb_params v1_params = {
33 .fcc = {
34 .name = "fast charge current",
35 .reg = FAST_CHARGE_CURRENT_CFG_REG,
36 .min_u = 0,
37 .max_u = 4500000,
38 .step_u = 25000,
39 },
40 .fv = {
41 .name = "float voltage",
42 .reg = FLOAT_VOLTAGE_CFG_REG,
43 .min_u = 2500000,
44 .max_u = 5000000,
45 .step_u = 10000,
46 },
47 .usb_icl = {
48 .name = "usb input current limit",
49 .reg = USBIN_CURRENT_LIMIT_CFG_REG,
50 .min_u = 0,
51 .max_u = 6000000,
52 .step_u = 25000,
53 },
54 .dc_icl = {
55 .name = "dc input current limit",
56 .reg = DCIN_CURRENT_LIMIT_CFG_REG,
57 .min_u = 0,
58 .max_u = 6000000,
59 .step_u = 25000,
60 },
61};
62
63struct smb_dt_props {
64 bool suspend_input;
65 int fcc_ua;
66 int usb_icl_ua;
67 int dc_icl_ua;
68 int fv_uv;
69};
70
71struct smb2 {
72 struct smb_charger chg;
73 struct smb_dt_props dt;
74 bool bad_part;
75};
76
77static int __debug_mask;
78module_param_named(
79 debug_mask, __debug_mask, int, 0600
80);
81
82static int smb2_parse_dt(struct smb2 *chip)
83{
84 struct smb_charger *chg = &chip->chg;
85 struct device_node *node = chg->dev->of_node;
86 int rc;
87
88 if (!node) {
89 pr_err("device tree node missing\n");
90 return -EINVAL;
91 }
92
93 chip->dt.suspend_input = of_property_read_bool(node,
94 "qcom,suspend-input");
95
96 rc = of_property_read_u32(node,
97 "qcom,fcc-max-ua", &chip->dt.fcc_ua);
98 if (rc < 0)
99 chip->dt.fcc_ua = SMB2_DEFAULT_FCC_UA;
100
101 rc = of_property_read_u32(node,
Abhijeet Dharmapurikarf9805d42016-05-17 18:38:42 -0700102 "qcom,fv-max-uv", &chip->dt.fv_uv);
103 if (rc < 0)
104 chip->dt.fv_uv = SMB2_DEFAULT_FV_UV;
105
106 rc = of_property_read_u32(node,
Nicholas Troast96886052016-02-25 15:42:17 -0800107 "qcom,usb-icl-ua", &chip->dt.usb_icl_ua);
108 if (rc < 0)
109 chip->dt.usb_icl_ua = SMB2_DEFAULT_ICL_UA;
110
111 rc = of_property_read_u32(node,
112 "qcom,dc-icl-ua", &chip->dt.dc_icl_ua);
113 if (rc < 0)
114 chip->dt.dc_icl_ua = SMB2_DEFAULT_ICL_UA;
115
116 return 0;
117}
118
119/************************
120 * USB PSY REGISTRATION *
121 ************************/
122
123static enum power_supply_property smb2_usb_props[] = {
124 POWER_SUPPLY_PROP_PRESENT,
125 POWER_SUPPLY_PROP_ONLINE,
126 POWER_SUPPLY_PROP_VOLTAGE_MIN,
127 POWER_SUPPLY_PROP_VOLTAGE_MAX,
128 POWER_SUPPLY_PROP_VOLTAGE_NOW,
129 POWER_SUPPLY_PROP_CURRENT_MAX,
130 POWER_SUPPLY_PROP_TYPE,
131 POWER_SUPPLY_PROP_TYPEC_MODE,
132 POWER_SUPPLY_PROP_TYPEC_POWER_ROLE,
133 POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION,
134 POWER_SUPPLY_PROP_PD_ALLOWED,
135 POWER_SUPPLY_PROP_PD_ACTIVE,
136};
137
138static int smb2_usb_get_prop(struct power_supply *psy,
139 enum power_supply_property psp,
140 union power_supply_propval *val)
141{
142 struct smb2 *chip = power_supply_get_drvdata(psy);
143 struct smb_charger *chg = &chip->chg;
144 int rc = 0;
145
146 switch (psp) {
147 case POWER_SUPPLY_PROP_PRESENT:
148 if (chip->bad_part)
149 val->intval = 1;
150 else
151 rc = smblib_get_prop_usb_present(chg, val);
152 break;
153 case POWER_SUPPLY_PROP_ONLINE:
154 rc = smblib_get_prop_usb_online(chg, val);
155 break;
156 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
157 val->intval = chg->voltage_min_uv;
158 break;
159 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
160 val->intval = chg->voltage_max_uv;
161 break;
162 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
163 rc = smblib_get_prop_usb_voltage_now(chg, val);
164 break;
165 case POWER_SUPPLY_PROP_CURRENT_MAX:
166 rc = smblib_get_prop_usb_current_max(chg, val);
167 break;
168 case POWER_SUPPLY_PROP_TYPE:
169 if (chip->bad_part)
170 val->intval = POWER_SUPPLY_TYPE_USB;
171 else
172 val->intval = chg->usb_psy_desc.type;
173 break;
174 case POWER_SUPPLY_PROP_TYPEC_MODE:
175 if (chip->bad_part)
176 val->intval = POWER_SUPPLY_TYPEC_SOURCE_DEFAULT;
177 else
178 rc = smblib_get_prop_typec_mode(chg, val);
179 break;
180 case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
181 rc = smblib_get_prop_typec_power_role(chg, val);
182 break;
183 case POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION:
184 rc = smblib_get_prop_typec_cc_orientation(chg, val);
185 break;
186 case POWER_SUPPLY_PROP_PD_ALLOWED:
187 rc = smblib_get_prop_pd_allowed(chg, val);
188 break;
189 case POWER_SUPPLY_PROP_PD_ACTIVE:
190 val->intval = chg->pd_active;
191 break;
192 default:
193 pr_err("get prop %d is not supported\n", psp);
194 rc = -EINVAL;
195 break;
196 }
197 return rc;
198}
199
200static int smb2_usb_set_prop(struct power_supply *psy,
201 enum power_supply_property psp,
202 const union power_supply_propval *val)
203{
204 struct smb2 *chip = power_supply_get_drvdata(psy);
205 struct smb_charger *chg = &chip->chg;
206 int rc = 0;
207
208 switch (psp) {
209 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
210 rc = smblib_set_prop_usb_voltage_min(chg, val);
211 break;
212 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
213 rc = smblib_set_prop_usb_voltage_max(chg, val);
214 break;
215 case POWER_SUPPLY_PROP_CURRENT_MAX:
216 rc = smblib_set_prop_usb_current_max(chg, val);
217 break;
Jack Pham9696e252016-05-23 11:15:15 -0700218 case POWER_SUPPLY_PROP_TYPE:
219 if (chg->pd_active && val->intval == POWER_SUPPLY_TYPE_USB_PD) {
220 chg->usb_psy_desc.type = val->intval;
221 } else {
222 pr_err("set type %d not allowed\n", val->intval);
223 rc = -EINVAL;
224 }
225 break;
Nicholas Troast96886052016-02-25 15:42:17 -0800226 case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
227 rc = smblib_set_prop_typec_power_role(chg, val);
228 break;
229 case POWER_SUPPLY_PROP_PD_ACTIVE:
230 rc = smblib_set_prop_pd_active(chg, val);
231 break;
232 default:
233 pr_err("set prop %d is not supported\n", psp);
234 rc = -EINVAL;
235 break;
236 }
237
238 return rc;
239}
240
241static int smb2_usb_prop_is_writeable(struct power_supply *psy,
242 enum power_supply_property psp)
243{
244 switch (psp) {
245 case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
246 return 1;
247 default:
248 break;
249 }
250
251 return 0;
252}
253
254static int smb2_init_usb_psy(struct smb2 *chip)
255{
256 struct power_supply_config usb_cfg = {};
257 struct smb_charger *chg = &chip->chg;
258
259 chg->usb_psy_desc.name = "usb";
260 chg->usb_psy_desc.type = POWER_SUPPLY_TYPE_UNKNOWN;
261 chg->usb_psy_desc.properties = smb2_usb_props;
262 chg->usb_psy_desc.num_properties = ARRAY_SIZE(smb2_usb_props);
263 chg->usb_psy_desc.get_property = smb2_usb_get_prop;
264 chg->usb_psy_desc.set_property = smb2_usb_set_prop;
265 chg->usb_psy_desc.property_is_writeable = smb2_usb_prop_is_writeable;
266
267 usb_cfg.drv_data = chip;
268 usb_cfg.of_node = chg->dev->of_node;
269 chg->usb_psy = devm_power_supply_register(chg->dev,
270 &chg->usb_psy_desc,
271 &usb_cfg);
272 if (IS_ERR(chg->usb_psy)) {
273 pr_err("Couldn't register USB power supply\n");
274 return PTR_ERR(chg->usb_psy);
275 }
276
277 return 0;
278}
279
280/*************************
281 * BATT PSY REGISTRATION *
282 *************************/
283
284static enum power_supply_property smb2_batt_props[] = {
285 POWER_SUPPLY_PROP_INPUT_SUSPEND,
286 POWER_SUPPLY_PROP_STATUS,
287 POWER_SUPPLY_PROP_HEALTH,
288 POWER_SUPPLY_PROP_PRESENT,
289 POWER_SUPPLY_PROP_CHARGE_TYPE,
290 POWER_SUPPLY_PROP_CAPACITY,
291};
292
293static int smb2_batt_get_prop(struct power_supply *psy,
294 enum power_supply_property psp,
295 union power_supply_propval *val)
296{
297 struct smb_charger *chg = power_supply_get_drvdata(psy);
298
299 switch (psp) {
300 case POWER_SUPPLY_PROP_STATUS:
301 smblib_get_prop_batt_status(chg, val);
302 break;
303 case POWER_SUPPLY_PROP_HEALTH:
304 smblib_get_prop_batt_health(chg, val);
305 break;
306 case POWER_SUPPLY_PROP_PRESENT:
307 smblib_get_prop_batt_present(chg, val);
308 break;
309 case POWER_SUPPLY_PROP_INPUT_SUSPEND:
310 smblib_get_prop_input_suspend(chg, val);
311 break;
312 case POWER_SUPPLY_PROP_CHARGE_TYPE:
313 smblib_get_prop_batt_charge_type(chg, val);
314 break;
315 case POWER_SUPPLY_PROP_CAPACITY:
316 smblib_get_prop_batt_capacity(chg, val);
317 break;
318 default:
319 pr_err("batt power supply prop %d not supported\n",
320 psp);
321 return -EINVAL;
322 }
323
324 return 0;
325}
326
327static int smb2_batt_set_prop(struct power_supply *psy,
328 enum power_supply_property prop,
329 const union power_supply_propval *val)
330{
331 struct smb_charger *chg = power_supply_get_drvdata(psy);
332
333 switch (prop) {
334 case POWER_SUPPLY_PROP_INPUT_SUSPEND:
335 smblib_set_prop_input_suspend(chg, val);
336 break;
337 default:
338 return -EINVAL;
339 }
340
341 return 0;
342}
343
344static int smb2_batt_prop_is_writeable(struct power_supply *psy,
345 enum power_supply_property psp)
346{
347 switch (psp) {
348 case POWER_SUPPLY_PROP_INPUT_SUSPEND:
349 return 1;
350 default:
351 break;
352 }
353
354 return 0;
355}
356
357static const struct power_supply_desc batt_psy_desc = {
358 .name = "battery",
359 .type = POWER_SUPPLY_TYPE_BATTERY,
360 .properties = smb2_batt_props,
361 .num_properties = ARRAY_SIZE(smb2_batt_props),
362 .get_property = smb2_batt_get_prop,
363 .set_property = smb2_batt_set_prop,
364 .property_is_writeable = smb2_batt_prop_is_writeable,
365};
366
367static int smb2_init_batt_psy(struct smb2 *chip)
368{
369 struct power_supply_config batt_cfg = {};
370 struct smb_charger *chg = &chip->chg;
371 int rc = 0;
372
373 batt_cfg.drv_data = chg;
374 batt_cfg.of_node = chg->dev->of_node;
375 chg->batt_psy = devm_power_supply_register(chg->dev,
376 &batt_psy_desc,
377 &batt_cfg);
378 if (IS_ERR(chg->batt_psy)) {
379 pr_err("Couldn't register battery power supply\n");
380 return PTR_ERR(chg->batt_psy);
381 }
382
383 return rc;
384}
385
386/******************************
387 * VBUS REGULATOR REGISTRATION *
388 ******************************/
389
390struct regulator_ops smb2_vbus_reg_ops = {
391 .enable = smblib_vbus_regulator_enable,
392 .disable = smblib_vbus_regulator_disable,
393 .is_enabled = smblib_vbus_regulator_is_enabled,
394};
395
396static int smb2_init_vbus_regulator(struct smb2 *chip)
397{
398 struct smb_charger *chg = &chip->chg;
399 struct regulator_config cfg = {};
400 int rc = 0;
401
402 chg->vbus_vreg = devm_kzalloc(chg->dev, sizeof(*chg->vbus_vreg),
403 GFP_KERNEL);
404 if (!chg->vbus_vreg)
405 return -ENOMEM;
406
407 cfg.dev = chg->dev;
408 cfg.driver_data = chip;
409
410 chg->vbus_vreg->rdesc.owner = THIS_MODULE;
411 chg->vbus_vreg->rdesc.type = REGULATOR_VOLTAGE;
412 chg->vbus_vreg->rdesc.ops = &smb2_vbus_reg_ops;
413 chg->vbus_vreg->rdesc.of_match = "qcom,smb2-vbus";
414 chg->vbus_vreg->rdesc.name = "qcom,smb2-vbus";
415
416 chg->vbus_vreg->rdev = devm_regulator_register(chg->dev,
417 &chg->vbus_vreg->rdesc, &cfg);
418 if (IS_ERR(chg->vbus_vreg->rdev)) {
419 rc = PTR_ERR(chg->vbus_vreg->rdev);
420 chg->vbus_vreg->rdev = NULL;
421 if (rc != -EPROBE_DEFER)
422 pr_err("Couldn't register VBUS regualtor rc=%d\n", rc);
423 }
424
425 return rc;
426}
427
428/******************************
429 * VCONN REGULATOR REGISTRATION *
430 ******************************/
431
432struct regulator_ops smb2_vconn_reg_ops = {
433 .enable = smblib_vconn_regulator_enable,
434 .disable = smblib_vconn_regulator_disable,
435 .is_enabled = smblib_vconn_regulator_is_enabled,
436};
437
438static int smb2_init_vconn_regulator(struct smb2 *chip)
439{
440 struct smb_charger *chg = &chip->chg;
441 struct regulator_config cfg = {};
442 int rc = 0;
443
444 chg->vconn_vreg = devm_kzalloc(chg->dev, sizeof(*chg->vconn_vreg),
445 GFP_KERNEL);
446 if (!chg->vconn_vreg)
447 return -ENOMEM;
448
449 cfg.dev = chg->dev;
450 cfg.driver_data = chip;
451
452 chg->vconn_vreg->rdesc.owner = THIS_MODULE;
453 chg->vconn_vreg->rdesc.type = REGULATOR_VOLTAGE;
454 chg->vconn_vreg->rdesc.ops = &smb2_vconn_reg_ops;
455 chg->vconn_vreg->rdesc.of_match = "qcom,smb2-vconn";
456 chg->vconn_vreg->rdesc.name = "qcom,smb2-vconn";
457
458 chg->vconn_vreg->rdev = devm_regulator_register(chg->dev,
459 &chg->vconn_vreg->rdesc, &cfg);
460 if (IS_ERR(chg->vconn_vreg->rdev)) {
461 rc = PTR_ERR(chg->vconn_vreg->rdev);
462 chg->vconn_vreg->rdev = NULL;
463 if (rc != -EPROBE_DEFER)
464 pr_err("Couldn't register VCONN regualtor rc=%d\n", rc);
465 }
466
467 return rc;
468}
469
470/***************************
471 * HARDWARE INITIALIZATION *
472 ***************************/
473
474static int smb2_init_hw(struct smb2 *chip)
475{
476 struct smb_charger *chg = &chip->chg;
477 int rc;
478
479 /* votes must be cast before configuring software control */
480 vote(chg->usb_suspend_votable,
481 DEFAULT_VOTER, chip->dt.suspend_input, 0);
482 vote(chg->dc_suspend_votable,
483 DEFAULT_VOTER, chip->dt.suspend_input, 0);
484 vote(chg->fcc_votable,
485 DEFAULT_VOTER, true, chip->dt.fcc_ua);
Abhijeet Dharmapurikarf9805d42016-05-17 18:38:42 -0700486 vote(chg->fv_votable,
487 DEFAULT_VOTER, true, chip->dt.fv_uv);
Nicholas Troast96886052016-02-25 15:42:17 -0800488 vote(chg->usb_icl_votable,
489 DEFAULT_VOTER, true, chip->dt.usb_icl_ua);
490 vote(chg->dc_icl_votable,
491 DEFAULT_VOTER, true, chip->dt.dc_icl_ua);
492
493 /* configure charge enable for software control; active high */
494 rc = smblib_masked_write(chg, CHGR_CFG2_REG,
495 CHG_EN_POLARITY_BIT | CHG_EN_SRC_BIT, 0);
496 if (rc < 0) {
497 dev_err(chg->dev,
498 "Couldn't configure charge enable source rc=%d\n", rc);
499 return rc;
500 }
501
502 /* enable the charging path */
503 rc = smblib_enable_charging(chg, true);
504 if (rc < 0) {
505 dev_err(chg->dev, "Couldn't enable charging rc=%d\n", rc);
506 return rc;
507 }
508
509 /*
510 * trigger the usb-typec-change interrupt only when the CC state
511 * changes, or there was a VBUS error
512 */
513 rc = smblib_write(chg, TYPE_C_INTRPT_ENB_REG,
514 TYPEC_CCSTATE_CHANGE_INT_EN_BIT
515 | TYPEC_VBUS_ERROR_INT_EN_BIT);
516 if (rc < 0) {
517 dev_err(chg->dev,
518 "Couldn't configure Type-C interrupts rc=%d\n", rc);
519 return rc;
520 }
521
522 /* configure VCONN for software control */
523 rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
524 VCONN_EN_SRC_BIT | VCONN_EN_VALUE_BIT,
525 VCONN_EN_SRC_BIT);
526 if (rc < 0) {
527 dev_err(chg->dev,
528 "Couldn't configure VCONN for SW control rc=%d\n", rc);
529 return rc;
530 }
531
532 /* configure VBUS for software control */
533 rc = smblib_masked_write(chg, OTG_CFG_REG, OTG_EN_SRC_CFG_BIT, 0);
534 if (rc < 0) {
535 dev_err(chg->dev,
536 "Couldn't configure VBUS for SW control rc=%d\n", rc);
537 return rc;
538 }
539
540 /* configure power role for dual-role */
541 rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
542 TYPEC_POWER_ROLE_CMD_MASK, 0);
543 if (rc < 0) {
544 dev_err(chg->dev,
545 "Couldn't configure power role for DRP rc=%d\n", rc);
546 return rc;
547 }
548
Nicholas Troast4ea53ba2016-05-20 16:15:36 -0700549 /* disable Type-C factory mode */
550 rc = smblib_masked_write(chg, TYPE_C_CFG_REG,
551 FACTORY_MODE_DETECTION_EN_BIT, 0);
552 if (rc < 0) {
553 dev_err(chg->dev,
554 "Couldn't disable Type-C factory mode rc=%d\n", rc);
555 return rc;
556 }
557
Nicholas Troast96886052016-02-25 15:42:17 -0800558 return rc;
559}
560
561/****************************
562 * DETERMINE INITIAL STATUS *
563 ****************************/
564
565static int smb2_determine_initial_status(struct smb2 *chip)
566{
567 struct smb_irq_data irq_data = {chip, "determine-initial-status"};
568
569 smblib_handle_usb_plugin(0, &irq_data);
570 smblib_handle_usb_typec_change(0, &irq_data);
571 smblib_handle_usb_source_change(0, &irq_data);
572
573 return 0;
574}
575
576/**************************
577 * INTERRUPT REGISTRATION *
578 **************************/
579
580struct smb2_irq_info {
581 const char *name;
582 const irq_handler_t handler;
583};
584
585static const struct smb2_irq_info smb2_irqs[] = {
586/* CHARGER IRQs */
587 { "chg-error", smblib_handle_debug },
588 { "chg-state-change", smblib_handle_debug },
589 { "step-chg-state-change", smblib_handle_debug },
590 { "step-chg-soc-update-fail", smblib_handle_debug },
591 { "step-chg-soc-update-request", smblib_handle_debug },
592/* OTG IRQs */
593 { "otg-fail", smblib_handle_debug },
594 { "otg-overcurrent", smblib_handle_debug },
595 { "otg-oc-dis-sw-sts", smblib_handle_debug },
596 { "testmode-change-detect", smblib_handle_debug },
597/* BATTERY IRQs */
598 { "bat-temp", smblib_handle_batt_psy_changed },
599 { "bat-ocp", smblib_handle_batt_psy_changed },
600 { "bat-ov", smblib_handle_batt_psy_changed },
601 { "bat-low", smblib_handle_batt_psy_changed },
602 { "bat-therm-or-id-missing", smblib_handle_batt_psy_changed },
603 { "bat-terminal-missing", smblib_handle_batt_psy_changed },
604/* USB INPUT IRQs */
605 { "usbin-collapse", smblib_handle_debug },
606 { "usbin-lt-3p6v", smblib_handle_debug },
607 { "usbin-uv", smblib_handle_debug },
608 { "usbin-ov", smblib_handle_debug },
609 { "usbin-plugin", smblib_handle_usb_plugin },
610 { "usbin-src-change", smblib_handle_usb_source_change },
611 { "usbin-icl-change", smblib_handle_debug },
612 { "type-c-change", smblib_handle_usb_typec_change },
613/* DC INPUT IRQs */
614 { "dcin-collapse", smblib_handle_debug },
615 { "dcin-lt-3p6v", smblib_handle_debug },
616 { "dcin-uv", smblib_handle_debug },
617 { "dcin-ov", smblib_handle_debug },
618 { "dcin-plugin", smblib_handle_debug },
619 { "div2-en-dg", smblib_handle_debug },
620 { "dcin-icl-change", smblib_handle_debug },
621/* MISCELLANEOUS IRQs */
622 { "wdog-snarl", smblib_handle_debug },
623 { "wdog-bark", smblib_handle_debug },
624 { "aicl-fail", smblib_handle_debug },
625 { "aicl-done", smblib_handle_debug },
626 { "high-duty-cycle", smblib_handle_debug },
627 { "input-current-limiting", smblib_handle_debug },
628 { "temperature-change", smblib_handle_debug },
629 { "switcher-power-ok", smblib_handle_debug },
630};
631
632static int smb2_get_irq_index_byname(const char *irq_name)
633{
634 int i;
635
636 for (i = 0; i < ARRAY_SIZE(smb2_irqs); i++) {
637 if (strcmp(smb2_irqs[i].name, irq_name) == 0)
638 return i;
639 }
640
641 return -ENOENT;
642}
643
644static int smb2_request_interrupt(struct smb2 *chip,
645 struct device_node *node, const char *irq_name)
646{
647 struct smb_charger *chg = &chip->chg;
648 int rc, irq, irq_index;
649 struct smb_irq_data *irq_data;
650
651 irq = of_irq_get_byname(node, irq_name);
652 if (irq < 0) {
653 pr_err("Couldn't get irq %s byname\n", irq_name);
654 return irq;
655 }
656
657 irq_index = smb2_get_irq_index_byname(irq_name);
658 if (irq_index < 0) {
659 pr_err("%s is not a defined irq\n", irq_name);
660 return irq_index;
661 }
662
663 irq_data = devm_kzalloc(chg->dev, sizeof(*irq_data), GFP_KERNEL);
664 if (!irq_data)
665 return -ENOMEM;
666
667 irq_data->parent_data = chip;
668 irq_data->name = irq_name;
669
670 rc = devm_request_threaded_irq(chg->dev, irq, NULL,
671 smb2_irqs[irq_index].handler,
672 IRQF_ONESHOT, irq_name, irq_data);
673 if (rc < 0) {
674 pr_err("Couldn't request irq %d\n", irq);
675 return rc;
676 }
677
678 return rc;
679}
680
681static int smb2_request_interrupts(struct smb2 *chip)
682{
683 struct smb_charger *chg = &chip->chg;
684 struct device_node *node = chg->dev->of_node;
685 struct device_node *child;
686 int rc = 0;
687 const char *name;
688 struct property *prop;
689
690 for_each_available_child_of_node(node, child) {
691 of_property_for_each_string(child, "interrupt-names",
692 prop, name) {
693 rc = smb2_request_interrupt(chip, child, name);
694 if (rc < 0)
695 return rc;
696 }
697 }
698
699 return rc;
700}
701
702/*********
703 * PROBE *
704 *********/
705
706static int smb2_probe(struct platform_device *pdev)
707{
708 struct smb2 *chip;
709 struct smb_charger *chg;
710 int rc = 0;
711 u8 stat;
712
713 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
714 if (!chip)
715 return -ENOMEM;
716
717 chg = &chip->chg;
718 chg->dev = &pdev->dev;
719 chg->param = v1_params;
720 chg->debug_mask = &__debug_mask;
721
722 chg->regmap = dev_get_regmap(chg->dev->parent, NULL);
723 if (!chg->regmap) {
724 pr_err("parent regmap is missing\n");
725 return -EINVAL;
726 }
727
728 smblib_init(chg);
729
730 rc = smb2_parse_dt(chip);
731 if (rc < 0) {
732 pr_err("Couldn't parse device tree rc=%d\n", rc);
733 goto cleanup;
734 }
735
736 /* set driver data before resources request it */
737 platform_set_drvdata(pdev, chip);
738
739 rc = smb2_init_vbus_regulator(chip);
740 if (rc < 0) {
741 pr_err("Couldn't initialize vbus regulator rc=%d\n",
742 rc);
743 goto cleanup;
744 }
745
746 rc = smb2_init_vconn_regulator(chip);
747 if (rc < 0) {
748 pr_err("Couldn't initialize vconn regulator rc=%d\n",
749 rc);
750 goto cleanup;
751 }
752
753 rc = smb2_init_usb_psy(chip);
754 if (rc < 0) {
755 pr_err("Couldn't initialize usb psy rc=%d\n", rc);
756 goto cleanup;
757 }
758
759 rc = smblib_read(chg, SHDN_CMD_REG, &stat);
760 if (rc < 0) {
761 pr_err("Couldn't read MISC_SHDN_CMD_REG rc=%d\n", rc);
762 return rc;
763 }
764
765 if (stat) {
766 pr_err("bad charger part; faking USB insertion\n");
767 chip->bad_part = true;
768 power_supply_changed(chg->usb_psy);
769 return 0;
770 }
771
772 rc = smb2_init_batt_psy(chip);
773 if (rc < 0) {
774 pr_err("Couldn't initialize batt psy rc=%d\n", rc);
775 goto cleanup;
776 }
777
778 rc = smb2_init_hw(chip);
779 if (rc < 0) {
780 pr_err("Couldn't initialize hardware rc=%d\n", rc);
781 goto cleanup;
782 }
783
784 rc = smb2_determine_initial_status(chip);
785 if (rc < 0) {
786 pr_err("Couldn't determine initial status rc=%d\n",
787 rc);
788 goto cleanup;
789 }
790
791 rc = smb2_request_interrupts(chip);
792 if (rc < 0) {
793 pr_err("Couldn't request interrupts rc=%d\n", rc);
794 goto cleanup;
795 }
796
797 pr_info("QPNP SMB2 probed successfully\n");
798 return rc;
799
800cleanup:
801 if (chg->usb_psy)
802 power_supply_unregister(chg->usb_psy);
803 if (chg->batt_psy)
804 power_supply_unregister(chg->batt_psy);
805 if (chg->vconn_vreg && chg->vconn_vreg->rdev)
806 regulator_unregister(chg->vconn_vreg->rdev);
807 if (chg->vbus_vreg && chg->vbus_vreg->rdev)
808 regulator_unregister(chg->vbus_vreg->rdev);
809 platform_set_drvdata(pdev, NULL);
810 return rc;
811}
812
813static int smb2_remove(struct platform_device *pdev)
814{
815 struct smb2 *chip = platform_get_drvdata(pdev);
816 struct smb_charger *chg = &chip->chg;
817
818 power_supply_unregister(chg->batt_psy);
819 power_supply_unregister(chg->usb_psy);
820 regulator_unregister(chg->vconn_vreg->rdev);
821 regulator_unregister(chg->vbus_vreg->rdev);
822
823 platform_set_drvdata(pdev, NULL);
824 return 0;
825}
826
827static const struct of_device_id match_table[] = {
828 { .compatible = "qcom,qpnp-smb2", },
829 { },
830};
831
832static struct platform_driver smb2_driver = {
833 .driver = {
834 .name = "qcom,qpnp-smb2",
835 .owner = THIS_MODULE,
836 .of_match_table = match_table,
837 },
838 .probe = smb2_probe,
839 .remove = smb2_remove,
840};
841module_platform_driver(smb2_driver);
842
843MODULE_DESCRIPTION("QPNP SMB2 Charger Driver");
844MODULE_LICENSE("GPL v2");